Get editor working with new library

This commit is contained in:
zontreck 2024-06-07 00:08:32 -07:00
parent 70fc9f740a
commit 674a3bf5f8
21 changed files with 268 additions and 1172 deletions

2
.gitignore vendored
View file

@ -25,3 +25,5 @@ doc/api/
.flutter-plugins .flutter-plugins
.flutter-plugins-dependencies .flutter-plugins-dependencies
out

5
bin/nbt2snbt.dart Normal file
View file

@ -0,0 +1,5 @@
void main(List<String> args) async {
for (int i = 0; i < args.length; i++) {
print("ARG ${i}: ${args[i]}");
}
}

4
compile.sh Normal file
View file

@ -0,0 +1,4 @@
#!/bin/bash
flutter build linux
dart compile exe -o out/nbt2snbt bin/nbt2snbt.dart

View file

@ -1,9 +1,11 @@
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/flutter_treeview.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:libac_dart/nbt/NbtIo.dart';
import 'package:libac_dart/nbt/Tag.dart';
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
import 'package:nbteditor/Constants.dart'; import 'package:nbteditor/Constants.dart';
import 'package:nbteditor/tags/CompoundTag.dart'; import 'package:nbteditor/tags/CompoundTag.dart';
import 'package:nbteditor/tags/NbtIo.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
class Editor extends StatefulWidget { class Editor extends StatefulWidget {
@ -56,7 +58,7 @@ class EditorState extends State<Editor> {
// Add a new compound tag as the root // Add a new compound tag as the root
Tag tag = CompoundTag(); Tag tag = CompoundTag();
nodes.add(tag.getNode("/")); nodes.add(TagExt.getNode("/", tag) as Node);
}); });
}, },
), ),
@ -80,13 +82,12 @@ class EditorState extends State<Editor> {
return; return;
} else { } else {
// String!! // String!!
compressed = await NbtIo.read(filePath); CompoundTag ct = await NbtIo.read(filePath);
nodes.clear();
nodes.add(ct.getNode("/") as Node);
} }
setState(() { setState(() {
nodes.clear();
nodes.add(Tag.read(NbtIo.getStream()).getNode("/"));
controller = TreeViewController(children: nodes); controller = TreeViewController(children: nodes);
}); });
}, },
@ -95,7 +96,7 @@ class EditorState extends State<Editor> {
), ),
body: TreeView( body: TreeView(
nodeBuilder: (context, node) { nodeBuilder: (context, node) {
return (node.data as Tag).render(); return TagExt.render(node.data as Tag);
}, },
controller: controller, controller: controller,
), ),

View file

@ -1,66 +1,29 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/src/models/node.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/ByteArrayTag.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class ByteArrayTag extends Tag { extension ByteArrayTagExt on ByteArrayTag {
final List<int> _value = [];
@override
Node getNode(String path) { Node getNode(String path) {
List<Node> entries = []; List<Node> entries = [];
int count = 0; int count = 0;
for (var element in _value) { for (var element in value) {
entries.add(Node(key: "$path/$count", label: "$element")); entries.add(Node(key: "$path/$count", label: "$element", data: element));
count++; count++;
} }
return Node(key: path, label: Name, data: this, children: entries); return Node(
key: path,
label: "TAG_ByteArray (${getKey()})",
data: this,
children: entries);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
int count = layer.readInt();
for (int i = 0; i < count; i++) {
_value.add(layer.readByte());
}
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_ByteArray ($Name)"), title: Text("TAG_ByteArray (${getKey()})"),
subtitle: Text("${_value.length} entries"), subtitle: TagExt.getElementDescriptor(
"${value.length} entries", true, false, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.ByteArray.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeInt(_value.length);
for (var element in _value) {
layer.writeByte(element);
}
}
@override
TagType getTagType() {
return TagType.ByteArray;
}
} }

View file

@ -1,52 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/src/models/node.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/ByteTag.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class ByteTag extends Tag { extension ByteTagExt on ByteTag {
int _value = 0;
@override
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "TAG_Byte $Name", data: this); return Node(key: path, label: "TAG_Byte ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readByte();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Byte ($Name)"), title: Text("TAG_Byte (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Byte.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeByte(_value);
}
@override
TagType getTagType() {
return TagType.Byte;
}
} }

View file

@ -1,91 +1,26 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/flutter_treeview.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/CompoundTag.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
import 'package:uuid/v4.dart';
class CompoundTag extends Tag { extension CompoundTagExt on CompoundTag {
UuidV4 v4 = const UuidV4();
final Map<String, Tag> _children = {};
CompoundTag() {
setKey(v4.generate());
setName("root");
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Compound ($Name)"), title: Text("TAG_Compound (${getKey()})"),
subtitle: subtitle: TagExt.getElementDescriptor(
Text("${_children.length} tag${_children.length > 1 ? "s" : ""}"), "${value.length} tag${value.length > 1 ? "s" : ""}",
); true,
false,
canBeNamed(this)));
} }
@override
Node getNode(String path) { Node getNode(String path) {
List<Node> childTags = []; List<Node> childTags = [];
for (var element in _children.entries) { for (var element in value.entries) {
childTags.add(element.value.getNode("$path/${element.key}")); childTags.add(TagExt.getNode("$path/${element.key}", element.value));
} }
Node me = Node(key: path, label: Name, data: this, children: childTags); Node me = Node(key: path, label: getKey(), data: this, children: childTags);
return me; return me;
} }
void put(String name, Tag child) {
_children[name] = child.withNick(name);
}
Tag? get(String name) {
return _children[name];
}
void remove(String name) {
_children.remove(name);
}
@override
void readValue(ByteLayer layer) {
TagType type;
while (true) {
type = Tag.readTagType(layer);
if (type == TagType.End) break;
Tag tag = Tag.readTag(layer, type, false);
put(tag.Name, tag);
}
}
@override
void writeValue(ByteLayer layer) {
for (var entry in _children.entries) {
layer.writeTagName(entry.key);
entry.value.writeValue(layer);
}
layer.writeByte(TagType.End.toByte());
}
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Compound.toByte());
}
@override
TagType getTagType() {
return TagType.Compound;
}
} }

View file

@ -1,52 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/src/models/node.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/DoubleTag.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class DoubleTag extends Tag { extension DoubleTagExt on DoubleTag {
double _value = 0.0;
@override
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "", data: this); return Node(key: path, label: "TAG_Double ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readDouble();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Double ($Name)"), title: Text("TAG_Double (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Double.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeDouble(_value);
}
@override
TagType getTagType() {
return TagType.Double;
}
} }

View file

@ -1,52 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/src/models/node.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/FloatTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class FloatTag extends Tag { import 'Tag.dart';
double _value = 0.0;
@override extension FloatTagExt on FloatTag {
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "$_value", data: this); return Node(key: path, label: "TAG_Float ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readFloat();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Float ($Name)"), title: Text("TAG_Float (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Float.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeFloat(_value);
}
@override
TagType getTagType() {
return TagType.Float;
}
} }

View file

