diff --git a/lib/nbt/Tag.dart b/lib/nbt/Tag.dart index 27330f9..24fb210 100644 --- a/lib/nbt/Tag.dart +++ b/lib/nbt/Tag.dart @@ -1,4 +1,18 @@ +import 'package:libac_flutter/nbt/impl/ByteArrayTag.dart'; +import 'package:libac_flutter/nbt/impl/CompoundTag.dart'; +import 'package:libac_flutter/nbt/impl/DoubleTag.dart'; +import 'package:libac_flutter/nbt/impl/EndTag.dart'; +import 'package:libac_flutter/nbt/impl/FloatTag.dart'; +import 'package:libac_flutter/nbt/impl/IntArrayTag.dart'; +import 'package:libac_flutter/nbt/impl/IntTag.dart'; +import 'package:libac_flutter/nbt/impl/LongTag.dart'; +import 'package:libac_flutter/nbt/impl/ShortTag.dart'; + import 'Stream.dart'; +import 'impl/ByteTag.dart'; +import 'impl/ListTag.dart'; +import 'impl/LongArrayTag.dart'; +import 'impl/StringTag.dart'; enum TagType { End(0), @@ -17,6 +31,16 @@ enum TagType { final int byte; const TagType(this.byte); + + static TagType get(int byte) { + for (TagType type in values) { + if (type.byte == byte) { + return type; + } + } + + return TagType.End; + } } abstract class Tag { @@ -27,4 +51,180 @@ abstract class Tag { TagType getTagType(); void writeValue(ByteLayer data); void readValue(ByteLayer data); + String? _key; + + String getKey() { + return (_key == null ? "" : _key!); + } + + static Tag readNamedTag(ByteLayer data) { + var type = data.readByte(); + if (type == 0) { + return EndTag(); + } else { + Tag tag = makeTagOfType(TagType.get(type)); + tag._key = data.readString(); + tag.readValue(data); + + return tag; + } + } + + static void writeNamedTag(Tag tag, ByteLayer data) { + data.writeByte(tag.getType()); + if (tag.getType() != 0) { + data.writeString(tag.getKey()); + tag.writeValue(data); + } + } + + bool equals(dynamic object) { + if (object == null || object is! Tag) return false; + + Tag tag = object; + if (tag.getType() != getType()) return false; + + if (!(getKey() == tag.getKey())) return false; + + return true; + } + + static Tag makeTagOfType(TagType type) { + switch (type) { + case TagType.Byte: + { + return ByteTag(); + } + case TagType.ByteArray: + { + return ByteArrayTag(); + } + + case TagType.Compound: + { + return CompoundTag(); + } + case TagType.Double: + { + return DoubleTag(); + } + case TagType.End: + { + return EndTag(); + } + case TagType.Short: + { + return ShortTag(); + } + case TagType.Int: + { + return IntTag(); + } + case TagType.Long: + { + return LongTag(); + } + case TagType.Float: + { + return FloatTag(); + } + case TagType.IntArray: + { + return IntArrayTag(); + } + case TagType.LongArray: + { + return LongArrayTag(); + } + + case TagType.List: + { + return ListTag(); + } + case TagType.String: + { + return StringTag(); + } + } + } + + int asByte() { + if (this is ByteTag) { + return (this as ByteTag).value; + } else { + return 0; + } + } + + List asByteArray() { + if (this is ByteArrayTag) { + return (this as ByteArrayTag).value; + } else { + return []; + } + } + + double asDouble() { + if (this is DoubleTag) { + return (this as DoubleTag).value; + } else { + return 0.0; + } + } + + double asFloat() { + if (this is FloatTag) { + return (this as FloatTag).value; + } else { + return 0.0; + } + } + + List asIntArray() { + if (this is IntArrayTag) { + return (this as IntArrayTag).value; + } else { + return []; + } + } + + int asInt() { + if (this is IntTag) { + return (this as IntTag).value; + } else { + return 0; + } + } + + List asLongArray() { + if (this is LongArrayTag) { + return (this as LongArrayTag).value; + } else { + return []; + } + } + + int asLong() { + if (this is LongTag) { + return (this as LongTag).value; + } else { + return 0; + } + } + + int asShort() { + if (this is ShortTag) { + return (this as ShortTag).value; + } else { + return 0; + } + } + + String asString() { + if (this is StringTag) { + return (this as StringTag).value; + } else { + return ""; + } + } } diff --git a/lib/nbt/impl/ByteArrayTag.dart b/lib/nbt/impl/ByteArrayTag.dart new file mode 100644 index 0000000..86cbf40 --- /dev/null +++ b/lib/nbt/impl/ByteArrayTag.dart @@ -0,0 +1,37 @@ +import 'package:libac_flutter/nbt/Stream.dart'; +import 'package:libac_flutter/nbt/Tag.dart'; + +class ByteArrayTag extends Tag { + final List value = []; + + ByteArrayTag(); + + ByteArrayTag._(List value) { + this.value.addAll(value); + } + + static ByteArrayTag valueOf(List value) { + return ByteArrayTag._(value); + } + + @override + void readValue(ByteLayer data) { + int len = data.readInt(); + for (int i = 0; i < len; i++) { + value.add(data.readByte()); + } + } + + @override + void writeValue(ByteLayer data) { + data.writeInt(value.length); + for (int i in value) { + data.writeByte(i); + } + } + + @override + TagType getTagType() { + return TagType.ByteArray; + } +} diff --git a/lib/nbt/impl/ByteTag.dart b/lib/nbt/impl/ByteTag.dart index 8a3b1a2..ca6c756 100644 --- a/lib/nbt/impl/ByteTag.dart +++ b/lib/nbt/impl/ByteTag.dart @@ -2,18 +2,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; class ByteTag extends Tag { - final int value; + int value = 0; - ByteTag({required this.value}); + ByteTag._(int value) { + this.value = value; + } + + ByteTag(); + + static ByteTag valueOf(int value) { + return ByteTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readByte(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeByte(value); } @override diff --git a/lib/nbt/impl/CompoundTag.dart b/lib/nbt/impl/CompoundTag.dart new file mode 100644 index 0000000..a4a50a0 --- /dev/null +++ b/lib/nbt/impl/CompoundTag.dart @@ -0,0 +1,60 @@ +import 'package:libac_flutter/nbt/Stream.dart'; +import 'package:libac_flutter/nbt/Tag.dart'; + +class CompoundTag extends Tag { + late final Map value = {}; + + CompoundTag(); + + @override + void readValue(ByteLayer data) { + value.clear(); + + while (true) { + Tag tag = Tag.readNamedTag(data); + if (tag.getType() == 0) { + return; + } + + put(tag.getKey(), tag); + } + } + + @override + void writeValue(ByteLayer data) { + Iterator it = value.values.iterator; + + while (it.moveNext()) { + Tag tag = it.current; + Tag.writeNamedTag(tag, data); + } + + data.writeByte(TagType.End.byte); + } + + void put(String name, Tag tag) { + value[name] = tag; + } + + bool contains(String name) { + return value.containsKey(name); + } + + Tag? get(String name) { + if (contains(name)) { + return value[name] as Tag; + } else { + // Does not exist! + return null; + } + } + + void remove(String name) { + value.remove(name); + } + + @override + TagType getTagType() { + return TagType.Compound; + } +} diff --git a/lib/nbt/impl/TagDouble.dart b/lib/nbt/impl/DoubleTag.dart similarity index 50% rename from lib/nbt/impl/TagDouble.dart rename to lib/nbt/impl/DoubleTag.dart index 6d7b94b..eaf2195 100644 --- a/lib/nbt/impl/TagDouble.dart +++ b/lib/nbt/impl/DoubleTag.dart @@ -1,18 +1,27 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagDouble extends Tag { - final double value; - TagDouble({required this.value}); +class DoubleTag extends Tag { + double value = 0.0; + + DoubleTag(); + + DoubleTag._(double value) { + this.value = value; + } + + static DoubleTag valueOf(double value) { + return DoubleTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readDouble(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeDouble(value); } @override diff --git a/lib/nbt/impl/TagEnd.dart b/lib/nbt/impl/EndTag.dart similarity index 87% rename from lib/nbt/impl/TagEnd.dart rename to lib/nbt/impl/EndTag.dart index e95c48d..f5e038f 100644 --- a/lib/nbt/impl/TagEnd.dart +++ b/lib/nbt/impl/EndTag.dart @@ -1,8 +1,8 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagEnd extends Tag { - TagEnd(); +class EndTag extends Tag { + EndTag(); @override void readValue(ByteLayer data) {} diff --git a/lib/nbt/impl/TagFloat.dart b/lib/nbt/impl/FloatTag.dart similarity index 51% rename from lib/nbt/impl/TagFloat.dart rename to lib/nbt/impl/FloatTag.dart index beef4c8..450a5ef 100644 --- a/lib/nbt/impl/TagFloat.dart +++ b/lib/nbt/impl/FloatTag.dart @@ -1,18 +1,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagFloat extends Tag { - final double value; - TagFloat({required this.value}); +class FloatTag extends Tag { + double value = 0.0; + FloatTag(); + + FloatTag._(double value) { + this.value = value; + } + + static FloatTag valueOf(double value) { + return FloatTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readFloat(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeFloat(value); } @override diff --git a/lib/nbt/impl/IntArrayTag.dart b/lib/nbt/impl/IntArrayTag.dart new file mode 100644 index 0000000..e5412e9 --- /dev/null +++ b/lib/nbt/impl/IntArrayTag.dart @@ -0,0 +1,32 @@ +import 'package:libac_flutter/nbt/Stream.dart'; +import 'package:libac_flutter/nbt/Tag.dart'; + +class IntArrayTag extends Tag { + final List value = []; + IntArrayTag(); + + IntArrayTag._(List value) { + this.value.addAll(value); + } + + @override + void readValue(ByteLayer data) { + int count = data.readInt(); + for (int i = 0; i < count; i++) { + value.add(data.readInt()); + } + } + + @override + void writeValue(ByteLayer data) { + data.writeInt(value.length); + for (int i in value) { + data.writeInt(i); + } + } + + @override + TagType getTagType() { + return TagType.IntArray; + } +} diff --git a/lib/nbt/impl/TagInt.dart b/lib/nbt/impl/IntTag.dart similarity index 53% rename from lib/nbt/impl/TagInt.dart rename to lib/nbt/impl/IntTag.dart index 6310085..877996e 100644 --- a/lib/nbt/impl/TagInt.dart +++ b/lib/nbt/impl/IntTag.dart @@ -1,18 +1,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagInt extends Tag { - final int value; - TagInt({required this.value}); +class IntTag extends Tag { + int value = 0; + IntTag(); + + IntTag._(int value) { + this.value = value; + } + + static IntTag valueOf(int value) { + return IntTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readInt(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeInt(value); } @override diff --git a/lib/nbt/impl/ListTag.dart b/lib/nbt/impl/ListTag.dart new file mode 100644 index 0000000..e7e1c1e --- /dev/null +++ b/lib/nbt/impl/ListTag.dart @@ -0,0 +1,65 @@ +import 'package:libac_flutter/nbt/Stream.dart'; +import 'package:libac_flutter/nbt/Tag.dart'; + +class ListTag extends Tag { + List value = []; + + ListTag(); + + @override + void readValue(ByteLayer data) { + TagType type = TagType.get(data.readByte()); + int size = data.readInt(); + + for (int i = 0; i < size; i++) { + Tag tag = Tag.makeTagOfType(type); + tag.readValue(data); + add(tag); + } + } + + @override + void writeValue(ByteLayer data) { + TagType type = TagType.End; + if (size() > 0) { + type = value[0].getTagType(); + } + + data.writeByte(type.byte); + data.writeInt(size()); + for (int i = 0; i < size(); i++) { + value[i].writeValue(data); + } + } + + void add(Tag tag) { + TagType type = TagType.End; + if (size() > 0) { + type = value[0].getTagType(); + } + if (type == TagType.End || type == tag.getTagType()) { + value.add(tag); + } + } + + void remove(Tag tag) { + value.remove(tag); + } + + void removeAt(int index) { + value.removeAt(index); + } + + int indexOf(Tag tag) { + return value.indexOf(tag); + } + + @override + TagType getTagType() { + return TagType.List; + } + + int size() { + return value.length; + } +} diff --git a/lib/nbt/impl/LongArrayTag.dart b/lib/nbt/impl/LongArrayTag.dart new file mode 100644 index 0000000..5f6bd37 --- /dev/null +++ b/lib/nbt/impl/LongArrayTag.dart @@ -0,0 +1,40 @@ +import 'package:libac_flutter/nbt/Stream.dart'; +import 'package:libac_flutter/nbt/Tag.dart'; + +class LongArrayTag extends Tag { + final List value = []; + LongArrayTag(); + + LongArrayTag._(List lst) { + value.addAll(lst); + } + + static LongArrayTag valueOf(List value) { + return LongArrayTag._(value); + } + + @override + void readValue(ByteLayer data) { + int count = data.readInt(); + for (int i = 0; i < count; i++) { + value.add(data.readLong()); + } + } + + @override + void writeValue(ByteLayer data) { + data.writeInt(size()); + for (int i in value) { + data.writeLong(i); + } + } + + int size() { + return value.length; + } + + @override + TagType getTagType() { + return TagType.LongArray; + } +} diff --git a/lib/nbt/impl/TagLong.dart b/lib/nbt/impl/LongTag.dart similarity index 52% rename from lib/nbt/impl/TagLong.dart rename to lib/nbt/impl/LongTag.dart index 6f70359..4a9e5ec 100644 --- a/lib/nbt/impl/TagLong.dart +++ b/lib/nbt/impl/LongTag.dart @@ -1,18 +1,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagLong extends Tag { - final int value; - TagLong({required this.value}); +class LongTag extends Tag { + int value = 0; + LongTag(); + + LongTag._(int value) { + this.value = value; + } + + static LongTag valueOf(int value) { + return LongTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readLong(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeLong(value); } @override diff --git a/lib/nbt/impl/TagShort.dart b/lib/nbt/impl/ShortTag.dart similarity index 52% rename from lib/nbt/impl/TagShort.dart rename to lib/nbt/impl/ShortTag.dart index 13040eb..1341d72 100644 --- a/lib/nbt/impl/TagShort.dart +++ b/lib/nbt/impl/ShortTag.dart @@ -1,18 +1,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagShort extends Tag { - final int value; - TagShort({required this.value}); +class ShortTag extends Tag { + int value = 0; + ShortTag(); + + ShortTag._(int value) { + this.value = value; + } + + static ShortTag valueOf(int value) { + return ShortTag._(value); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readShort(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeShort(value); } @override diff --git a/lib/nbt/impl/TagString.dart b/lib/nbt/impl/StringTag.dart similarity index 51% rename from lib/nbt/impl/TagString.dart rename to lib/nbt/impl/StringTag.dart index 861f413..19f5aa9 100644 --- a/lib/nbt/impl/TagString.dart +++ b/lib/nbt/impl/StringTag.dart @@ -1,18 +1,26 @@ import 'package:libac_flutter/nbt/Stream.dart'; import 'package:libac_flutter/nbt/Tag.dart'; -class TagString extends Tag { - final String value; - TagString({required this.value}); +class StringTag extends Tag { + String value = ""; + StringTag(); + + StringTag._(String str) { + value = str; + } + + static StringTag valueOf(String str) { + return StringTag._(str); + } @override void readValue(ByteLayer data) { - // TODO: implement readValue + value = data.readString(); } @override void writeValue(ByteLayer data) { - // TODO: implement writeValue + data.writeString(value); } @override diff --git a/lib/nbt/impl/TagByteArray.dart b/lib/nbt/impl/TagByteArray.dart deleted file mode 100644 index 9e53c63..0000000 --- a/lib/nbt/impl/TagByteArray.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:libac_flutter/nbt/Stream.dart'; -import 'package:libac_flutter/nbt/Tag.dart'; - -class TagByteArray extends Tag { - final List value; - TagByteArray({required this.value}); - - @override - void readValue(ByteLayer data) { - // TODO: implement readValue - } - - @override - void writeValue(ByteLayer data) { - // TODO: implement writeValue - } - - @override - TagType getTagType() { - return TagType.ByteArray; - } -} diff --git a/lib/nbt/impl/TagCompound.dart b/lib/nbt/impl/TagCompound.dart deleted file mode 100644 index 4415f6d..0000000 --- a/lib/nbt/impl/TagCompound.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:libac_flutter/nbt/Stream.dart'; -import 'package:libac_flutter/nbt/Tag.dart'; - -class TagCompound extends Tag { - late final Map _value; - - TagCompound() { - _value = new Map(); - } - - @override - void readValue(ByteLayer data) { - // TODO: implement readValue - } - - @override - void writeValue(ByteLayer data) { - // TODO: implement writeValue - } - - void put(String name, Tag tag) { - _value[name] = tag; - } - - bool contains(String name) { - return _value.containsKey(name); - } - - Tag? get(String name) { - if (contains(name)) - return _value[name] as Tag; - else { - // Does not exist! - return null; - } - } - - void remove(String name) { - _value.remove(name); - } - - @override - TagType getTagType() { - return TagType.Compound; - } -} diff --git a/lib/nbt/impl/TagIntArray.dart b/lib/nbt/impl/TagIntArray.dart deleted file mode 100644 index 9edcb33..0000000 --- a/lib/nbt/impl/TagIntArray.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:libac_flutter/nbt/Stream.dart'; -import 'package:libac_flutter/nbt/Tag.dart'; - -class TagIntArray extends Tag { - final List value; - TagIntArray({required this.value}); - - @override - void readValue(ByteLayer data) { - // TODO: implement readValue - } - - @override - void writeValue(ByteLayer data) { - // TODO: implement writeValue - } - - @override - TagType getTagType() { - return TagType.IntArray; - } -} diff --git a/lib/nbt/impl/TagList.dart b/lib/nbt/impl/TagList.dart deleted file mode 100644 index 6b6af5d..0000000 --- a/lib/nbt/impl/TagList.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:libac_flutter/nbt/Stream.dart'; -import 'package:libac_flutter/nbt/Tag.dart'; - -class TagList extends Tag { - late final List _value; - TagType _internalType = TagType.End; - - TagList() { - _value = List.empty(growable: true); - } - - @override - void readValue(ByteLayer data) { - // TODO: implement readValue - } - - @override - void writeValue(ByteLayer data) { - // TODO: implement writeValue - } - - void add(Tag tag) { - if (_internalType == TagType.End) { - _value.clear(); - _value.add(tag); - _internalType = tag.getTagType(); - } else { - if (_internalType == tag.getTagType()) { - _value.add(tag); - } - } - } - - void remove(Tag tag) { - _value.remove(tag); - } - - void removeAt(int index) { - _value.removeAt(index); - } - - int indexOf(Tag tag) { - return _value.indexOf(tag); - } - - @override - TagType getTagType() { - return TagType.List; - } -} diff --git a/lib/nbt/impl/TagLongArray.dart b/lib/nbt/impl/TagLongArray.dart deleted file mode 100644 index 62d41cb..0000000 --- a/lib/nbt/impl/TagLongArray.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:libac_flutter/nbt/Stream.dart'; -import 'package:libac_flutter/nbt/Tag.dart'; - -class TagLongArray extends Tag { - final List value; - TagLongArray({required this.value}); - - @override - void readValue(ByteLayer data) { - // TODO: implement readValue - } - - @override - void writeValue(ByteLayer data) { - // TODO: implement writeValue - } - - @override - TagType getTagType() { - return TagType.LongArray; - } -}