diff --git a/src/cycle.rs b/src/cycle.rs index d0ac983..7c93ce7 100644 --- a/src/cycle.rs +++ b/src/cycle.rs @@ -1,7 +1,7 @@ use tokio::net::TcpStream; -use crate::data::{clientbound, serverbound, DataError, AsyncReader, DataWriter, Packet, TextComponentBuilder}; +use crate::data::{clientbound, serverbound, AsyncReader, AsyncWriter, DataError, Packet, Reader, TextComponentBuilder, Writer}; #[derive(Debug)] @@ -33,10 +33,10 @@ pub async fn main(mut stream: TcpStream) { async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> { let mut packet = stream.read_packet(None).await?; if packet.id() != 0 { return Err(PacketError::WrongPacketID);} - let version = packet.read_varint().await?; - let host = packet.read_string().await?; - let port = packet.read_short().await?; - let ns = packet.read_varint().await?; + let version = packet.read_varint()?; + let host = packet.read_string()?; + let port = packet.read_short()?; + let ns = packet.read_varint()?; if version != 770 { let mut packet = Packet::empty(0x00); @@ -45,7 +45,7 @@ async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> { .text("Версия игры отличается от 1.21.5") .color("red") .build(); - packet.write_string(&component.as_json()?).await?; + packet.write_string(&component.as_json()?)?; return Ok(stream.write_packet(packet, None).await?); } @@ -70,13 +70,13 @@ async fn the_status(stream: &mut TcpStream) -> Result<(), PacketError> { \"online\": 1 } }"; - p.write_string(status).await?; + p.write_string(status)?; stream.write_packet(p, None).await?; let mut packet = stream.read_packet(None).await?; if packet.id() != 1 { return Err(PacketError::WrongPacketID); } let mut p = Packet::empty(clientbound::status::PONG_RESPONSE); - p.write_long(packet.read_long().await?).await?; + p.write_long(packet.read_long()?)?; stream.write_packet(p, None).await?; Ok(()) @@ -91,7 +91,7 @@ async fn the_login(stream: &mut TcpStream, data: (i32, String, u16)) -> Result<( .text("Версия игры отличается от 1.21.5") .color("red") .build(); - packet.write_string(&component.as_json()?).await?; + packet.write_string(&component.as_json()?)?; return Ok(stream.write_packet(packet, None).await?); } @@ -109,15 +109,15 @@ async fn the_login(stream: &mut TcpStream, data: (i32, String, u16)) -> Result<( let mut packet = stream.read_packet(None).await?; if packet.id() != serverbound::login::START { return Err(PacketError::WrongPacketID); } - let username = packet.read_string().await?; - let uuid = packet.read_uuid().await?; + let username = packet.read_string()?; + let uuid = packet.read_uuid()?; println!("Адрес клиента: {:?}", stream.peer_addr()); println!("Адрес сервера: {}:{}", data.1, data.2); println!("Username: {username}\n UUID: {:X}", uuid); let mut packet = Packet::empty(clientbound::login::SET_COMPRESSION); - packet.write_varint(512).await?; + packet.write_varint(512)?; Ok(()) } \ No newline at end of file diff --git a/src/data/async_reader.rs b/src/data/async_reader.rs index b38eea7..61f7cae 100644 --- a/src/data/async_reader.rs +++ b/src/data/async_reader.rs @@ -1,13 +1,30 @@ -use std::io::{Cursor, ErrorKind, Read}; +use std::io::{Cursor, ErrorKind}; -use tokio::io::{AsyncRead, AsyncReadExt}; +use tokio::{io::AsyncReadExt, net::TcpStream}; use crate::inet::InetError; -use super::{decompress, packet::Packet, DataError}; +use super::{decompress, packet::Packet, DataError, Reader}; +impl AsyncReader for TcpStream { + async fn read_bytes(&mut self, size: usize) -> Result, DataError> { + let mut buf = vec![0; size]; + match AsyncReadExt::read_exact(self, &mut buf).await { + Ok(_) => Ok(buf), + Err(e) => match e.kind() { + ErrorKind::UnexpectedEof | ErrorKind::BrokenPipe | ErrorKind::ConnectionReset => { + Err(DataError::Inet(InetError::ConnectionClosed)) + } + _ => { + Err(DataError::ReadError) + }, + } + } + } +} + pub trait AsyncReader { async fn read_bytes(&mut self, size: usize) -> Result, DataError>; @@ -51,7 +68,7 @@ pub trait AsyncReader { data = self.read_bytes(packet_lenght).await?; } let mut cursor = Cursor::new(data); - let id = cursor.read_varint().await?; + let id = cursor.read_varint()?; Ok(Packet::new(id as u8, cursor)) } @@ -86,21 +103,4 @@ pub trait AsyncReader { self.read_bytes(16).await?.try_into().unwrap() )) } -} - -impl AsyncReader for R { - async fn read_bytes(&mut self, size: usize) -> Result, DataError> { - let mut buf = vec![0; size]; - match AsyncReadExt::read_exact(self, &mut buf).await { - Ok(_) => Ok(buf), - Err(e) => match e.kind() { - ErrorKind::UnexpectedEof | ErrorKind::BrokenPipe | ErrorKind::ConnectionReset => { - Err(DataError::Inet(InetError::ConnectionClosed)) - } - _ => { - Err(DataError::ReadError) - }, - } - } - } } \ No newline at end of file diff --git a/src/data/async_writer.rs b/src/data/async_writer.rs new file mode 100644 index 0000000..521a3d3 --- /dev/null +++ b/src/data/async_writer.rs @@ -0,0 +1,96 @@ +use std::io::Write; + +use tokio::{io::AsyncWriteExt, net::TcpStream}; + +use super::{compress, packet::Packet, DataError, Writer}; + + + +impl AsyncWriter for TcpStream { + async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> { + AsyncWriteExt::write_all(self, bytes).await.or(Err(DataError::WriteError)) + } +} + +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 { + 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) + -> Result<(), DataError> { + let mut buf = Vec::new(); + + let mut data_buf = Vec::new(); + data_buf.write_varint((packet.id() as u32) as i32)?; + data_buf.write_bytes(packet.get_bytes())?; + + if let Some(threshold) = threshold { + let mut packet_buf = Vec::new(); + + if data_buf.len() > threshold { + packet_buf.write_varint(data_buf.len() as i32)?; + let compressed_data = compress(&data_buf, 5)?; + Write::write_all(&mut packet_buf, &compressed_data).or(Err(DataError::WriteError))?; + } else { + packet_buf.write_varint(0)?; + packet_buf.write_bytes(&data_buf)?; + } + buf.write_varint(packet_buf.len() as i32)?; + buf.write_bytes(&packet_buf)?; + } else { + buf.write_varint(data_buf.len() as i32)?; + buf.write_bytes(&data_buf)?; + } + 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 + } +} \ No newline at end of file diff --git a/src/data/mod.rs b/src/data/mod.rs index f32c74c..8eeb329 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1,10 +1,12 @@ -use std::io::Read; +use std::io::{Read, Write}; use crate::inet::InetError; mod async_reader; mod reader; +mod async_writer; mod writer; + mod packet; mod packet_id; mod component; @@ -28,10 +30,17 @@ pub fn decompress(bytes: &[u8]) -> Result, DataError> { Ok(output) } +pub fn compress(bytes: &[u8], compression: u32) -> Result, DataError> { + let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(compression)); + encoder.write_all(bytes).or(Err(DataError::ZlibError))?; + encoder.finish().or(Err(DataError::ZlibError)) +} + pub use async_reader::*; pub use reader::*; -use flate2::bufread::ZlibDecoder; +pub use async_writer::*; pub use writer::*; +use flate2::{bufread::ZlibDecoder, write::ZlibEncoder, Compression}; pub use packet::*; pub use packet_id::{clientbound, serverbound}; pub use component::*; \ No newline at end of file diff --git a/src/data/packet.rs b/src/data/packet.rs index ad61fab..710162b 100644 --- a/src/data/packet.rs +++ b/src/data/packet.rs @@ -1,6 +1,6 @@ use std::io::Cursor; -use super::{DataError, async_reader::AsyncReader, writer::DataWriter}; +use super::{DataError, Reader, Writer}; #[derive(Debug, Clone)] pub struct Packet { @@ -84,14 +84,14 @@ impl From for Cursor> { } } -impl AsyncReader for Packet { - async fn read_bytes(&mut self, size: usize) -> Result, DataError> { - self.cursor.read_bytes(size).await +impl Reader for Packet { + fn read_bytes(&mut self, size: usize) -> Result, DataError> { + self.cursor.read_bytes(size) } } -impl DataWriter for Packet { - async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> { - self.cursor.write_bytes(bytes).await +impl Writer for Packet { + fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> { + self.cursor.write_bytes(bytes) } } diff --git a/src/data/reader.rs b/src/data/reader.rs index 5c3f110..352a82f 100644 --- a/src/data/reader.rs +++ b/src/data/reader.rs @@ -1,14 +1,9 @@ -use std::io::Read; +use std::io::{Cursor, Read}; -use super::DataError; +use super::{decompress, DataError, Packet}; - -pub trait Reader { - fn read_bytes(&mut self, size: usize) -> Result, DataError>; -} - impl Reader for R { fn read_bytes(&mut self, size: usize) -> Result, DataError> { let mut buf = vec![0; size]; @@ -17,4 +12,84 @@ impl Reader for R { Err(_) => Err(DataError::ReadError) } } +} + +pub trait Reader { + fn read_bytes(&mut self, size: usize) -> Result, DataError>; + + fn read_byte(&mut self) -> Result { + Ok(self.read_bytes(1)?[0]) + } + + fn read_signed_byte(&mut self) -> Result { + Ok(self.read_byte()? as i8) + } + + fn read_varint_size(&mut self) -> Result<(i32, usize), DataError> { + let mut value = 0; + let mut position = 0; + loop { + let byte = self.read_byte()?; + value |= ((byte & 0x7F) as i32) << (position * 7); + if (byte & 0x80) == 0 { + return Ok((value, position as usize)); + }; + position += 1; + if position >= 5 { + return Err(DataError::VarIntIsSoBig); + }; + } + } + + fn read_varint(&mut self) -> Result { + Ok(self.read_varint_size()?.0) + } + + fn read_packet(&mut self, threshold: Option) + -> Result { + let mut data: Vec; + let packet_lenght = self.read_varint()? as usize; + if threshold.is_some() { + let data_lenght = self.read_varint_size()?; + data = self.read_bytes(packet_lenght - data_lenght.1)?; + if data_lenght.0 != 0 { data = decompress(&data)?; } + } else { + data = self.read_bytes(packet_lenght)?; + } + let mut cursor = Cursor::new(data); + let id = cursor.read_varint()?; + Ok(Packet::new(id as u8, cursor)) + } + + fn read_short(&mut self) -> Result { + Ok(u16::from_be_bytes( + self.read_bytes(2)?.try_into().unwrap() + )) + } + + fn read_signed_short(&mut self) -> Result { + 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_long(&mut self) -> Result { + Ok(u64::from_be_bytes( + self.read_bytes(8)?.try_into().unwrap() + )) + } + + fn read_signed_long(&mut self) -> Result { + Ok(self.read_long()? as i64) + } + + fn read_uuid(&mut self) -> Result { + Ok(u128::from_be_bytes( + self.read_bytes(16)?.try_into().unwrap() + )) + } } \ No newline at end of file diff --git a/src/data/writer.rs b/src/data/writer.rs index 3c42793..3ea32ed 100644 --- a/src/data/writer.rs +++ b/src/data/writer.rs @@ -1,103 +1,94 @@ -use std::io::{Cursor, Seek, SeekFrom, Write}; +use std::io::Write; -use flate2::{write::ZlibEncoder, Compression}; -use tokio::io::{AsyncWrite, AsyncWriteExt}; - -use super::{packet::{self, Packet}, DataError}; +use super::{compress, DataError, Packet}; -pub fn compress(bytes: &[u8], compression: u32) -> Result, DataError> { - let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(compression)); - encoder.write_all(bytes).or(Err(DataError::ZlibError))?; - encoder.finish().or(Err(DataError::ZlibError)) +impl Writer for W { + fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> { + self.write_all(bytes).or(Err(DataError::WriteError)) + } } -pub trait DataWriter { - async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>; +pub trait Writer { + fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>; - async fn write_byte(&mut self, value: u8) -> Result<(), DataError> { - self.write_bytes(&[value]).await + fn write_byte(&mut self, value: u8) -> Result<(), DataError> { + self.write_bytes(&[value]) } - async fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> { - self.write_byte(value as u8).await + fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> { + self.write_byte(value as u8) } - async fn write_varint_size(&mut self, value: i32) -> Result { + fn write_varint_size(&mut self, value: i32) -> Result { 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?; + self.write_byte(byte)?; if _value == 0 { return Ok(position) } } } - async fn write_varint(&mut self, value: i32) -> Result<(), DataError> { - self.write_varint_size(value).await?; Ok(()) + fn write_varint(&mut self, value: i32) -> Result<(), DataError> { + self.write_varint_size(value)?; Ok(()) } - async fn write_packet(&mut self, packet: Packet, threshold: Option) + fn write_packet(&mut self, packet: Packet, threshold: Option) -> Result<(), DataError> { let mut buf = Vec::new(); let mut data_buf = Vec::new(); - data_buf.write_varint((packet.id() as u32) as i32).await?; - data_buf.write_bytes(packet.get_bytes()).await?; + data_buf.write_varint((packet.id() as u32) as i32)?; + data_buf.write_bytes(packet.get_bytes())?; if let Some(threshold) = threshold { let mut packet_buf = Vec::new(); if data_buf.len() > threshold { - packet_buf.write_varint(data_buf.len() as i32).await?; + packet_buf.write_varint(data_buf.len() as i32)?; let compressed_data = compress(&data_buf, 5)?; Write::write_all(&mut packet_buf, &compressed_data).or(Err(DataError::WriteError))?; } else { - packet_buf.write_varint(0).await?; - packet_buf.write_bytes(&data_buf).await?; + packet_buf.write_varint(0)?; + packet_buf.write_bytes(&data_buf)?; } - buf.write_varint(packet_buf.len() as i32).await?; - buf.write_bytes(&packet_buf).await?; + buf.write_varint(packet_buf.len() as i32)?; + buf.write_bytes(&packet_buf)?; } else { - buf.write_varint(data_buf.len() as i32).await?; - buf.write_bytes(&data_buf).await?; + buf.write_varint(data_buf.len() as i32)?; + buf.write_bytes(&data_buf)?; } - self.write_bytes(&buf).await?; + self.write_bytes(&buf)?; Ok(()) } - async fn write_short(&mut self, value: u16) -> Result<(), DataError> { - self.write_bytes(&value.to_be_bytes()).await + fn write_short(&mut self, value: u16) -> Result<(), DataError> { + self.write_bytes(&value.to_be_bytes()) } - async fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> { - self.write_short(value as u16).await + fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> { + self.write_short(value as u16) } - 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?; + fn write_string(&mut self, value: &str) -> Result<(), DataError> { + self.write_varint(value.len() as i32)?; + self.write_bytes(value.as_bytes())?; Ok(()) } - async fn write_long(&mut self, value: u64) -> Result<(), DataError> { - self.write_bytes(&value.to_be_bytes()).await + fn write_long(&mut self, value: u64) -> Result<(), DataError> { + self.write_bytes(&value.to_be_bytes()) } - async fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> { - self.write_long(value as u64).await + fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> { + self.write_long(value as u64) } - async fn write_uuid(&mut self, value: u128) -> Result<(), DataError> { - self.write_bytes(&value.to_be_bytes()).await - } -} - -impl DataWriter for W { - async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> { - AsyncWriteExt::write_all(self, bytes).await.or(Err(DataError::WriteError)) + fn write_uuid(&mut self, value: u128) -> Result<(), DataError> { + self.write_bytes(&value.to_be_bytes()) } } \ No newline at end of file