@ -1,66 +1,30 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/src/models/node.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/IntArrayTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class IntArrayTag extends Tag { import 'Tag.dart';
final List<int> _value = [];
@override extension IntArrayTagExt on IntArrayTag {
Node getNode(String path) { Node getNode(String path) {
List<Node> entries = []; List<Node> entries = [];
int count = 0; int count = 0;
for (var element in _value) { for (var element in value) {
entries.add(Node(key: "$path/$count", label: "$element")); entries.add(Node(key: "$path/$count", label: "$element", data: element));
count++; count++;
} }
return Node(key: path, label: Name, data: this, children: entries); return Node(
key: path,
label: "TAG_IntArray (${getKey()})",
data: this,
children: entries);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
int count = layer.readInt();
for (int i = 0; i < count; i++) {
_value.add(layer.readInt());
}
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_IntArray ($Name)"), title: Text("TAG_IntArray (${getKey()})"),
subtitle: Text("${_value.length} entries"), subtitle: TagExt.getElementDescriptor(
"${value.length} entries", true, false, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.IntArray.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeInt(_value.length);
for (var element in _value) {
layer.writeInt(element);
}
}
@override
TagType getTagType() {
return TagType.IntArray;
}
} }

View file

@ -1,51 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/IntTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class IntTag extends Tag { import 'Tag.dart';
int _value = 0;
@override extension IntTagExt on IntTag {
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "$_value", data: this); return Node(key: path, label: "TAG_Int ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readInt();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Int ($Name)"), title: Text("TAG_Int (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Int.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeInt(_value);
}
@override
TagType getTagType() {
return TagType.Int;
}
} }

View file

@ -1,100 +1,29 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/Tag.dart';
import 'package:libac_dart/nbt/impl/ListTag.dart';
import 'package:nbteditor/tags/Tag.dart'; import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class ListTag extends Tag { extension ListTagExt on ListTag {
final List<Tag> _value = [];
@override
Node getNode(String path) { Node getNode(String path) {
List<Node> nodes = []; List<Node> nodes = [];
int count = 0; int count = 0;
for (var element in _value) { for (var element in value) {
nodes.add(element.getNode("$path/$count")); nodes.add(TagExt.getNode("$path/$count", element));
count++; count++;
} }
return Node(key: path, label: Name, data: this, children: nodes); return Node(key: path, label: getKey(), data: this, children: nodes);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
bool add(Tag tag) {
if (_value.isNotEmpty) {
if (tag.getTagType() == _value[0].getTagType()) {
_value.add(tag);
return true;
} else {
return false;
}
} else {
_value.add(tag);
return true;
}
}
@override
void readValue(ByteLayer layer) {
TagType type = Tag.readTagType(layer);
int count = layer.readInt();
if (count == 0) return;
for (int i = 0; i < count; i++) {
add(Tag.readTag(layer, type, true));
}
}
@override
Widget render() { Widget render() {
TagType type = TagType.End;
if (value.length > 0) type = get(0).getTagType();
return ListTile( return ListTile(
title: Text("TAG_List ($Name) (${getListTagType()})"), title: Text("TAG_List (${getKey()}) (${type})"),
subtitle: Text("${_value.length} entries"), subtitle: TagExt.getElementDescriptor(
); "${value.length} entries", true, false, canBeNamed(this)));
}
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.List.toByte());
}
TagType getListTagType() {
if (_value.isNotEmpty) {
return TagType.End;
} else {
return _value[0].getTagType();
}
}
@override
void writeValue(ByteLayer layer) {
if (_value.isNotEmpty) {
_value[0].writeTagType(layer);
} else {
layer.writeByte(TagType.End.toByte());
}
layer.writeInt(_value.length);
for (var element in _value) {
element.writeValue(layer);
}
}
@override
TagType getTagType() {
return TagType.List;
} }
} }

View file

@ -1,66 +1,30 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/LongArrayTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class LongArrayTag extends Tag { import 'Tag.dart';
final List<int> _value = [];
@override extension LongArrayTagExt on LongArrayTag {
Node getNode(String path) { Node getNode(String path) {
List<Node> entries = []; List<Node> entries = [];
int count = 0; int count = 0;
for (var element in _value) { for (var element in value) {
entries.add(Node(key: "$path/$count", label: "$element")); entries.add(Node(key: "$path/$count", label: "$element", data: element));
count++; count++;
} }
return Node(key: path, label: Name, data: this, children: entries); return Node(
key: path,
label: "TAG_IntArray (${getKey()})",
data: this,
children: entries);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
int count = layer.readInt();
for (int i = 0; i < count; i++) {
_value.add(layer.readLong());
}
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_LongArray ($Name)"), title: Text("TAG_LongArray (${getKey()})"),
subtitle: Text("${_value.length} entries"), subtitle: TagExt.getElementDescriptor(
"${value.length} entries", true, false, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.LongArray.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeInt(_value.length);
for (var element in _value) {
layer.writeLong(element);
}
}
@override
TagType getTagType() {
return TagType.LongArray;
}
} }

View file

@ -1,52 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/LongTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class LongTag extends Tag { import 'Tag.dart';
int _value = 0;
@override extension LongTagExt on LongTag {
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "$_value", data: this); return Node(key: path, label: "TAG_Long ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readLong();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Long ($Name)"), title: Text("TAG_Long (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Long.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeLong(_value);
}
@override
TagType getTagType() {
return TagType.Long;
}
} }

View file

@ -1,284 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:nbteditor/tags/TagType.dart';
class ByteLayer {
Uint8List _byteBuffer = Uint8List(0);
int _position = 0;
ByteLayer() {
_byteBuffer = Uint8List(0); // Initial size, can be adjusted
_position = 0;
}
int get length => _byteBuffer.length;
int get currentPosition => _position;
Uint8List get bytes => _byteBuffer.sublist(0, _position);
void _ensureCapacity(int additionalBytes) {
final requiredCapacity = _position + additionalBytes;
if (requiredCapacity > _byteBuffer.length) {
final newCapacity =
_position * 2 + additionalBytes; // Adjust capacity as needed
final newBuffer = Uint8List(newCapacity);
newBuffer.setAll(0, _byteBuffer);
_byteBuffer = newBuffer;
}
}
void writeInt(int value) {
_ensureCapacity(4);
_byteBuffer.buffer.asByteData().setInt32(_position, value, Endian.big);
_position += 4;
}
void writeDouble(double value) {
_ensureCapacity(8);
_byteBuffer.buffer.asByteData().setFloat64(_position, value, Endian.big);
_position += 8;
}
void writeString(String value) {
final encoded = utf8.encode(value);
writeShort(encoded.length);
_ensureCapacity(encoded.length);
_byteBuffer.setAll(_position, encoded);
_position += encoded.length;
}
int readInt() {
final value =
_byteBuffer.buffer.asByteData().getInt32(_position, Endian.big);
_position += 4;
return value;
}
double readDouble() {
final value =
_byteBuffer.buffer.asByteData().getFloat64(_position, Endian.big);
_position += 8;
return value;
}
String readString() {
final length = readShort();
final encoded = _byteBuffer.sublist(_position, _position + length);
_position += length;
return utf8.decode(encoded);
}
void writeIntZigZag(int value) {
final zigzag = (value << 1) ^ (value >> 31);
writeInt(zigzag);
}
int readIntZigZag() {
final zigzag = readInt();
final value = (zigzag >> 1) ^ -(zigzag & 1);
return value;
}
void writeByte(int value) {
_ensureCapacity(1);
_byteBuffer[_position] = value & 0xFF;
_position++;
}
int readByte() {
final value = _byteBuffer[_position];
_position++;
return value;
}
void writeVarInt(int value) {
while ((value & ~0x7F) != 0) {
writeByte((value & 0x7F) | 0x80);
value = (value >> 7) & 0x1FFFFFFF;
}
writeByte(value & 0x7F);
}
int readVarInt() {
int result = 0;
int shift = 0;
int byte;
do {
byte = readByte();
result |= (byte & 0x7F) << shift;
if ((byte & 0x80) == 0) {
break;
}
shift += 7;
} while (true);
return result;
}
void writeVarIntNoZigZag(int value) {
while ((value & ~0x7F) != 0) {
writeByte((value & 0x7F) | 0x80);
value >>= 7;
}
writeByte(value & 0x7F);
}
int readVarIntNoZigZag() {
int result = 0;
int shift = 0;
int byte;
do {
byte = readByte();
result |= (byte & 0x7F) << shift;
if ((byte & 0x80) == 0) {
break;
}
shift += 7;
} while (true);
return result;
}
void writeShort(int value) {
_ensureCapacity(2);
_byteBuffer.buffer.asByteData().setInt16(_position, value, Endian.big);
_position += 2;
}
int readShort() {
final value =
_byteBuffer.buffer.asByteData().getInt16(_position, Endian.big);
_position += 2;
return value;
}
void writeFloat(double value) {
_ensureCapacity(4);
_byteBuffer.buffer.asByteData().setFloat32(_position, value, Endian.big);
_position += 2;
}
double readFloat() {
final value =
_byteBuffer.buffer.asByteData().getFloat32(_position, Endian.big);
_position += 2;
return value;
}
void writeTagName(String name) {
final encodedName = utf8.encode(name);
writeShort(encodedName.length);
_ensureCapacity(encodedName.length);
_byteBuffer.setAll(_position, encodedName);
_position += encodedName.length;
}
String readTagName() {
final length = readShort();
final encodedName = _byteBuffer.sublist(_position, _position + length);
_position += length;
return utf8.decode(encodedName);
}
void resetPosition() {
_position = 0;
}
void clear() {
resetPosition();
_byteBuffer = Uint8List(0);
}
Future<void> writeToFile(String filePath) async {
final file = File(filePath);
await file.writeAsBytes(bytes);
}
Future<void> readFromFile(String filePath) async {
final file = File(filePath);
final exists = await file.exists();
if (!exists) {
print('File does not exist.');
return;
}
_byteBuffer = await file.readAsBytes();
resetPosition();
}
Future<void> compress() async {
final gzip = GZipCodec();
final compressedData = gzip.encode(_byteBuffer);
_byteBuffer = Uint8List.fromList(compressedData);
_position = _byteBuffer.length;
}
Future<void> decompress() async {
final gzip = GZipCodec();
final decompressedData = gzip.decode(_byteBuffer);
_byteBuffer = Uint8List.fromList(decompressedData);
_position = _byteBuffer.length;
}
void writeLong(int value) {
_ensureCapacity(8);
_byteBuffer.buffer.asByteData().setInt64(_position, value, Endian.big);
_position += 8;
}
int readLong() {
final value =
_byteBuffer.buffer.asByteData().getInt64(_position, Endian.big);
_position += 8;
return value;
}
}
class NbtIo {
static ByteLayer _io = ByteLayer();
// Handle various helper functions here!
static Future<void> _read(String file) async {
_io = ByteLayer();
await _io.readFromFile(file);
}
// This function will read the file and check if it is infact gzipped
static Future<bool> read(String file) async {
await _read(file);
if (_io.readByte() == TagType.Compound.toByte()) {
_io.resetPosition();
return false;
} else {
// Is likely gzip compressed
await _readCompressed(file);
_io.resetPosition();
return true;
}
}
static Future<void> _readCompressed(String file) async {
_io = ByteLayer();
await _io.readFromFile(file);
await _io.decompress();
}
static Future<void> write(String file) async {
await _io.writeToFile(file);
}
static Future<void> writeCompressed(String file) async {
await _io.compress();
await _io.writeToFile(file);
}
static ByteLayer getStream() {
return _io;
}
}

View file

@ -1,52 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/ShortTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class ShortTag extends Tag { import 'Tag.dart';
int _value = 0;
@override extension ShortTagExt on ShortTag {
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: "$_value", data: this); return Node(key: path, label: "TAG_Short ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readShort();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_Short ($Name)"), title: Text("TAG_Short (${getKey()})"),
subtitle: Text("$_value"), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.Short.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeShort(_value);
}
@override
TagType getTagType() {
return TagType.Short;
}
} }

