This commit is contained in:
GIKExe 2025-05-19 06:59:47 +03:00
parent 07b7fd4cdf
commit 52ed60c758
12 changed files with 293 additions and 200 deletions

BIN
level.dat Normal file

Binary file not shown.

View File

@ -1,5 +1,7 @@
use tokio::{net::TcpStream, time::Sleep};
use std::{thread::sleep, time::Duration};
use tokio::net::TcpStream;
use crate::data::{clientbound, serverbound, AsyncReader, AsyncWriter, DataError, Packet, Reader, TextComponentBuilder, Writer};
@ -153,6 +155,6 @@ async fn the_configuration(conn: &mut Connection) -> Result<(), PacketError> {
let packet = Packet::empty(clientbound::configuration::FINISH);
conn.write_packet(packet).await?;
loop {
sleep(Duration::from_secs(1));
}
}

View File

@ -12,7 +12,6 @@ mod writer;
mod packet;
mod packet_id;
mod component;
mod nbt;
#[derive(Debug)]
pub enum DataError {
@ -25,7 +24,7 @@ pub enum DataError {
DeSerializationError,
ZlibError,
NBTError,
NBTCompoundError,
// NBTCompoundError,
}
pub type Buffer = Cursor<Vec<u8>>;
@ -49,5 +48,4 @@ pub use async_writer::*;
pub use writer::*;
pub use packet::*;
pub use packet_id::{clientbound, serverbound};
pub use component::*;
pub use nbt::*;
pub use component::*;

View File

@ -1,154 +0,0 @@
use std::{collections::HashMap, io::Cursor};
use super::{DataError, Reader};
const TAG_END: u8 = 0;
const TAG_BYTE: u8 = 1;
const TAG_SHORT: u8 = 2;
const TAG_INT: u8 = 3;
const TAG_LONG: u8 = 4;
const TAG_FLOAT: u8 = 5;
const TAG_DOUBLE: u8 = 6;
const TAG_BYTE_ARRAY: u8 = 7;
const TAG_STRING: u8 = 8;
const TAG_LIST: u8 = 9;
const TAG_COMPOUND: u8 = 10;
const TAG_INT_ARRAY: u8 = 11;
const TAG_LONG_ARRAY: u8 = 12;
#[derive(Debug)]
pub enum TAG {
END,
COMPOUND(HashMap<String, TAG>),
STRING(String),
BYTE(i8),
SHORT(i16),
INT(i32),
LONG(i64),
FLOAT(f32),
DOUBLE(f64),
LIST(Vec<NBT>),
BYTE_ARRAY(Vec<i8>),
INT_ARRAY(Vec<i32>),
LONG_ARRAY(Vec<i64>),
}
#[derive(Debug)]
pub struct NBT {
pub key: Option<String>,
pub value: TAG,
}
impl NBT {
fn new(key: Option<String>, value: TAG) -> Self {
Self { key, value }
}
}
pub trait NBT_Reader {
fn _read_nbt(&mut self, root: bool, inet: bool, byte: Option<u8>) -> Result<NBT, DataError>;
fn read_nbt(&mut self, inet: bool) -> Result<NBT, DataError>;
}
impl NBT_Reader for Cursor<Vec<u8>> {
fn read_nbt(&mut self, inet: bool) -> Result<NBT, DataError> {
self._read_nbt(true, inet, None)
}
fn _read_nbt(&mut self, root: bool, inet: bool, b: Option<u8>) -> Result<NBT, DataError> {
let byte = match b { Some(v) => v, None => self.read_byte()? };
let mut key: Option<String>;
if byte == TAG_END {
return Ok(NBT::new(None, TAG::END));
}
if root & (byte != TAG_COMPOUND) {
return Err(DataError::NBTCompoundError)
}
if root & inet {
key = None;
} else {
let size = self.read_short()? as usize;
let buf = self.read_bytes(size)?;
key = Some(String::from_utf8_lossy(&buf).to_string());
}
if b.is_some() {
key = None;
}
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<i32> = 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<i64> = 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<NBT> = Vec::new();
let count = self.read_signed_int()? as usize;
println!("List count: {count}");
for _ in 0..count {
buf.push(self._read_nbt(false, inet, None)?);
}
Ok(NBT::new(key, TAG::LIST(buf)))
},
TAG_COMPOUND => {
// println!("COMPOUND");
let mut map = HashMap::new();
loop {
let nbt = self._read_nbt(false, inet, None)?;
if matches!(nbt.value, TAG::END) { break; };
let Some(key) = nbt.key else { continue; };
map.insert(key, nbt.value);
}
Ok(NBT::new(key, TAG::COMPOUND(map)))
}
_ => {
// println!("o: {other}");
Err(DataError::NBTError)
}
}
}
}

View File

@ -73,12 +73,16 @@ pub trait Reader {
Ok(self.read_short()? as i16)
}
fn read_signed_int(&mut self) -> Result<i32, DataError> {
Ok(i32::from_be_bytes(
fn read_int(&mut self) -> Result<u32, DataError> {
Ok(u32::from_be_bytes(
self.read_bytes(4)?.try_into().unwrap()
))
}
fn read_signed_int(&mut self) -> Result<i32, DataError> {
Ok(self.read_int()? as i32)
}
fn read_long(&mut self) -> Result<u64, DataError> {
Ok(u64::from_be_bytes(
self.read_bytes(8)?.try_into().unwrap()

View File

@ -74,10 +74,12 @@ pub trait Writer {
self.write_short(value as u16)
}
fn write_string(&mut self, value: &str) -> Result<(), DataError> {
self.write_varint(value.len() as i32)?;
self.write_bytes(value.as_bytes())?;
Ok(())
fn write_int(&mut self, value: u32) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes())
}
fn write_signed_int(&mut self, value: i32) -> Result<(), DataError> {
self.write_int(value as u32)
}
fn write_long(&mut self, value: u64) -> Result<(), DataError> {
@ -88,6 +90,20 @@ pub trait Writer {
self.write_long(value as u64)
}
fn write_float(&mut self, value: f32) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes())
}
fn write_double(&mut self, value: f64) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes())
}
fn write_string(&mut self, value: &str) -> Result<(), DataError> {
self.write_varint(value.len() as i32)?;
self.write_bytes(value.as_bytes())?;
Ok(())
}
fn write_uuid(&mut self, value: u128) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes())
}

4
src/lib.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod inet;
pub mod data;
pub mod cycle;
pub mod nbt;

View File

@ -1,41 +1,16 @@
use rust_mc_serv::{cycle, inet::Server};
use std::fs;
use data::{Buffer, NBT_Reader, Reader};
use inet::Server;
mod data;
mod inet;
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));
// }
let mut buf = Buffer::new(fs::read("servers.dat").unwrap());
// let mut buf = Buffer::new(vec![
// 0x0a,
// // 0x00, 0x0b,
// // 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
// 0x08,
// 0x00, 0x04,
// 0x6e, 0x61, 0x6d, 0x65,
// 0x00, 0x05,
// 0x42, 0x61, 0x6e, 0x61, 0x6e,
// 0x00
// ]);
let nbt = buf.read_nbt(false).unwrap();
println!("{nbt:?}");
loop {
let stream = server.accept().await;
tokio::spawn(cycle::main(stream));
}
}

25
src/nbt/mod.rs Normal file
View File

@ -0,0 +1,25 @@
pub mod reader;
pub mod writer;
mod tags;
use std::collections::HashMap;
pub use reader::*;
pub use writer::*;
#[derive(Debug)]
pub enum Tag {
End,
Byte(i8),
Short(i16),
Int(i32),
Long(i64),
Float(f32),
Double(f64),
ByteArray(Vec<i8>),
String(String),
List(Vec<Tag>),
Compound(HashMap<String, Tag>),
IntArray(Vec<i32>),
LongArray(Vec<i64>),
}

98
src/nbt/reader.rs Normal file
View File

@ -0,0 +1,98 @@
use std::{collections::HashMap, io::Seek};
use crate::data::{Buffer, DataError, Reader};
use super::{tags::*, Tag};
trait NbtReaderInternal {
fn read_value(&mut self, t: u8) -> Result<Tag, DataError>;
fn read_compound(&mut self) -> Result<Tag, DataError>;
fn read_list(&mut self) -> Result<Tag, DataError>;
}
impl NbtReaderInternal for Buffer {
fn read_value(&mut self, t: u8) -> Result<Tag, DataError> {
match t {
TAG_END => { self.read_byte()?; Ok(Tag::End) }
TAG_BYTE => { Ok(Tag::Byte(self.read_signed_byte()?)) }
TAG_SHORT => { Ok(Tag::Short(self.read_signed_short()?)) }
TAG_INT => { Ok(Tag::Int(self.read_signed_int()?)) }
TAG_LONG => { Ok(Tag::Long(self.read_signed_long()?)) }
TAG_FLOAT => { Ok(Tag::Float(self.read_float()?)) }
TAG_DOUBLE => { Ok(Tag::Double(self.read_double()?)) }
TAG_BYTE_ARRAY => {
let size = self.read_int()? as usize;
Ok(Tag::ByteArray(self.read_bytes(size)?.into_iter().map(|x| x as i8).collect()))
}
TAG_STRING => {
let size = self.read_short()? as usize;
let data = self.read_bytes(size)?;
Ok(Tag::String(String::from_utf8_lossy(&data).to_string()))
}
TAG_LIST => { self.read_list() }
TAG_COMPOUND => { self.read_compound() }
TAG_INT_ARRAY => {
let size = self.read_int()? as usize;
let mut data = Vec::new();
for _ in 0..size {
data.push(self.read_signed_int()?);
}
Ok(Tag::IntArray(data))
}
TAG_LONG_ARRAY => {
let size = self.read_int()? as usize;
let mut data = Vec::new();
for _ in 0..size {
data.push(self.read_signed_long()?);
}
Ok(Tag::LongArray(data))
}
other => {
println!("Неверный тэг: {other}");
Err(DataError::NBTError)
}
}
}
fn read_compound(&mut self) -> Result<Tag, DataError> {
let mut map = HashMap::new();
loop {
let type_of_value = self.read_byte()?;
if type_of_value == TAG_END { break; }
let size = self.read_short()? as usize;
let key = String::from_utf8_lossy(&self.read_bytes(size)?).to_string();
map.insert(key, self.read_value(type_of_value)?);
}
Ok(Tag::Compound(map))
}
fn read_list(&mut self) -> Result<Tag, DataError> {
let type_of_list = self.read_byte()?;
let size_of_list = self.read_signed_int()?;
let mut list = Vec::new();
if size_of_list <= 0 { return Ok(Tag::List(list)); };
for _ in 0..size_of_list {
list.push(self.read_value(type_of_list)?);
}
Ok(Tag::List(list))
}
}
pub trait NbtReader {
fn read_nbt(&mut self) -> Result<Tag, DataError>;
}
impl NbtReader for Buffer {
fn read_nbt(&mut self) -> Result<Tag, DataError> {
if self.read_byte()? != TAG_COMPOUND {
return Err(DataError::NBTError);
}
if self.read_short()? != 0 {
let _ = self.seek_relative(-2);
}
self.read_compound()
}
}

16
src/nbt/tags.rs Normal file
View File

@ -0,0 +1,16 @@
pub const TAG_END: u8 = 0;
pub const TAG_BYTE: u8 = 1;
pub const TAG_SHORT: u8 = 2;
pub const TAG_INT: u8 = 3;
pub const TAG_LONG: u8 = 4;
pub const TAG_FLOAT: u8 = 5;
pub const TAG_DOUBLE: u8 = 6;
pub const TAG_BYTE_ARRAY: u8 = 7;
pub const TAG_STRING: u8 = 8;
pub const TAG_LIST: u8 = 9;
pub const TAG_COMPOUND: u8 = 10;
pub const TAG_INT_ARRAY: u8 = 11;
pub const TAG_LONG_ARRAY: u8 = 12;

109
src/nbt/writer.rs Normal file
View File

@ -0,0 +1,109 @@
use std::collections::HashMap;
use crate::data::{Buffer, DataError, Writer};
use super::{tags::*, Tag};
fn get_id(tag: &Tag) -> u8 {
match tag {
Tag::End => TAG_END,
Tag::Byte(_) => TAG_BYTE,
Tag::Short(_) => TAG_SHORT,
Tag::Int(_) => TAG_INT,
Tag::Long(_) => TAG_LONG,
Tag::Float(_) => TAG_FLOAT,
Tag::Double(_) => TAG_DOUBLE,
Tag::ByteArray(_) => TAG_BYTE_ARRAY,
Tag::String(_) => TAG_STRING,
Tag::List(_) => TAG_LIST,
Tag::Compound(_) => TAG_COMPOUND,
Tag::IntArray(_) => TAG_INT_ARRAY,
Tag::LongArray(_) => TAG_LONG_ARRAY,
}
}
trait NbtWriterInternal {
fn write_value(&mut self, tag: Tag) -> Result<(), DataError>;
fn write_compound(&mut self, map: HashMap<String, Tag>) -> Result<(), DataError>;
fn write_list(&mut self, list: Vec<Tag>) -> Result<(), DataError>;
}
impl NbtWriterInternal for Buffer {
fn write_value(&mut self, tag: Tag) -> Result<(), DataError> {
match tag {
Tag::End => self.write_byte(0)?,
Tag::Byte(value) => self.write_signed_byte(value)?,
Tag::Short(value) => self.write_signed_short(value)?,
Tag::Int(value) => self.write_signed_int(value)?,
Tag::Long(value) => self.write_signed_long(value)?,
Tag::Float(value) => self.write_float(value)?,
Tag::Double(value) => self.write_double(value)?,
Tag::ByteArray(value) => {
self.write_int(value.len() as u32)?;
let data: Vec<u8> = value.into_iter().map(|x| x as u8).collect();
self.write_bytes(&data)?;
}
Tag::String(value) => {
self.write_short(value.len() as u16)?;
self.write_bytes(value.as_bytes())?;
}
Tag::List(list) => self.write_list(list)?,
Tag::Compound(map) => self.write_compound(map)?,
Tag::IntArray(list) => {
self.write_int(list.len() as u32)?;
for value in list {
self.write_signed_int(value)?;
}
}
Tag::LongArray(list) => {
self.write_int(list.len() as u32)?;
for value in list {
self.write_signed_long(value)?;
}
}
}
Ok(())
}
fn write_compound(&mut self, map: HashMap<String, Tag>) -> Result<(), DataError> {
for (key, tag) in map {
self.write_byte(get_id(&tag))?;
self.write_short(key.len() as u16)?;
self.write_bytes(key.as_bytes())?;
self.write_value(tag)?;
}
Ok(())
}
fn write_list(&mut self, list: Vec<Tag>) -> Result<(), DataError> {
let type_of_list = match list.as_slice() {
[] => 0, [first, rest @ ..] => {
let first_id = get_id(first);
if rest.iter().all(|tag| get_id(tag) == first_id) { first_id }
else { return Err(DataError::NBTError) }
}
};
self.write_byte(type_of_list)?;
self.write_int(list.len() as u32)?;
for tag in list {
self.write_value(tag)?;
}
Ok(())
}
}
pub trait NbtWriter {
fn write_nbt(&mut self, tag: Tag, to_file: bool) -> Result<(), DataError>;
}
impl NbtWriter for Buffer {
fn write_nbt(&mut self, tag: Tag, to_file: bool) -> Result<(), DataError> {
let Tag::Compound(map) = tag else { return Err(DataError::NBTError); };
self.write_byte(TAG_COMPOUND)?;
if to_file { self.write_short(0)? };
self.write_compound(map)?;
Ok(())
}
}