mirror of
https://github.com/GIKExe/rust_mc_serv.git
synced 2025-06-24 10:22:57 +03:00
?
This commit is contained in:
parent
8f189d6531
commit
8f07ea37e7
@ -4,4 +4,8 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# async-trait = {version = "0.1.88", optional = true}
|
||||||
tokio = {version = "1.45.0", features = ["full"]}
|
tokio = {version = "1.45.0", features = ["full"]}
|
||||||
|
|
||||||
|
# [features]
|
||||||
|
# async = ["async-trait"]
|
154
src/data.rs
154
src/data.rs
@ -1,12 +1,10 @@
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
|
|
||||||
use tokio::io::{AsyncRead, AsyncReadExt};
|
use tokio::io::{AsyncRead, AsyncReadExt};
|
||||||
|
|
||||||
use crate::inet::InetError;
|
use crate::inet::InetError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
|
||||||
|
|
||||||
pub enum DataError {
|
pub enum DataError {
|
||||||
ReadError,
|
ReadError,
|
||||||
WriteError,
|
WriteError,
|
||||||
@ -15,37 +13,65 @@ pub enum DataError {
|
|||||||
Inet(InetError),
|
Inet(InetError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReadLike {
|
pub trait DataReader {
|
||||||
type Output;
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
||||||
fn _read_bytes(self, size: usize) -> Self::Output;
|
|
||||||
|
async fn read_byte(&mut self) -> Result<u8, DataError> {
|
||||||
|
Ok(self.read_bytes(1).await?[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <R: Read> ReadLike for &mut R {
|
async fn read_signed_byte(&mut self) -> Result<i8, DataError> {
|
||||||
type Output = Result<Vec<u8>, DataError>;
|
Ok(self.read_byte().await? as i8)
|
||||||
|
}
|
||||||
|
|
||||||
fn _read_bytes(self, size: usize) -> Self::Output {
|
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_varint_size(&mut self) -> Result<(i32, usize), DataError> {
|
||||||
|
let mut value = 0;
|
||||||
|
let mut position = 0;
|
||||||
|
loop {
|
||||||
|
let byte = self.read_byte().await?;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_varint(&mut self) -> Result<i32, DataError> {
|
||||||
|
Ok(self.read_varint_size().await?.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// async fn read_packet(&mut self, threshold: Option<usize>) -> Result<Cursor<Vec<u8>>, DataError> {
|
||||||
|
// let size = self.read_varint().await?;
|
||||||
|
// let mut buf = self.read_bytes(size).await?;
|
||||||
|
// }
|
||||||
|
|
||||||
|
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).map_err(|_| DataError::StringDecodeError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: AsyncRead + Unpin> DataReader for R {
|
||||||
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
let mut buf = vec![0; size];
|
let mut buf = vec![0; size];
|
||||||
let mut read = 0;
|
let mut read = 0;
|
||||||
while read < size {
|
while read < size {
|
||||||
match self.read(&mut buf[read..]) {
|
match AsyncReadExt::read(self, &mut buf[read..]).await {
|
||||||
Ok(0) => return Err(DataError::Inet(InetError::ConnectionClosed)),
|
|
||||||
Ok(n) => read+=n,
|
|
||||||
Err(_) => return Err(DataError::ReadError)
|
|
||||||
}
|
|
||||||
}; Ok(buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
|
||||||
#[async_trait]
|
|
||||||
impl <R: AsyncRead + Unpin + Send> ReadLike for &mut R {
|
|
||||||
type Output = Result<Vec<u8>, DataError>;
|
|
||||||
|
|
||||||
async fn _read_bytes(self, size: usize) -> Self::Output {
|
|
||||||
let mut buf = vec![0; size];
|
|
||||||
let mut read = 0;
|
|
||||||
while read < size {
|
|
||||||
match AsyncReadExt::read(&mut self, &mut buf[read..]).await {
|
|
||||||
Ok(0) => return Err(DataError::Inet(InetError::ConnectionClosed)),
|
Ok(0) => return Err(DataError::Inet(InetError::ConnectionClosed)),
|
||||||
Ok(n) => read += n,
|
Ok(n) => read += n,
|
||||||
Err(_) => return Err(DataError::ReadError),
|
Err(_) => return Err(DataError::ReadError),
|
||||||
@ -54,73 +80,3 @@ impl <R: AsyncRead + Unpin + Send> ReadLike for &mut R {
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "async", async_trait)]
|
|
||||||
pub trait DataReader {
|
|
||||||
#[cfg(not(feature = "async"))]
|
|
||||||
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
|
||||||
async 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_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_varint(&mut self) -> Result<i32, DataError> {
|
|
||||||
let mut value = 0;
|
|
||||||
let mut position = 0;
|
|
||||||
loop {
|
|
||||||
let byte = self.read_byte()?;
|
|
||||||
value |= ((byte & 0x7F) << position) as i32;
|
|
||||||
if (byte & 0x80) == 0 {return Ok(value)};
|
|
||||||
position += 7;
|
|
||||||
if position >= 32 {return Err(DataError::VarIntIsSoBig)};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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).map_err(|_| DataError::StringDecodeError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <R: Read> DataReader for R {
|
|
||||||
#[cfg(not(feature = "async"))]
|
|
||||||
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
|
||||||
self._read_bytes(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
|
||||||
#[async_trait]
|
|
||||||
impl<R: AsyncRead + Unpin + Send> DataReader for R {
|
|
||||||
async fn _read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
|
||||||
self.read_bytes(size).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub trait DataWriter {
|
|
||||||
fn write_bytes(&mut self, buf: Vec<u8>) -> Result<(), DataError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <W: Write> DataWriter for W {
|
|
||||||
fn write_bytes(&mut self, buf: Vec<u8>) -> Result<(), DataError> {
|
|
||||||
self.write_all(&buf).map_err(|_| DataError::WriteError)
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ use tokio::net::{TcpListener, TcpStream};
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum InetError {
|
pub enum InetError {
|
||||||
BindError,
|
BindError,
|
||||||
ConnectionClosed
|
ConnectionClosed
|
||||||
|
42
src/main.rs
42
src/main.rs
@ -1,20 +1,18 @@
|
|||||||
use std::{io::Cursor, sync::Arc, time::Duration};
|
|
||||||
|
use std::{io::Cursor, net::Shutdown};
|
||||||
|
|
||||||
use data::{DataError, DataReader};
|
use data::{DataError, DataReader};
|
||||||
use inet::Server;
|
use inet::Server;
|
||||||
use tokio::{io::AsyncReadExt, net::TcpStream, time::sleep};
|
use tokio::{io::AsyncWriteExt, net::TcpStream};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mod inet;
|
|
||||||
mod data;
|
mod data;
|
||||||
|
mod inet;
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let Ok(server) = Server::new("127.0.0.1:25565").await else {
|
let Ok(server) = Server::new("127.0.0.1:25565").await else {
|
||||||
println!("Не удалось забиндить сервер"); return;
|
println!("Не удалось забиндить сервер");
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -23,10 +21,30 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test(stream: TcpStream) {
|
async fn test(mut stream: TcpStream) {
|
||||||
let Ok(addr) = stream.peer_addr() else {return;};
|
let Ok(addr) = stream.peer_addr() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
println!("Подключение: {addr}");
|
println!("Подключение: {addr}");
|
||||||
// читаем первый пакет
|
// читаем первый пакет
|
||||||
let size = stream.read_varint();
|
match read_first_packet(&mut stream).await {
|
||||||
println!("Отключение: {addr}");
|
Ok(_) => {}, Err(e) => println!("Ошибка во время обработки пакета: {e:?}")
|
||||||
|
}
|
||||||
|
println!("Отключение: {addr}");
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_first_packet(stream: &mut TcpStream) -> Result<(), DataError> {
|
||||||
|
let size = stream.read_varint().await?;
|
||||||
|
let mut buf = Cursor::new(stream.read_bytes(size as usize).await?);
|
||||||
|
let id = buf.read_varint().await?;
|
||||||
|
let version = buf.read_varint().await?;
|
||||||
|
let host = buf.read_string().await?;
|
||||||
|
let port = buf.read_short().await?;
|
||||||
|
let ns = buf.read_varint().await?;
|
||||||
|
println!("Айди пакета: {id}");
|
||||||
|
println!("Версия протокола: {version}");
|
||||||
|
println!("Адрес сервера: {host}:{port}");
|
||||||
|
println!("Следующее состояние: {ns}");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user