View file

@ -1,51 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/src/models/node.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:nbteditor/tags/NbtIo.dart'; import 'package:libac_dart/nbt/impl/StringTag.dart';
import 'package:nbteditor/tags/Tag.dart';
import 'package:nbteditor/tags/TagType.dart';
class StringTag extends Tag { import 'Tag.dart';
String _value = "";
@override extension StringTagExt on StringTag {
Node getNode(String path) { Node getNode(String path) {
return Node(key: path, label: _value, data: this); return Node(key: path, label: "TAG_String ${getKey()}", data: this);
} }
@override
void readHeader(ByteLayer layer) {
setName(layer.readTagName());
}
@override
void readValue(ByteLayer layer) {
_value = layer.readString();
}
@override
Widget render() { Widget render() {
return ListTile( return ListTile(
title: Text("TAG_String ($Name)"), title: Text("TAG_String (${getKey()})"),
subtitle: Text(_value), subtitle: TagExt.getElementDescriptor(
"${value}", false, true, canBeNamed(this)),
); );
} }
@override
void writeHeader(ByteLayer layer) {
layer.writeTagName(Name);
}
@override
void writeTagType(ByteLayer layer) {
layer.writeByte(TagType.String.toByte());
}
@override
void writeValue(ByteLayer layer) {
layer.writeString(_value);
}
@override
TagType getTagType() {
return TagType.String;
}
} }

