mirror of
https://github.com/GIKExe/rust_mc_serv.git
synced 2025-06-24 18:32:57 +03:00
Compare commits
No commits in common. "9a15eb92e51981f95e5573274e98c29c8f2cdbee" and "dfd6f56f76ef5c4ef0fc2d2af3e961da0212aee5" have entirely different histories.
9a15eb92e5
...
dfd6f56f76
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -178,6 +178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"libz-sys",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -285,6 +286,17 @@ version = "0.2.172"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libz-sys"
|
||||||
|
version = "1.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@ -386,6 +398,12 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powerfmt"
|
name = "powerfmt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -630,6 +648,12 @@ version = "1.0.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
@ -5,7 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = {version = "1.45.0", features = ["full"]}
|
tokio = {version = "1.45.0", features = ["full"]}
|
||||||
flate2 = {version = "1.1.1"}
|
flate2 = {version = "1.1.1", features = ["zlib"]}
|
||||||
serde = {version = "1.0.219", features = ["derive"]}
|
serde = {version = "1.0.219", features = ["derive"]}
|
||||||
serde_with = "3.12.0"
|
serde_with = "3.12.0"
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
|
60
src/cycle.rs
60
src/cycle.rs
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
use tokio::{net::TcpStream, time::Sleep};
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
use crate::data::{clientbound, serverbound, AsyncReader, AsyncWriter, DataError, Packet, Reader, TextComponentBuilder, Writer};
|
use crate::data::{clientbound, serverbound, DataError, AsyncReader, DataWriter, Packet, TextComponentBuilder};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -33,10 +33,10 @@ pub async fn main(mut stream: TcpStream) {
|
|||||||
async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> {
|
async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> {
|
||||||
let mut packet = stream.read_packet(None).await?;
|
let mut packet = stream.read_packet(None).await?;
|
||||||
if packet.id() != 0 { return Err(PacketError::WrongPacketID);}
|
if packet.id() != 0 { return Err(PacketError::WrongPacketID);}
|
||||||
let version = packet.read_varint()?;
|
let version = packet.read_varint().await?;
|
||||||
let host = packet.read_string()?;
|
let host = packet.read_string().await?;
|
||||||
let port = packet.read_short()?;
|
let port = packet.read_short().await?;
|
||||||
let ns = packet.read_varint()?;
|
let ns = packet.read_varint().await?;
|
||||||
|
|
||||||
if version != 770 {
|
if version != 770 {
|
||||||
let mut packet = Packet::empty(0x00);
|
let mut packet = Packet::empty(0x00);
|
||||||
@ -45,18 +45,15 @@ async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> {
|
|||||||
.text("Версия игры отличается от 1.21.5")
|
.text("Версия игры отличается от 1.21.5")
|
||||||
.color("red")
|
.color("red")
|
||||||
.build();
|
.build();
|
||||||
packet.write_string(&component.as_json()?)?;
|
packet.write_string(&component.as_json()?).await?;
|
||||||
return Ok(stream.write_packet(packet, None).await?);
|
return Ok(stream.write_packet(packet, None).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ns {
|
match ns {
|
||||||
1 => return the_status(stream).await,
|
1 => the_status(stream).await,
|
||||||
2 => the_login(stream, (version, host, port)).await?,
|
2 => the_login(stream, (version, host, port)).await,
|
||||||
_ => return Err(PacketError::NextStateIncorrect)
|
_ => Err(PacketError::NextStateIncorrect)
|
||||||
};
|
}
|
||||||
|
|
||||||
the_configuration(stream).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn the_status(stream: &mut TcpStream) -> Result<(), PacketError> {
|
async fn the_status(stream: &mut TcpStream) -> Result<(), PacketError> {
|
||||||
@ -73,13 +70,13 @@ async fn the_status(stream: &mut TcpStream) -> Result<(), PacketError> {
|
|||||||
\"online\": 1
|
\"online\": 1
|
||||||
}
|
}
|
||||||
}";
|
}";
|
||||||
p.write_string(status)?;
|
p.write_string(status).await?;
|
||||||
stream.write_packet(p, None).await?;
|
stream.write_packet(p, None).await?;
|
||||||
|
|
||||||
let mut packet = stream.read_packet(None).await?;
|
let mut packet = stream.read_packet(None).await?;
|
||||||
if packet.id() != 1 { return Err(PacketError::WrongPacketID); }
|
if packet.id() != 1 { return Err(PacketError::WrongPacketID); }
|
||||||
let mut p = Packet::empty(clientbound::status::PONG_RESPONSE);
|
let mut p = Packet::empty(clientbound::status::PONG_RESPONSE);
|
||||||
p.write_long(packet.read_long()?)?;
|
p.write_long(packet.read_long().await?).await?;
|
||||||
stream.write_packet(p, None).await?;
|
stream.write_packet(p, None).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -94,7 +91,7 @@ async fn the_login(stream: &mut TcpStream, data: (i32, String, u16)) -> Result<(
|
|||||||
.text("Версия игры отличается от 1.21.5")
|
.text("Версия игры отличается от 1.21.5")
|
||||||
.color("red")
|
.color("red")
|
||||||
.build();
|
.build();
|
||||||
packet.write_string(&component.as_json()?)?;
|
packet.write_string(&component.as_json()?).await?;
|
||||||
return Ok(stream.write_packet(packet, None).await?);
|
return Ok(stream.write_packet(packet, None).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,32 +109,15 @@ async fn the_login(stream: &mut TcpStream, data: (i32, String, u16)) -> Result<(
|
|||||||
|
|
||||||
let mut packet = stream.read_packet(None).await?;
|
let mut packet = stream.read_packet(None).await?;
|
||||||
if packet.id() != serverbound::login::START { return Err(PacketError::WrongPacketID); }
|
if packet.id() != serverbound::login::START { return Err(PacketError::WrongPacketID); }
|
||||||
let username = packet.read_string()?;
|
let username = packet.read_string().await?;
|
||||||
let uuid = packet.read_uuid()?;
|
let uuid = packet.read_uuid().await?;
|
||||||
|
|
||||||
// println!("Адрес клиента: {}", stream.peer_addr().unwrap());
|
println!("Адрес клиента: {:?}", stream.peer_addr());
|
||||||
// println!("Адрес сервера: {}:{}", data.1, data.2);
|
println!("Адрес сервера: {}:{}", data.1, data.2);
|
||||||
// println!("Username: {username}\nUUID: {:X}", uuid);
|
println!("Username: {username}\n UUID: {:X}", uuid);
|
||||||
|
|
||||||
let threshold = 512usize;
|
|
||||||
let mut packet = Packet::empty(clientbound::login::SET_COMPRESSION);
|
let mut packet = Packet::empty(clientbound::login::SET_COMPRESSION);
|
||||||
packet.write_varint(threshold as i32)?;
|
packet.write_varint(512).await?;
|
||||||
stream.write_packet(packet, None).await?;
|
|
||||||
|
|
||||||
let mut packet = Packet::empty(clientbound::login::SUCCESS);
|
|
||||||
packet.write_uuid(uuid)?;
|
|
||||||
packet.write_string(&username)?;
|
|
||||||
packet.write_varint(0)?;
|
|
||||||
stream.write_packet(packet, Some(threshold)).await?;
|
|
||||||
|
|
||||||
let packet = stream.read_packet(Some(threshold)).await?;
|
|
||||||
if packet.id() != serverbound::login::ACKNOWLEDGED { return Err(PacketError::WrongPacketID); }
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
|
||||||
|
|
||||||
async fn the_configuration(stream: &mut TcpStream) -> Result<(), PacketError> {
|
|
||||||
loop {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,30 +1,13 @@
|
|||||||
use std::io::{Cursor, ErrorKind};
|
use std::io::{Cursor, ErrorKind, Read};
|
||||||
|
|
||||||
use tokio::{io::AsyncReadExt, net::TcpStream};
|
use tokio::io::{AsyncRead, AsyncReadExt};
|
||||||
|
|
||||||
use crate::inet::InetError;
|
use crate::inet::InetError;
|
||||||
|
|
||||||
use super::{decompress, packet::Packet, DataError, Reader};
|
use super::{decompress, packet::Packet, DataError};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl AsyncReader for TcpStream {
|
|
||||||
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, 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 {
|
pub trait AsyncReader {
|
||||||
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
||||||
|
|
||||||
@ -68,7 +51,7 @@ pub trait AsyncReader {
|
|||||||
data = self.read_bytes(packet_lenght).await?;
|
data = self.read_bytes(packet_lenght).await?;
|
||||||
}
|
}
|
||||||
let mut cursor = Cursor::new(data);
|
let mut cursor = Cursor::new(data);
|
||||||
let id = cursor.read_varint()?;
|
let id = cursor.read_varint().await?;
|
||||||
Ok(Packet::new(id as u8, cursor))
|
Ok(Packet::new(id as u8, cursor))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,4 +86,21 @@ pub trait AsyncReader {
|
|||||||
self.read_bytes(16).await?.try_into().unwrap()
|
self.read_bytes(16).await?.try_into().unwrap()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: AsyncRead + Unpin> AsyncReader for R {
|
||||||
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, 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)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,96 +0,0 @@
|
|||||||
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<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();
|
|
||||||
|
|
||||||
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)?;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,10 @@
|
|||||||
use std::io::{Read, Write};
|
use std::io::Read;
|
||||||
|
|
||||||
use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression};
|
|
||||||
|
|
||||||
use crate::inet::InetError;
|
use crate::inet::InetError;
|
||||||
|
|
||||||
mod async_reader;
|
mod async_reader;
|
||||||
mod reader;
|
mod reader;
|
||||||
mod async_writer;
|
|
||||||
mod writer;
|
mod writer;
|
||||||
|
|
||||||
mod packet;
|
mod packet;
|
||||||
mod packet_id;
|
mod packet_id;
|
||||||
mod component;
|
mod component;
|
||||||
@ -32,15 +28,9 @@ pub fn decompress(bytes: &[u8]) -> Result<Vec<u8>, DataError> {
|
|||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compress(bytes: &[u8]) -> Result<Vec<u8>, DataError> {
|
|
||||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(1));
|
|
||||||
encoder.write_all(bytes).or(Err(DataError::ZlibError))?;
|
|
||||||
encoder.finish().or(Err(DataError::ZlibError))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use async_reader::*;
|
pub use async_reader::*;
|
||||||
pub use reader::*;
|
pub use reader::*;
|
||||||
pub use async_writer::*;
|
use flate2::bufread::ZlibDecoder;
|
||||||
pub use writer::*;
|
pub use writer::*;
|
||||||
pub use packet::*;
|
pub use packet::*;
|
||||||
pub use packet_id::{clientbound, serverbound};
|
pub use packet_id::{clientbound, serverbound};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use super::{DataError, Reader, Writer};
|
use super::{DataError, async_reader::AsyncReader, writer::DataWriter};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Packet {
|
pub struct Packet {
|
||||||
@ -84,14 +84,14 @@ impl From<Packet> for Cursor<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reader for Packet {
|
impl AsyncReader for Packet {
|
||||||
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
self.cursor.read_bytes(size)
|
self.cursor.read_bytes(size).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Writer for Packet {
|
impl DataWriter for Packet {
|
||||||
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
||||||
self.cursor.write_bytes(bytes)
|
self.cursor.write_bytes(bytes).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
use std::io::{Cursor, Read};
|
use std::io::Read;
|
||||||
|
|
||||||
use super::{decompress, DataError, Packet};
|
use super::DataError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub trait Reader {
|
||||||
|
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<R: Read> Reader for R {
|
impl<R: Read> Reader for R {
|
||||||
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
let mut buf = vec![0; size];
|
let mut buf = vec![0; size];
|
||||||
@ -12,84 +17,4 @@ impl<R: Read> Reader for R {
|
|||||||
Err(_) => Err(DataError::ReadError)
|
Err(_) => Err(DataError::ReadError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Reader {
|
|
||||||
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
|
||||||
|
|
||||||
fn read_byte(&mut self) -> Result<u8, DataError> {
|
|
||||||
Ok(self.read_bytes(1)?[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_signed_byte(&mut self) -> Result<i8, DataError> {
|
|
||||||
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<i32, DataError> {
|
|
||||||
Ok(self.read_varint_size()?.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_packet(&mut self, threshold: Option<usize>)
|
|
||||||
-> Result<Packet, DataError> {
|
|
||||||
let mut data: Vec<u8>;
|
|
||||||
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<u16, DataError> {
|
|
||||||
Ok(u16::from_be_bytes(
|
|
||||||
self.read_bytes(2)?.try_into().unwrap()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_signed_short(&mut self) -> Result<i16, DataError> {
|
|
||||||
Ok(self.read_short()? as i16)
|
|
||||||
}
|
|
||||||
|
|
||||||
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> {
|
|
||||||
Ok(u64::from_be_bytes(
|
|
||||||
self.read_bytes(8)?.try_into().unwrap()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_signed_long(&mut self) -> Result<i64, DataError> {
|
|
||||||
Ok(self.read_long()? as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_uuid(&mut self) -> Result<u128, DataError> {
|
|
||||||
Ok(u128::from_be_bytes(
|
|
||||||
self.read_bytes(16)?.try_into().unwrap()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,94 +1,103 @@
|
|||||||
use std::io::Write;
|
use std::io::{Cursor, Seek, SeekFrom, Write};
|
||||||
|
|
||||||
use super::{compress, DataError, Packet};
|
use flate2::{write::ZlibEncoder, Compression};
|
||||||
|
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
||||||
|
|
||||||
|
use super::{packet::{self, Packet}, DataError};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl<W: Write> Writer for W {
|
pub fn compress(bytes: &[u8], compression: u32) -> Result<Vec<u8>, DataError> {
|
||||||
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(compression));
|
||||||
self.write_all(bytes).or(Err(DataError::WriteError))
|
encoder.write_all(bytes).or(Err(DataError::ZlibError))?;
|
||||||
}
|
encoder.finish().or(Err(DataError::ZlibError))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Writer {
|
pub trait DataWriter {
|
||||||
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>;
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>;
|
||||||
|
|
||||||
fn write_byte(&mut self, value: u8) -> Result<(), DataError> {
|
async fn write_byte(&mut self, value: u8) -> Result<(), DataError> {
|
||||||
self.write_bytes(&[value])
|
self.write_bytes(&[value]).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> {
|
async fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> {
|
||||||
self.write_byte(value as u8)
|
self.write_byte(value as u8).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_varint_size(&mut self, value: i32) -> Result<usize, DataError> {
|
async fn write_varint_size(&mut self, value: i32) -> Result<usize, DataError> {
|
||||||
let mut _value = value as u32;
|
let mut _value = value as u32;
|
||||||
let mut position = 0;
|
let mut position = 0;
|
||||||
loop {
|
loop {
|
||||||
let mut byte = (_value & 127) as u8;
|
let mut byte = (_value & 127) as u8;
|
||||||
position += 1; _value >>= 7;
|
position += 1; _value >>= 7;
|
||||||
if _value != 0 { byte += 128; };
|
if _value != 0 { byte += 128; };
|
||||||
self.write_byte(byte)?;
|
self.write_byte(byte).await?;
|
||||||
if _value == 0 { return Ok(position) }
|
if _value == 0 { return Ok(position) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_varint(&mut self, value: i32) -> Result<(), DataError> {
|
async fn write_varint(&mut self, value: i32) -> Result<(), DataError> {
|
||||||
self.write_varint_size(value)?; Ok(())
|
self.write_varint_size(value).await?; Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_packet(&mut self, packet: Packet, threshold: Option<usize>)
|
async fn write_packet(&mut self, packet: Packet, threshold: Option<usize>)
|
||||||
-> Result<(), DataError> {
|
-> Result<(), DataError> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
let mut data_buf = Vec::new();
|
let mut data_buf = Vec::new();
|
||||||
data_buf.write_varint((packet.id() as u32) as i32)?;
|
data_buf.write_varint((packet.id() as u32) as i32).await?;
|
||||||
data_buf.write_bytes(packet.get_bytes())?;
|
data_buf.write_bytes(packet.get_bytes()).await?;
|
||||||
|
|
||||||
if let Some(threshold) = threshold {
|
if let Some(threshold) = threshold {
|
||||||
let mut packet_buf = Vec::new();
|
let mut packet_buf = Vec::new();
|
||||||
|
|
||||||
if data_buf.len() > threshold {
|
if data_buf.len() > threshold {
|
||||||
packet_buf.write_varint(data_buf.len() as i32)?;
|
packet_buf.write_varint(data_buf.len() as i32).await?;
|
||||||
let compressed_data = compress(&data_buf)?;
|
let compressed_data = compress(&data_buf, 5)?;
|
||||||
Write::write_all(&mut packet_buf, &compressed_data).or(Err(DataError::WriteError))?;
|
Write::write_all(&mut packet_buf, &compressed_data).or(Err(DataError::WriteError))?;
|
||||||
} else {
|
} else {
|
||||||
packet_buf.write_varint(0)?;
|
packet_buf.write_varint(0).await?;
|
||||||
packet_buf.write_bytes(&data_buf)?;
|
packet_buf.write_bytes(&data_buf).await?;
|
||||||
}
|
}
|
||||||
buf.write_varint(packet_buf.len() as i32)?;
|
buf.write_varint(packet_buf.len() as i32).await?;
|
||||||
buf.write_bytes(&packet_buf)?;
|
buf.write_bytes(&packet_buf).await?;
|
||||||
} else {
|
} else {
|
||||||
buf.write_varint(data_buf.len() as i32)?;
|
buf.write_varint(data_buf.len() as i32).await?;
|
||||||
buf.write_bytes(&data_buf)?;
|
buf.write_bytes(&data_buf).await?;
|
||||||
}
|
}
|
||||||
self.write_bytes(&buf)?;
|
self.write_bytes(&buf).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_short(&mut self, value: u16) -> Result<(), DataError> {
|
async fn write_short(&mut self, value: u16) -> Result<(), DataError> {
|
||||||
self.write_bytes(&value.to_be_bytes())
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> {
|
async fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> {
|
||||||
self.write_short(value as u16)
|
self.write_short(value as u16).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_string(&mut self, value: &str) -> Result<(), DataError> {
|
async fn write_string(&mut self, value: &str) -> Result<(), DataError> {
|
||||||
self.write_varint(value.len() as i32)?;
|
self.write_varint(value.len() as i32).await?;
|
||||||
self.write_bytes(value.as_bytes())?;
|
self.write_bytes(value.as_bytes()).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_long(&mut self, value: u64) -> Result<(), DataError> {
|
async fn write_long(&mut self, value: u64) -> Result<(), DataError> {
|
||||||
self.write_bytes(&value.to_be_bytes())
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> {
|
async fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> {
|
||||||
self.write_long(value as u64)
|
self.write_long(value as u64).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_uuid(&mut self, value: u128) -> Result<(), DataError> {
|
async fn write_uuid(&mut self, value: u128) -> Result<(), DataError> {
|
||||||
self.write_bytes(&value.to_be_bytes())
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: AsyncWrite + Unpin> DataWriter for W {
|
||||||
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
||||||
|
AsyncWriteExt::write_all(self, bytes).await.or(Err(DataError::WriteError))
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user