Compare commits

..

No commits in common. "52ed60c75852f2eb9daa5cbd630551ec1d695f08" and "077c3e71089c857ccfe80ee0a5f71c8c7626217e" have entirely different histories.

14 changed files with 106 additions and 312 deletions

BIN
level.dat

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,5 @@
use std::{thread::sleep, time::Duration};
use tokio::net::TcpStream;
use tokio::{net::TcpStream, time::Sleep};
use crate::data::{clientbound, serverbound, AsyncReader, AsyncWriter, DataError, Packet, Reader, TextComponentBuilder, Writer};
@ -155,6 +153,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

@ -32,6 +32,10 @@ pub trait AsyncReader {
Ok(self.read_bytes(1).await?[0])
}
async fn read_signed_byte(&mut self) -> Result<i8, DataError> {
Ok(self.read_byte().await? as i8)
}
async fn read_varint_size(&mut self) -> Result<(i32, usize), DataError> {
let mut value = 0;
let mut position = 0;
@ -67,4 +71,36 @@ pub trait AsyncReader {
let id = cursor.read_varint()?;
Ok(Packet::new(id as u8, cursor))
}
async fn read_short(&mut self) -> Result<u16, DataError> {
Ok(u16::from_be_bytes(
self.read_bytes(2).await?.try_into().unwrap()
))
}
async fn read_signed_short(&mut self) -> Result<i16, DataError> {
Ok(self.read_short().await? as i16)
}
async fn read_string(&mut self) -> Result<String, DataError> {
let size = self.read_varint().await?;
let vec = self.read_bytes(size as usize).await?;
String::from_utf8(vec).or( Err(DataError::StringDecodeError))
}
async fn read_long(&mut self) -> Result<u64, DataError> {
Ok(u64::from_be_bytes(
self.read_bytes(8).await?.try_into().unwrap()
))
}
async fn read_signed_long(&mut self) -> Result<i64, DataError> {
Ok(self.read_long().await? as i64)
}
async fn read_uuid(&mut self) -> Result<u128, DataError> {
Ok(u128::from_be_bytes(
self.read_bytes(16).await?.try_into().unwrap()
))
}
}

View File

@ -15,6 +15,30 @@ impl AsyncWriter for TcpStream {
pub trait AsyncWriter {
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>;
async fn write_byte(&mut self, value: u8) -> Result<(), DataError> {
self.write_bytes(&[value]).await
}
async fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> {
self.write_byte(value as u8).await
}
async fn write_varint_size(&mut self, value: i32) -> Result<usize, DataError> {
let mut _value = value as u32;
let mut position = 0;
loop {
let mut byte = (_value & 127) as u8;
position += 1; _value >>= 7;
if _value != 0 { byte += 128; };
self.write_byte(byte).await?;
if _value == 0 { return Ok(position) }
}
}
async fn write_varint(&mut self, value: i32) -> Result<(), DataError> {
self.write_varint_size(value).await?; Ok(())
}
async fn write_packet(&mut self, packet: Packet, threshold: Option<usize>)
-> Result<(), DataError> {
let mut buf = Vec::new();
@ -43,4 +67,30 @@ pub trait AsyncWriter {
self.write_bytes(&buf).await?;
Ok(())
}
async fn write_short(&mut self, value: u16) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes()).await
}
async fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> {
self.write_short(value as u16).await
}
async fn write_string(&mut self, value: &str) -> Result<(), DataError> {
self.write_varint(value.len() as i32).await?;
self.write_bytes(value.as_bytes()).await?;
Ok(())
}
async fn write_long(&mut self, value: u64) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes()).await
}
async fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> {
self.write_long(value as u64).await
}
async fn write_uuid(&mut self, value: u128) -> Result<(), DataError> {
self.write_bytes(&value.to_be_bytes()).await
}
}

View File

@ -1,4 +1,4 @@
use std::io::{Cursor, Read, Write};
use std::io::{Read, Write};
use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression};
@ -23,12 +23,8 @@ pub enum DataError {
SerializationError,
DeSerializationError,
ZlibError,
NBTError,
// NBTCompoundError,
}
pub type Buffer = Cursor<Vec<u8>>;
pub fn decompress(bytes: &[u8]) -> Result<Vec<u8>, DataError> {
let mut decoder = ZlibDecoder::new(bytes);
let mut output = Vec::new();

View File

@ -1,13 +1,11 @@
use std::io::{Cursor, Read};
use super::{decompress, Buffer, DataError, Packet};
use super::{decompress, DataError, Packet};
impl Reader for Buffer {
impl<R: Read> Reader for R {
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
println!("Read bytes: {size}");
if size == 0 { return Ok(Vec::new());};
let mut buf = vec![0; size];
match self.read_exact(&mut buf) {
Ok(_) => Ok(buf),
@ -73,14 +71,10 @@ pub trait Reader {
Ok(self.read_short()? as i16)
}
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_string(&mut self) -> Result<String, DataError> {
let size = self.read_varint()?;
let vec = self.read_bytes(size as usize)?;
String::from_utf8(vec).or( Err(DataError::StringDecodeError))
}
fn read_long(&mut self) -> Result<u64, DataError> {
@ -93,24 +87,6 @@ pub trait Reader {
Ok(self.read_long()? as i64)
}
fn read_float(&mut self) -> Result<f32, DataError> {
Ok(f32::from_be_bytes(
self.read_bytes(4)?.try_into().unwrap()
))
}
fn read_double(&mut self) -> Result<f64, DataError> {
Ok(f64::from_be_bytes(
self.read_bytes(8)?.try_into().unwrap()
))
}
fn read_string(&mut self) -> Result<String, DataError> {
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<u128, DataError> {
Ok(u128::from_be_bytes(
self.read_bytes(16)?.try_into().unwrap()

View File

@ -74,12 +74,10 @@ pub trait Writer {
self.write_short(value as u16)
}
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_string(&mut self, value: &str) -> Result<(), DataError> {
self.write_varint(value.len() as i32)?;
self.write_bytes(value.as_bytes())?;
Ok(())
}
fn write_long(&mut self, value: u64) -> Result<(), DataError> {
@ -90,20 +88,6 @@ 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())
}

View File

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

View File

@ -1,6 +1,12 @@
use rust_mc_serv::{cycle, inet::Server};
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 {

View File

@ -1,25 +0,0 @@
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>),
}

View File

@ -1,98 +0,0 @@
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()
}
}

View File

@ -1,16 +0,0 @@
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;

View File

@ -1,109 +0,0 @@
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(())
}
}