View file

@ -1,6 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_treeview/flutter_treeview.dart'; import 'package:flutter_treeview/flutter_treeview.dart';
import 'package:libac_dart/nbt/Tag.dart';
import 'package:libac_dart/nbt/impl/ByteArrayTag.dart';
import 'package:libac_dart/nbt/impl/ByteTag.dart';
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
import 'package:libac_dart/nbt/impl/DoubleTag.dart';
import 'package:libac_dart/nbt/impl/FloatTag.dart';
import 'package:libac_dart/nbt/impl/IntArrayTag.dart';
import 'package:libac_dart/nbt/impl/IntTag.dart';
import 'package:libac_dart/nbt/impl/ListTag.dart';
import 'package:libac_dart/nbt/impl/LongArrayTag.dart';
import 'package:libac_dart/nbt/impl/LongTag.dart';
import 'package:libac_dart/nbt/impl/ShortTag.dart';
import 'package:libac_dart/nbt/impl/StringTag.dart';
import 'package:nbteditor/tags/ByteArrayTag.dart'; import 'package:nbteditor/tags/ByteArrayTag.dart';
import 'package:nbteditor/tags/ByteTag.dart'; import 'package:nbteditor/tags/ByteTag.dart';
import 'package:nbteditor/tags/CompoundTag.dart'; import 'package:nbteditor/tags/CompoundTag.dart';
@ -11,230 +23,143 @@ import 'package:nbteditor/tags/IntTag.dart';
import 'package:nbteditor/tags/ListTag.dart'; import 'package:nbteditor/tags/ListTag.dart';
import 'package:nbteditor/tags/LongArrayTag.dart'; import 'package:nbteditor/tags/LongArrayTag.dart';
import 'package:nbteditor/tags/LongTag.dart'; import 'package:nbteditor/tags/LongTag.dart';
import 'package:nbteditor/tags/NbtIo.dart';
import 'package:nbteditor/tags/ShortTag.dart'; import 'package:nbteditor/tags/ShortTag.dart';
import 'package:nbteditor/tags/StringTag.dart'; import 'package:nbteditor/tags/StringTag.dart';
import 'package:nbteditor/tags/TagType.dart';
abstract class Tag { class TagExt {
String Name = ""; static Widget render(Tag tag) {
Tag(); switch (tag.getTagType()) {
case TagType.List:
late String key; {
return (tag as ListTag).render();
void setKey(String key) { }
this.key = key;
}
Widget render();
Node getNode(String path);
ByteTag asByte() {
if (this is ByteTag) {
return this as ByteTag;
} else {
return ByteTag();
}
}
ShortTag asShort() {
if (this is ShortTag) {
return this as ShortTag;
} else {
return ShortTag();
}
}
IntTag asInt() {
if (this is IntTag) {
return this as IntTag;
} else {
return IntTag();
}
}
LongTag asLong() {
if (this is LongTag) {
return this as LongTag;
} else {
return LongTag();
}
}
FloatTag asFloat() {
if (this is FloatTag) {
return this as FloatTag;
} else {
return FloatTag();
}
}
DoubleTag asDouble() {
if (this is DoubleTag) {
return this as DoubleTag;
} else {
return DoubleTag();
}
}
ByteArrayTag asByteArray() {
if (this is ByteArrayTag) {
return this as ByteArrayTag;
} else {
return ByteArrayTag();
}
}
StringTag asString() {
if (this is StringTag) {
return this as StringTag;
} else {
return StringTag();
}
}
ListTag asListTag() {
if (this is ListTag) {
return this as ListTag;
} else {
return ListTag();
}
}
CompoundTag asCompoundTag() {
if (this is CompoundTag) {
return this as CompoundTag;
} else {
return CompoundTag();
}
}
IntArrayTag asIntArrayTag() {
if (this is IntArrayTag) {
return this as IntArrayTag;
} else {
return IntArrayTag();
}
}
LongArrayTag asLongArrayTag() {
if (this is LongArrayTag) {
return this as LongArrayTag;
} else {
return LongArrayTag();
}
}
Tag withNick(String name) {
Name = name;
return this;
}
void setName(String name) {
Name = name;
}
static Tag read(ByteLayer layer) {
TagType tagType = readTagType(layer);
return readTag(layer, tagType, false);
}
static Tag readTag(ByteLayer layer, TagType tagType, bool isList) {
Tag tag;
switch (tagType) {
case TagType.Byte: case TagType.Byte:
{ {
tag = ByteTag(); return (tag as ByteTag).render();
break;
}
case TagType.Short:
{
tag = ShortTag();
break;
} }
case TagType.Int: case TagType.Int:
{ {
tag = IntTag(); return (tag as IntTag).render();
break;
}
case TagType.Long:
{
tag = LongTag();
break;
}
case TagType.Float:
{
tag = FloatTag();
break;
} }
case TagType.Double: case TagType.Double:
{ {
tag = DoubleTag(); return (tag as DoubleTag).render();
break;
}
case TagType.ByteArray:
{
tag = ByteArrayTag();
break;
}
case TagType.String:
{
tag = StringTag();
break;
}
case TagType.List:
{
tag = ListTag();
break;
}
case TagType.Compound:
{
tag = CompoundTag();
break;
}
case TagType.IntArray:
{
tag = IntArrayTag();
break;
} }
case TagType.LongArray: case TagType.LongArray:
{ {
tag = LongArrayTag(); return (tag as LongArrayTag).render();
break;
} }
default: case TagType.Long:
{ {
print( return (tag as LongTag).render();
"Unknown tag: $tagType, aborting read at ${layer.currentPosition - 1} bytes"); }
case TagType.IntArray:
throw Exception("Unknown tag, could not deserialize"); {
return (tag as IntArrayTag).render();
}
case TagType.ByteArray:
{
return (tag as ByteArrayTag).render();
}
case TagType.String:
{
return (tag as StringTag).render();
}
case TagType.Compound:
{
return (tag as CompoundTag).render();
}
case TagType.Short:
{
return (tag as ShortTag).render();
}
case TagType.Float:
{
return (tag as FloatTag).render();
}
case TagType.End:
{
return SizedBox();
} }
} }
print("Read $tagType");
if (!isList) tag.readHeader(layer);
print("Name: ${tag.Name}");
tag.readValue(layer);
return tag;
} }
static TagType readTagType(ByteLayer layer) { static Node getNode(String path, Tag tag) {
int type = layer.readByte(); switch (tag.getTagType()) {
TagType tagType = TagTypeExtension.fromByte(type); case TagType.List:
{
return tagType; return (tag as ListTag).getNode(path);
}
case TagType.Byte:
{
return (tag as ByteTag).getNode(path);
}
case TagType.Int:
{
return (tag as IntTag).getNode(path);
}
case TagType.Double:
{
return (tag as DoubleTag).getNode(path);
}
case TagType.LongArray:
{
return (tag as LongArrayTag).getNode(path);
}
case TagType.Long:
{
return (tag as LongTag).getNode(path);
}
case TagType.IntArray:
{
return (tag as IntArrayTag).getNode(path);
}
case TagType.ByteArray:
{
return (tag as ByteArrayTag).getNode(path);
}
case TagType.String:
{
return (tag as StringTag).getNode(path);
}
case TagType.Compound:
{
return (tag as CompoundTag).getNode(path);
}
case TagType.Short:
{
return (tag as ShortTag).getNode(path);
}
case TagType.Float:
{
return (tag as FloatTag).getNode(path);
}
case TagType.End:
{
return Node(key: "ENDTAG", label: "");
}
}
} }
void readHeader(ByteLayer layer); static Widget getElementDescriptor(
void readValue(ByteLayer layer); String descript, bool canAddElements, bool editableValue, bool isNamed) {
return Row(
TagType getTagType(); children: [
void writeTagType(ByteLayer layer); Text(descript),
void writeHeader(ByteLayer layer); SizedBox(
void writeValue(ByteLayer layer); width: 100,
),
if (canAddElements)
ElevatedButton(onPressed: () {}, child: Icon(Icons.add)),
if (isNamed)
ElevatedButton(onPressed: () {}, child: Text("R E N A M E")),
if (editableValue)
ElevatedButton(onPressed: () {}, child: Text("E D I T"))
],
);
}
}
bool canBeNamed(Tag tag) {
return tag.parentTagType == TagType.List ? false : true;
} }

