Compare commits
2 Commits
42055ae6a9
...
d5acd42cb8
Author | SHA1 | Date | |
---|---|---|---|
d5acd42cb8 | |||
79719b2844 |
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
32
.idea/inspectionProfiles/Project_Default.xml
Normal file
32
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="NonAsciiCharacters" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES" />
|
||||
<inspection_tool class="PyAugmentAssignmentInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PyByteLiteralInspection" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES" />
|
||||
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ourVersions">
|
||||
<value>
|
||||
<list size="5">
|
||||
<item index="0" class="java.lang.String" itemvalue="3.12" />
|
||||
<item index="1" class="java.lang.String" itemvalue="3.11" />
|
||||
<item index="2" class="java.lang.String" itemvalue="3.10" />
|
||||
<item index="3" class="java.lang.String" itemvalue="3.9" />
|
||||
<item index="4" class="java.lang.String" itemvalue="3.8" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyMissingOrEmptyDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PyMissingTypeHintsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PyNonAsciiCharInspection" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES" />
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="utils.translate.__getattr__.*" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="SqlUnicodeStringLiteralInspection" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
.idea/misc.xml
Normal file
4
.idea/misc.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/nbt-rust.iml" filepath="$PROJECT_DIR$/.idea/nbt-rust.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
11
.idea/nbt-rust.iml
Normal file
11
.idea/nbt-rust.iml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
243
src/data.rs
243
src/data.rs
@ -14,227 +14,19 @@ pub type StringLength = u32;
|
||||
/// Reader
|
||||
pub type Reader<'a> = Cursor<&'a [u8]>;
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NbtItem<T: NbtListTrait> {
|
||||
pub enum NbtItem {
|
||||
Value(NbtValue),
|
||||
Array(NbtList),
|
||||
}
|
||||
|
||||
/// 一个 NBT list 的基本素养
|
||||
pub trait NbtListTrait {
|
||||
/// 内容类型
|
||||
type ValueType;
|
||||
/// 输出类型标识符
|
||||
/// 类型标识符
|
||||
/// (0x07) Vec<bool>
|
||||
/// (0x09) Vec<NbtItem>
|
||||
/// (0x0A) Compound <xxxx>
|
||||
/// (0x0B) Vec<i32>
|
||||
/// (0x0C) Vec<i64>
|
||||
fn type_tag() -> u8;
|
||||
/// 输出自身长度
|
||||
fn len(&self) -> usize;
|
||||
/// 通过索引获取内容
|
||||
fn get_index(&self, index: usize) -> Option<Self::ValueType>;
|
||||
/// 通过名称获取内容
|
||||
fn get_name(&self, name: &str) -> Option<Self::ValueType>;
|
||||
}
|
||||
|
||||
/// 通过范型实现的 NBT List (其实包括了 NbtCompound)
|
||||
// #[derive(Debug, Clone)]
|
||||
// pub struct NbtList<T: NbtListTrait> {
|
||||
// /// 内容
|
||||
// pub value: T,
|
||||
// }
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NbtList {
|
||||
BoolArray(Rc<RefCell<Vec<bool>>>)
|
||||
}
|
||||
|
||||
|
||||
#[allow(unused)]
|
||||
impl<T> NbtList<T>
|
||||
where
|
||||
T: NbtListTrait,
|
||||
{
|
||||
pub fn type_tag() -> u8 { T::type_tag() }
|
||||
|
||||
pub fn len(&self) -> usize { self.value.len() }
|
||||
|
||||
pub fn get_index(&self, index: usize) -> Option<T::ValueType> { self.value.get_index(index) }
|
||||
|
||||
pub fn get_name(&self, name: &str) -> Option<T::ValueType> { self.value.get_name(name) }
|
||||
}
|
||||
|
||||
macro_rules! add_impl {
|
||||
($type:ty, $value:ty ,$tag:expr) => {
|
||||
impl NbtListTrait for $type {
|
||||
type ValueType = $value;
|
||||
#[inline]
|
||||
fn type_tag() -> u8 { $tag }
|
||||
#[inline]
|
||||
fn len(&self) -> usize { self.len() }
|
||||
#[inline]
|
||||
fn get_index(&self, index: usize) -> Option<Self::ValueType> { self.get(index).copied() }
|
||||
#[inline]
|
||||
fn get_name(&self, _: &str) -> Option<Self::ValueType> { None }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
add_impl!(Vec<bool>, bool, 0x07);
|
||||
add_impl!(Vec<i32>, i32, 0x0B);
|
||||
add_impl!(Vec<i64>, i64, 0x0C);
|
||||
|
||||
/// 给 HashMap 增加 NbtListTrait
|
||||
/// 用作待会儿的 NbtCompound
|
||||
impl<T> NbtListTrait for HashMap<Arc<str>, NbtItem<T>>
|
||||
where
|
||||
T: Clone + NbtListTrait,
|
||||
{
|
||||
type ValueType = NbtItem<T>;
|
||||
#[inline]
|
||||
fn type_tag() -> u8 { 0x0A }
|
||||
#[inline]
|
||||
fn len(&self) -> usize { self.len() }
|
||||
#[inline]
|
||||
fn get_index(&self, _: usize) -> Option<Self::ValueType> { None }
|
||||
#[inline]
|
||||
fn get_name(&self, name: &str) -> Option<Self::ValueType> { self.get(name).cloned() }
|
||||
}
|
||||
|
||||
/// 给 Vec<NbtItem> 增加 NbtListTrait
|
||||
/// 用作待会儿的 NbtList
|
||||
impl<T> NbtListTrait for Vec<NbtItem<T>>
|
||||
where
|
||||
T: Clone + NbtListTrait,
|
||||
{
|
||||
type ValueType = NbtItem<T>;
|
||||
#[inline]
|
||||
fn type_tag() -> u8 { 0x09 }
|
||||
#[inline]
|
||||
fn len(&self) -> usize { self.len() }
|
||||
#[inline]
|
||||
fn get_index(&self, index: usize) -> Option<Self::ValueType> { self.get(index).cloned() }
|
||||
#[inline]
|
||||
fn get_name(&self, _: &str) -> Option<Self::ValueType> { None }
|
||||
}
|
||||
|
||||
/// NbtList
|
||||
/// 来力
|
||||
#[allow(unused)]
|
||||
impl<T> NbtList<Vec<NbtItem<T>>>
|
||||
where
|
||||
T: NbtListTrait + Clone,
|
||||
{
|
||||
/// 直接读取长度和值 不带名称
|
||||
pub fn from_reader(value: &mut Reader) -> Self {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec: Vec<NbtItem<T>> = Vec::with_capacity(len as usize);
|
||||
// 先读取 type
|
||||
let mut type_buff = [0_u8; 1];
|
||||
_ = value.read(&mut type_buff).unwrap();
|
||||
match type_buff {
|
||||
[0x00] => {
|
||||
todo!()
|
||||
}
|
||||
[0x01] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_bool(value)));
|
||||
}
|
||||
}
|
||||
[0x02] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i16(value)));
|
||||
}
|
||||
}
|
||||
[0x03] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i32(value)));
|
||||
}
|
||||
}
|
||||
[0x04] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i64(value)));
|
||||
}
|
||||
}
|
||||
[0x05] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_f32(value)));
|
||||
}
|
||||
}
|
||||
[0x06] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_f64(value)));
|
||||
}
|
||||
}
|
||||
[0x07] => {
|
||||
for _ in 0..len {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Array( todo!() ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// ByteArray
|
||||
#[allow(unused)]
|
||||
impl NbtList<Vec<bool>> {
|
||||
/// 直接读取长度和值 不带名称
|
||||
pub fn from_reader(value: &mut Reader) -> Self {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
// 读取内容
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_bool(value).as_bool().unwrap());
|
||||
}
|
||||
Self { value: vec }
|
||||
}
|
||||
}
|
||||
|
||||
/// IntArray
|
||||
#[allow(unused)]
|
||||
impl NbtList<Vec<i32>> {
|
||||
/// 直接读取长度和值 不带名称
|
||||
pub fn from_reader(value: &mut Reader) -> Self {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
// 读取内容
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_i32(value).as_i32().unwrap());
|
||||
}
|
||||
Self { value: vec }
|
||||
}
|
||||
}
|
||||
|
||||
/// LongArray
|
||||
#[allow(unused)]
|
||||
impl NbtList<Vec<i64>> {
|
||||
/// 直接读取长度和值 不带名称
|
||||
pub fn from_reader(value: &mut Reader) -> Self {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
// 读取内容
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_i64(value).as_i64().unwrap());
|
||||
}
|
||||
Self { value: vec }
|
||||
}
|
||||
BoolArray(Rc<RefCell<Vec<bool>>>),
|
||||
IntArray(Rc<RefCell<Vec<i32>>>),
|
||||
LongArray(Rc<RefCell<Vec<i64>>>),
|
||||
List(Rc<RefCell<Vec<NbtItem>>>),
|
||||
Compound(Rc<RefCell<HashMap<Arc<str>, NbtItem>>>),
|
||||
}
|
||||
|
||||
/// 基本 NBT 数据类型
|
||||
@ -261,6 +53,24 @@ pub enum NbtValue {
|
||||
NbtString(Arc<str>),
|
||||
}
|
||||
|
||||
impl NbtItem {
|
||||
#[inline]
|
||||
pub fn as_value(&self) -> Option<&NbtValue> {
|
||||
match self {
|
||||
Self::Value(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_array(&self) -> Option<&NbtList> {
|
||||
match self {
|
||||
Self::Array(value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! export_data {
|
||||
($name:ident, $nbt_name:ident, $type:ty) => {
|
||||
#[inline]
|
||||
@ -327,6 +137,9 @@ impl NbtValue {
|
||||
/// 直接读取
|
||||
pub fn from_string(value: &mut Reader) -> Self {
|
||||
let len: StringLength = Self::from_i32(value).as_i32().unwrap() as StringLength;
|
||||
if len == 0 {
|
||||
return Self::NbtString(Arc::from(""));
|
||||
}
|
||||
let mut buff = vec![0_u8; len as usize];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
Self::NbtString(Arc::from(String::from_utf8(buff).unwrap()))
|
||||
|
@ -1,4 +1,5 @@
|
||||
mod data;
|
||||
mod read;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
166
src/read.rs
166
src/read.rs
@ -1 +1,165 @@
|
||||
use crate::data::NbtValue;
|
||||
use crate::data::{NbtItem, NbtLength, NbtList, NbtValue, Reader};
|
||||
use std::cell::RefCell;
|
||||
use std::convert::{From, Into};
|
||||
use std::io::{Cursor, Read};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// 输出类型标识符
|
||||
/// 类型标识符
|
||||
/// (0x07) Vec<bool>
|
||||
/// (0x08) UTF-8 String (Arc<str>)
|
||||
/// (0x09) Vec<NbtItem>
|
||||
/// (0x0A) Compound <xxxx>
|
||||
/// (0x0B) Vec<i32>
|
||||
/// (0x0C) Vec<i64>
|
||||
pub mod read {
|
||||
use crate::data::{NbtItem, NbtLength, NbtList, NbtValue, Reader};
|
||||
use std::cell::RefCell;
|
||||
use std::io::Read;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// 直接读取长度和值 不带名称
|
||||
/// 反正名字都在外面读过
|
||||
#[inline]
|
||||
pub fn from_bool_array(value: &mut Reader) -> Vec<bool> {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_bool(value).as_bool().unwrap());
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
/// 直接读取长度和值 不带名称
|
||||
#[inline]
|
||||
pub fn from_i32_array(value: &mut Reader) -> Vec<i32> {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_i32(value).as_i32().unwrap());
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
/// 直接读取长度和值 不带名称
|
||||
#[inline]
|
||||
pub fn from_i64_array(value: &mut Reader) -> Vec<i64> {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
for _ in 0..len {
|
||||
vec.push(NbtValue::from_i64(value).as_i64().unwrap());
|
||||
}
|
||||
vec
|
||||
}
|
||||
|
||||
/// 直接读取长度和值 不带名称
|
||||
pub fn read_nbt_list(value: &mut Reader) -> Vec<NbtItem> {
|
||||
// 读取长度
|
||||
let mut buff = [0_u8; 4];
|
||||
_ = value.read(&mut buff).unwrap();
|
||||
let len = NbtLength::from_be_bytes(buff);
|
||||
let mut vec: Vec<NbtItem> = Vec::with_capacity(len as usize);
|
||||
// 先读取 type
|
||||
let mut type_buff = [0_u8; 1];
|
||||
_ = value.read(&mut type_buff).unwrap();
|
||||
match type_buff {
|
||||
[0x00] => {
|
||||
todo!()
|
||||
}
|
||||
[0x01] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_bool(value)));
|
||||
}
|
||||
}
|
||||
[0x02] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i16(value)));
|
||||
}
|
||||
}
|
||||
[0x03] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i32(value)));
|
||||
}
|
||||
}
|
||||
[0x04] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_i64(value)));
|
||||
}
|
||||
}
|
||||
[0x05] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_f32(value)));
|
||||
}
|
||||
}
|
||||
[0x06] => {
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_f64(value)));
|
||||
}
|
||||
}
|
||||
[0x07] => {
|
||||
// ByteArray
|
||||
for _ in 0..len {
|
||||
let arr = Rc::new(RefCell::new(from_bool_array(value)));
|
||||
vec.push(NbtItem::Array(NbtList::BoolArray(arr)));
|
||||
}
|
||||
}
|
||||
[0x08] => {
|
||||
// string
|
||||
for _ in 0..len {
|
||||
vec.push(NbtItem::Value(NbtValue::from_string(value)));
|
||||
}
|
||||
}
|
||||
[0x09] => {
|
||||
// NbtList
|
||||
// 要命 (虽说没 Compound 那么麻烦)
|
||||
}
|
||||
[0x0A] => {
|
||||
// Compound
|
||||
// 他甚至不告诉你有多少个元素,要命
|
||||
}
|
||||
[0x0B] => {
|
||||
// IntArray
|
||||
for _ in 0..len {
|
||||
let arr = Rc::new(RefCell::new(from_i32_array(value)));
|
||||
vec.push(NbtItem::Array(NbtList::IntArray(arr)));
|
||||
}
|
||||
}
|
||||
[0x0C] => {
|
||||
// LongArray
|
||||
for _ in 0..len {
|
||||
let arr = Rc::new(RefCell::new(from_i64_array(value)));
|
||||
vec.push(NbtItem::Array(NbtList::LongArray(arr)));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"WTF while reading Nbt List \ntype: {:?}\nreader pos: {:?}",
|
||||
type_buff,
|
||||
value.position()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
||||
/// NbtItem
|
||||
/// 完整的读取逻辑就在这里了
|
||||
/// 来力
|
||||
#[allow(unused)]
|
||||
impl From<Cursor<&[u8]>> for NbtItem {
|
||||
/// 完整逻辑~
|
||||
fn from(value: Reader) -> NbtItem { todo!() }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user