Compare commits

...

2 Commits

Author SHA1 Message Date
d5acd42cb8
把配置丢上去吧 2023-08-04 14:29:59 +08:00
79719b2844
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 2023-08-04 14:29:52 +08:00
10 changed files with 269 additions and 216 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View 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>

View 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
View 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
View 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
View 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
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -14,227 +14,19 @@ pub type StringLength = u32;
/// Reader /// Reader
pub type Reader<'a> = Cursor<&'a [u8]>; pub type Reader<'a> = Cursor<&'a [u8]>;
#[allow(unused)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum NbtItem<T: NbtListTrait> { pub enum NbtItem {
Value(NbtValue), Value(NbtValue),
Array(NbtList), Array(NbtList),
} }
/// 一个 NBT list 的基本素养 #[derive(Debug, Clone)]
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,
// }
pub enum NbtList { pub enum NbtList {
BoolArray(Rc<RefCell<Vec<bool>>>) BoolArray(Rc<RefCell<Vec<bool>>>),
} IntArray(Rc<RefCell<Vec<i32>>>),
LongArray(Rc<RefCell<Vec<i64>>>),
List(Rc<RefCell<Vec<NbtItem>>>),
#[allow(unused)] Compound(Rc<RefCell<HashMap<Arc<str>, NbtItem>>>),
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 }
}
} }
/// 基本 NBT 数据类型 /// 基本 NBT 数据类型
@ -261,6 +53,24 @@ pub enum NbtValue {
NbtString(Arc<str>), 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 { macro_rules! export_data {
($name:ident, $nbt_name:ident, $type:ty) => { ($name:ident, $nbt_name:ident, $type:ty) => {
#[inline] #[inline]
@ -327,6 +137,9 @@ impl NbtValue {
/// 直接读取 /// 直接读取
pub fn from_string(value: &mut Reader) -> Self { pub fn from_string(value: &mut Reader) -> Self {
let len: StringLength = Self::from_i32(value).as_i32().unwrap() as StringLength; 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]; let mut buff = vec![0_u8; len as usize];
_ = value.read(&mut buff).unwrap(); _ = value.read(&mut buff).unwrap();
Self::NbtString(Arc::from(String::from_utf8(buff).unwrap())) Self::NbtString(Arc::from(String::from_utf8(buff).unwrap()))

View File

@ -1,4 +1,5 @@
mod data; mod data;
mod read;
fn main() { fn main() {
println!("Hello, world!"); println!("Hello, world!");

View File

@ -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!() }
}