From 3e5fb4f149e5bf89a5ff18676e40422f8b6218c2 Mon Sep 17 00:00:00 2001 From: GIKExe <72767917+GIKExe@users.noreply.github.com> Date: Fri, 16 May 2025 10:05:00 +0300 Subject: [PATCH] nbt 90% --- src/data/mod.rs | 5 ++- src/data/nbt.rs | 87 +++++++++++++++++++++++++++++++++++++++++----- src/data/reader.rs | 30 ++++++++++++---- src/main.rs | 18 +++++----- 4 files changed, 114 insertions(+), 26 deletions(-) diff --git a/src/data/mod.rs b/src/data/mod.rs index 46a1a5d..204b6da 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,4 +1,4 @@ -use std::io::{Read, Write}; +use std::io::{Cursor, Read, Write}; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; @@ -24,8 +24,11 @@ pub enum DataError { SerializationError, DeSerializationError, ZlibError, + NBTError, } +type Buffer = Cursor>; + pub fn decompress(bytes: &[u8]) -> Result, DataError> { let mut decoder = ZlibDecoder::new(bytes); let mut output = Vec::new(); diff --git a/src/data/nbt.rs b/src/data/nbt.rs index 8eb1322..36ac463 100644 --- a/src/data/nbt.rs +++ b/src/data/nbt.rs @@ -1,5 +1,7 @@ use std::io::Cursor; +use super::{DataError, Reader}; + @@ -17,7 +19,7 @@ const TAG_COMPOUND: u8 = 10; const TAG_INT_ARRAY: u8 = 11; const TAG_LONG_ARRAY: u8 = 12; -enum TAG { +pub enum TAG { END, COMPOUND(Vec), STRING(String), @@ -27,10 +29,10 @@ enum TAG { LONG(i64), FLOAT(f32), DOUBLE(f64), - // LIST - // BYTE_ARRAY - // INT_ARRAY - // LONG_ARRAY + LIST(Vec), + BYTE_ARRAY(Vec), + INT_ARRAY(Vec), + LONG_ARRAY(Vec), } struct NBT { @@ -39,15 +41,82 @@ struct NBT { } impl NBT { - fn new(key: String, value: TAG) -> Self { - Self { key, value } + fn new(key: &str, value: TAG) -> Self { + Self { key: key.to_string(), value } } } pub trait NBT_Reader { - + fn read_nbt(&mut self, root: bool, inet: bool, byte: Option) -> Result; } -impl NBT_Reader for Cursor> { +impl NBT_Reader for dyn Reader { + fn read_nbt(&mut self, root: bool, inet: bool, byte: Option) -> Result { + let mut byte = match byte { Some(v) => v, None => self.read_byte()? }; + let key: String; + if root & inet { + key = "".to_string(); + if byte != TAG_COMPOUND { + return Err(DataError::NBTError); + } + } else { + let size = self.read_short()? as usize; + let buf = self.read_bytes(size)?; + key = String::from_utf8_lossy(&buf).to_string(); + } + + match byte { + TAG_BYTE => { Ok(NBT::new(&key, TAG::BYTE(self.read_signed_byte()?))) }, + TAG_SHORT => { Ok(NBT::new(&key, TAG::SHORT(self.read_signed_short()?))) }, + TAG_INT => { Ok(NBT::new(&key, TAG::INT(self.read_signed_int()?))) }, + TAG_LONG => { Ok(NBT::new(&key, TAG::LONG(self.read_signed_long()?))) }, + TAG_FLOAT => { Ok(NBT::new(&key, TAG::FLOAT(self.read_float()?))) }, + TAG_DOUBLE => { Ok(NBT::new(&key, TAG::DOUBLE(self.read_double()?))) }, + + TAG_STRING => { + let size = self.read_short()? as usize; + let buf = self.read_bytes(size)?; + Ok(NBT::new(&key, TAG::STRING(String::from_utf8_lossy(&buf).to_string()))) + }, + + TAG_BYTE_ARRAY => { + let size = self.read_signed_int()? as usize; + let buf = self.read_bytes(size)?.into_iter().map(|x| x as i8).collect(); + Ok(NBT::new(&key, TAG::BYTE_ARRAY(buf))) + }, + + TAG_INT_ARRAY => { + let count = self.read_signed_int()? as usize; + let mut buf: Vec = Vec::with_capacity(count); + for _ in 0..count { + buf.push(self.read_signed_int()?); + } + Ok(NBT::new(&key, TAG::INT_ARRAY(buf))) + }, + + TAG_LONG_ARRAY => { + let count = self.read_signed_int()? as usize; + let mut buf: Vec = Vec::with_capacity(count); + for _ in 0..count { + buf.push(self.read_signed_long()?); + } + Ok(NBT::new(&key, TAG::LONG_ARRAY(buf))) + }, + + TAG_LIST => { + byte = self.read_byte()?; + let mut buf: Vec = Vec::new(); + let count = self.read_signed_int()? as usize; + for _ in 0..count { + buf.push(self.read_nbt(false, inet, Some(byte))?); + } + Ok(NBT::new(&key, TAG::LIST(buf))) + } + + + _ => Err(DataError::NBTError) + } + + } } \ No newline at end of file diff --git a/src/data/reader.rs b/src/data/reader.rs index 352a82f..809fc61 100644 --- a/src/data/reader.rs +++ b/src/data/reader.rs @@ -1,10 +1,10 @@ use std::io::{Cursor, Read}; -use super::{decompress, DataError, Packet}; +use super::{decompress, Buffer, DataError, Packet}; -impl Reader for R { +impl Reader for Buffer { fn read_bytes(&mut self, size: usize) -> Result, DataError> { let mut buf = vec![0; size]; match self.read_exact(&mut buf) { @@ -71,10 +71,10 @@ pub trait Reader { Ok(self.read_short()? as i16) } - fn read_string(&mut self) -> Result { - let size = self.read_varint()?; - let vec = self.read_bytes(size as usize)?; - String::from_utf8(vec).or( Err(DataError::StringDecodeError)) + fn read_signed_int(&mut self) -> Result { + Ok(i32::from_be_bytes( + self.read_bytes(4)?.try_into().unwrap() + )) } fn read_long(&mut self) -> Result { @@ -87,6 +87,24 @@ pub trait Reader { Ok(self.read_long()? as i64) } + fn read_float(&mut self) -> Result { + Ok(f32::from_be_bytes( + self.read_bytes(4)?.try_into().unwrap() + )) + } + + fn read_double(&mut self) -> Result { + Ok(f64::from_be_bytes( + self.read_bytes(8)?.try_into().unwrap() + )) + } + + fn read_string(&mut self) -> Result { + let size = self.read_varint()?; + let vec = self.read_bytes(size as usize)?; + String::from_utf8(vec).or( Err(DataError::StringDecodeError)) + } + fn read_uuid(&mut self) -> Result { Ok(u128::from_be_bytes( self.read_bytes(16)?.try_into().unwrap() diff --git a/src/main.rs b/src/main.rs index 24af8b6..923a66e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,16 +9,14 @@ mod cycle; #[tokio::main] async fn main() { - // let Ok(server) = Server::new("127.0.0.1:25565").await else { - // println!("Не удалось забиндить сервер"); - // return; - // }; + let Ok(server) = Server::new("127.0.0.1:25565").await else { + println!("Не удалось забиндить сервер"); + return; + }; - // loop { - // let stream = server.accept().await; - // tokio::spawn(cycle::main(stream)); - // } - - + loop { + let stream = server.accept().await; + tokio::spawn(cycle::main(stream)); + } }