View file

@ -1,83 +0,0 @@
enum TagType {
End,
Byte,
Short,
Int,
Long,
Float,
Double,
ByteArray,
String,
List,
Compound,
IntArray,
LongArray
}
extension TagTypeExtension on TagType {
int toByte() {
switch (this) {
case TagType.End:
return 0;
case TagType.Byte:
return 1;
case TagType.Short:
return 2;
case TagType.Int:
return 3;
case TagType.Long:
return 4;
case TagType.Float:
return 5;
case TagType.Double:
return 6;
case TagType.ByteArray:
return 7;
case TagType.String:
return 8;
case TagType.List:
return 9;
case TagType.Compound:
return 10;
case TagType.IntArray:
return 11;
case TagType.LongArray:
return 12;
default:
throw Exception('Unknown TagType: $this');
}
}
static TagType fromByte(int type) {
switch (type) {
case 0:
return TagType.End;
case 1:
return TagType.Byte;
case 2:
return TagType.Short;
case 3:
return TagType.Int;
case 4:
return TagType.Long;
case 5:
return TagType.Float;
case 6:
return TagType.Double;
case 7:
return TagType.ByteArray;
case 8:
return TagType.String;
case 9:
return TagType.List;
case 10:
return TagType.Compound;
case 11:
return TagType.IntArray;
case 12:
return TagType.LongArray;
default:
throw Exception("Unknown TagType $type");
}
}
}

0
out/.placeholder Normal file
View file

View file

@ -11,7 +11,9 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_treeview: ^1.0.7+1 flutter_treeview: ^1.0.7+1
uuid: ^4.2.2 libac_dart:
hosted: https://git.zontreck.com/api/packages/AriasCreations/pub/
version: 1.0.33
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: