Initial implementation
This commit is contained in:
parent
3cb4c0d768
commit
6fdcbb05c4
45 changed files with 13962 additions and 6 deletions
|
@ -2,4 +2,5 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class Constants {
|
||||
static const Color TITLEBAR_COLOR = Color.fromARGB(255, 80, 0, 0);
|
||||
static const Color DRAWER_COLOR = Color.fromARGB(255, 0, 75, 75);
|
||||
}
|
||||
|
|
129
lib/Editor.dart
Normal file
129
lib/Editor.dart
Normal file
|
@ -0,0 +1,129 @@
|
|||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_treeview/flutter_treeview.dart';
|
||||
import 'package:nbteditor/Constants.dart';
|
||||
import 'package:nbteditor/tags/CompoundTag.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
|
||||
class Editor extends StatefulWidget {
|
||||
Editor({super.key});
|
||||
|
||||
@override
|
||||
EditorState createState() => EditorState();
|
||||
}
|
||||
|
||||
class EditorState extends State<Editor> {
|
||||
List<Node> nodes = [CompoundTag().getNode("/")];
|
||||
bool compressed = false;
|
||||
|
||||
late TreeViewController controller;
|
||||
|
||||
String appendCompressed() {
|
||||
if (compressed) {
|
||||
return " - Compressed";
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
controller = TreeViewController(children: nodes);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Constants.TITLEBAR_COLOR,
|
||||
title: Text("Named Binary Tag Editor${appendCompressed()}"),
|
||||
),
|
||||
drawer: Drawer(
|
||||
backgroundColor: Constants.DRAWER_COLOR,
|
||||
child: Column(children: [
|
||||
DrawerHeader(
|
||||
child: Column(
|
||||
children: [
|
||||
Text("Named Binary Tag Editor"),
|
||||
Text("Created by Tara Piccari")
|
||||
],
|
||||
)),
|
||||
ListTile(
|
||||
title: Text("N E W"),
|
||||
subtitle: Text("Create a new NBT Document"),
|
||||
leading: Icon(Icons.add),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
nodes.clear();
|
||||
|
||||
// Add a new compound tag as the root
|
||||
Tag tag = CompoundTag();
|
||||
nodes.add(tag.getNode("/"));
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text("O P E N"),
|
||||
leading: Icon(Icons.folder),
|
||||
subtitle: Text("Open an existing NBT Document for editing"),
|
||||
onTap: () async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles();
|
||||
String? filePath;
|
||||
if (result != null) {
|
||||
filePath = result.files.single.path;
|
||||
// Do something with the selected file path
|
||||
print('Selected file path: $filePath');
|
||||
} else {
|
||||
// User canceled the picker
|
||||
print('File selection canceled.');
|
||||
}
|
||||
if (filePath == null) {
|
||||
// cancelled
|
||||
return;
|
||||
} else {
|
||||
// String!!
|
||||
compressed = await NbtIo.read(filePath);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
nodes.clear();
|
||||
nodes.add(Tag.read(NbtIo.getStream()).getNode("/"));
|
||||
|
||||
controller = TreeViewController(children: nodes);
|
||||
});
|
||||
},
|
||||
)
|
||||
]),
|
||||
),
|
||||
body: TreeView(
|
||||
nodeBuilder: (context, node) {
|
||||
return (node.data as Tag).render();
|
||||
},
|
||||
controller: controller,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FileSelectionScreen extends StatelessWidget {
|
||||
Future<void> openFilePicker(BuildContext context) async {
|
||||
try {} catch (e) {
|
||||
// Handle errors
|
||||
print('Error selecting file: $e');
|
||||
}
|
||||
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('File Selection'),
|
||||
),
|
||||
body: Center(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => openFilePicker(context),
|
||||
child: Text('Select File'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:nbteditor/Editor.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MainApp());
|
||||
|
@ -9,12 +10,12 @@ class MainApp extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Text('Hello World!'),
|
||||
),
|
||||
),
|
||||
return MaterialApp(
|
||||
theme: ThemeData.dark(),
|
||||
routes: {
|
||||
"/": (context) => Editor(),
|
||||
"/select_file": (context) => FileSelectionScreen()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
67
lib/tags/ByteArrayTag.dart
Normal file
67
lib/tags/ByteArrayTag.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class ByteArrayTag extends Tag {
|
||||
List<int> _value = [];
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
List<Node> entries = [];
|
||||
int count = 0;
|
||||
for (var element in _value) {
|
||||
entries.add(Node(key: "$path/${count}", label: "${element}"));
|
||||
count++;
|
||||
}
|
||||
|
||||
return Node(key: path, label: Name, 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() {
|
||||
return ListTile(
|
||||
title: Text("TAG_ByteArray (${Name})"),
|
||||
subtitle: Text("${_value.length} entries"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
53
lib/tags/ByteTag.dart
Normal file
53
lib/tags/ByteTag.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class ByteTag extends Tag {
|
||||
int _value = 0;
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "TAG_Byte ${Name}", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
this._value = layer.readByte();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Byte (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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(this._value);
|
||||
}
|
||||
|
||||
@override
|
||||
TagType getTagType() {
|
||||
return TagType.Byte;
|
||||
}
|
||||
}
|
91
lib/tags/CompoundTag.dart
Normal file
91
lib/tags/CompoundTag.dart
Normal file
|
@ -0,0 +1,91 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_treeview/flutter_treeview.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
import 'package:uuid/v4.dart';
|
||||
|
||||
class CompoundTag extends Tag {
|
||||
UuidV4 v4 = UuidV4();
|
||||
Map<String, Tag> _children = {};
|
||||
|
||||
CompoundTag() {
|
||||
setKey(v4.generate());
|
||||
|
||||
setName("root");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Compound (${Name})"),
|
||||
subtitle:
|
||||
Text("${_children.length} tag${_children.length > 1 ? "s" : ""}"),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
List<Node> childTags = [];
|
||||
|
||||
for (var element in _children.entries) {
|
||||
childTags.add(element.value.getNode(path + "/${element.key}"));
|
||||
}
|
||||
Node me = Node(key: path, label: Name, data: this, children: childTags);
|
||||
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;
|
||||
}
|
||||
}
|
53
lib/tags/DoubleTag.dart
Normal file
53
lib/tags/DoubleTag.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class DoubleTag extends Tag {
|
||||
double _value = 0.0;
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readDouble();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Double (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
53
lib/tags/FloatTag.dart
Normal file
53
lib/tags/FloatTag.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class FloatTag extends Tag {
|
||||
double _value = 0.0;
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "$_value", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readFloat();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Float (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
67
lib/tags/IntArrayTag.dart
Normal file
67
lib/tags/IntArrayTag.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class IntArrayTag extends Tag {
|
||||
List<int> _value = [];
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
List<Node> entries = [];
|
||||
int count = 0;
|
||||
for (var element in _value) {
|
||||
entries.add(Node(key: "$path/${count}", label: "${element}"));
|
||||
count++;
|
||||
}
|
||||
|
||||
return Node(key: path, label: Name, 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() {
|
||||
return ListTile(
|
||||
title: Text("TAG_IntArray (${Name})"),
|
||||
subtitle: Text("${_value.length} entries"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
52
lib/tags/IntTag.dart
Normal file
52
lib/tags/IntTag.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class IntTag extends Tag {
|
||||
int _value = 0;
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "$_value", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readInt();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Int (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
100
lib/tags/ListTag.dart
Normal file
100
lib/tags/ListTag.dart
Normal file
|
@ -0,0 +1,100 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class ListTag extends Tag {
|
||||
List<Tag> _value = [];
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
List<Node> nodes = [];
|
||||
|
||||
int count = 0;
|
||||
for (var element in _value) {
|
||||
nodes.add(element.getNode("$path/$count"));
|
||||
count++;
|
||||
}
|
||||
|
||||
return Node(key: path, label: Name, data: this, children: nodes);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
bool add(Tag tag) {
|
||||
if (_value.length > 0) {
|
||||
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() {
|
||||
return ListTile(
|
||||
title: Text("TAG_List (${Name}) (${getListTagType()})"),
|
||||
subtitle: Text("${_value.length} entries"),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeHeader(ByteLayer layer) {
|
||||
layer.writeTagName(Name);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeTagType(ByteLayer layer) {
|
||||
layer.writeByte(TagType.List.toByte());
|
||||
}
|
||||
|
||||
TagType getListTagType() {
|
||||
if (_value.length > 0) {
|
||||
return TagType.End;
|
||||
} else
|
||||
return _value[0].getTagType();
|
||||
}
|
||||
|
||||
@override
|
||||
void writeValue(ByteLayer layer) {
|
||||
if (_value.length > 0) {
|
||||
_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;
|
||||
}
|
||||
}
|
67
lib/tags/LongArrayTag.dart
Normal file
67
lib/tags/LongArrayTag.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class LongArrayTag extends Tag {
|
||||
List<int> _value = [];
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
List<Node> entries = [];
|
||||
int count = 0;
|
||||
for (var element in _value) {
|
||||
entries.add(Node(key: "$path/${count}", label: "${element}"));
|
||||
count++;
|
||||
}
|
||||
|
||||
return Node(key: path, label: Name, 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() {
|
||||
return ListTile(
|
||||
title: Text("TAG_LongArray (${Name})"),
|
||||
subtitle: Text("${_value.length} entries"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
53
lib/tags/LongTag.dart
Normal file
53
lib/tags/LongTag.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class LongTag extends Tag {
|
||||
int _value = 0;
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "$_value", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readLong();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Long (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
285
lib/tags/NbtIo.dart
Normal file
285
lib/tags/NbtIo.dart
Normal file
|
@ -0,0 +1,285 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:ffi';
|
||||
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;
|
||||
}
|
||||
}
|
53
lib/tags/ShortTag.dart
Normal file
53
lib/tags/ShortTag.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class ShortTag extends Tag {
|
||||
int _value = 0;
|
||||
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "$_value", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readShort();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_Short (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
52
lib/tags/StringTag.dart
Normal file
52
lib/tags/StringTag.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter_treeview/src/models/node.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/Tag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
class StringTag extends Tag {
|
||||
String _value = "";
|
||||
@override
|
||||
Node getNode(String path) {
|
||||
return Node(key: path, label: "$_value", data: this);
|
||||
}
|
||||
|
||||
@override
|
||||
void readHeader(ByteLayer layer) {
|
||||
setName(layer.readTagName());
|
||||
}
|
||||
|
||||
@override
|
||||
void readValue(ByteLayer layer) {
|
||||
_value = layer.readString();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return ListTile(
|
||||
title: Text("TAG_String (${Name})"),
|
||||
subtitle: Text("${_value}"),
|
||||
);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
229
lib/tags/Tag.dart
Normal file
229
lib/tags/Tag.dart
Normal file
|
@ -0,0 +1,229 @@
|
|||
import 'dart:ffi';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_treeview/flutter_treeview.dart';
|
||||
import 'package:nbteditor/tags/ByteArrayTag.dart';
|
||||
import 'package:nbteditor/tags/ByteTag.dart';
|
||||
import 'package:nbteditor/tags/CompoundTag.dart';
|
||||
import 'package:nbteditor/tags/DoubleTag.dart';
|
||||
import 'package:nbteditor/tags/FloatTag.dart';
|
||||
import 'package:nbteditor/tags/IntArrayTag.dart';
|
||||
import 'package:nbteditor/tags/IntTag.dart';
|
||||
import 'package:nbteditor/tags/ListTag.dart';
|
||||
import 'package:nbteditor/tags/LongArrayTag.dart';
|
||||
import 'package:nbteditor/tags/LongTag.dart';
|
||||
import 'package:nbteditor/tags/NbtIo.dart';
|
||||
import 'package:nbteditor/tags/ShortTag.dart';
|
||||
import 'package:nbteditor/tags/StringTag.dart';
|
||||
import 'package:nbteditor/tags/TagType.dart';
|
||||
|
||||
abstract class Tag {
|
||||
String Name = "";
|
||||
Tag();
|
||||
|
||||
late String key;
|
||||
|
||||
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:
|
||||
{
|
||||
tag = ByteTag();
|
||||
break;
|
||||
}
|
||||
case TagType.Short:
|
||||
{
|
||||
tag = ShortTag();
|
||||
break;
|
||||
}
|
||||
case TagType.Int:
|
||||
{
|
||||
tag = IntTag();
|
||||
break;
|
||||
}
|
||||
case TagType.Long:
|
||||
{
|
||||
tag = LongTag();
|
||||
break;
|
||||
}
|
||||
case TagType.Float:
|
||||
{
|
||||
tag = FloatTag();
|
||||
break;
|
||||
}
|
||||
case TagType.Double:
|
||||
{
|
||||
tag = DoubleTag();
|
||||
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:
|
||||
{
|
||||
tag = LongArrayTag();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
print(
|
||||
"Unknown tag: ${tagType}, aborting read at ${layer.currentPosition - 1} bytes");
|
||||
|
||||
throw Exception("Unknown tag, could not deserialize");
|
||||
}
|
||||
}
|
||||
|
||||
print("Read ${tagType}");
|
||||
|
||||
if (!isList) tag.readHeader(layer);
|
||||
|
||||
print("Name: ${tag.Name}");
|
||||
|
||||
tag.readValue(layer);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
static TagType readTagType(ByteLayer layer) {
|
||||
int type = layer.readByte();
|
||||
TagType tagType = TagTypeExtension.fromByte(type);
|
||||
|
||||
return tagType;
|
||||
}
|
||||
|
||||
void readHeader(ByteLayer layer);
|
||||
void readValue(ByteLayer layer);
|
||||
|
||||
TagType getTagType();
|
||||
void writeTagType(ByteLayer layer);
|
||||
void writeHeader(ByteLayer layer);
|
||||
void writeValue(ByteLayer layer);
|
||||
}
|
83
lib/tags/TagType.dart
Normal file
83
lib/tags/TagType.dart
Normal file
|
@ -0,0 +1,83 @@
|
|||
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");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue