move write_packet and read_packet to methods

This commit is contained in:
MeexReay 2025-05-03 03:56:34 +03:00
parent 689d769baa
commit fbcb1ce123
4 changed files with 74 additions and 84 deletions

View File

@ -17,56 +17,6 @@ macro_rules! generate_handlers {
}; };
} }
/// Отправляет пакет клиенту и проходит по пакет ханлдерам
/// Пример использования:
///
/// write_packet!(client, Handshake, packet);
///
/// `Handshake` это режим подключения (типы ConnectionState)
#[macro_export]
macro_rules! write_packet {
($client:expr, $state:ident, $packet:expr) => {
{
let mut packet = $packet;
let mut cancelled = false;
for handler in $client.server.packet_handlers(
|o| o.on_outcoming_packet_priority()
).iter() {
handler.on_outcoming_packet($client.clone(), &mut packet, &mut cancelled, crate::server::protocol::ConnectionState::$state)?;
packet.get_mut().set_position(0);
}
if !cancelled {
$client.conn().write_packet(&packet)?;
}
}
};
}
/// Читает пакет от клиента и проходит по пакет ханлдерам
/// Пример использования:
///
/// let packet = read_packet!(client, Handshake);
///
/// `Handshake` это режим подключения (типы ConnectionState)
#[macro_export]
macro_rules! read_packet {
($client:expr, $state:ident) => {
loop {
let mut packet = $client.conn().read_packet()?;
let mut cancelled = false;
for handler in $client.server.packet_handlers(
|o| o.on_incoming_packet_priority()
).iter() {
handler.on_incoming_packet($client.clone(), &mut packet, &mut cancelled, crate::server::protocol::ConnectionState::$state)?;
packet.get_mut().set_position(0);
}
if !cancelled {
break packet;
}
}
};
}
/// Пример использования: /// Пример использования:
/// ///
/// trigger_event!(client, status, &mut response, state); /// trigger_event!(client, status, &mut response, state);

View File

@ -1,6 +1,6 @@
use std::{hash::Hash, net::{SocketAddr, TcpStream}, sync::{Arc, RwLock, RwLockWriteGuard}}; use std::{hash::Hash, net::{SocketAddr, TcpStream}, sync::{Arc, RwLock}};
use rust_mc_proto::MinecraftConnection; use rust_mc_proto::{MinecraftConnection, Packet};
use uuid::Uuid; use uuid::Uuid;
use crate::server::{context::ServerContext, protocol::ConnectionState, ServerError}; use crate::server::{context::ServerContext, protocol::ConnectionState, ServerError};
@ -91,8 +91,48 @@ impl ClientContext {
self.state.read().unwrap().clone() self.state.read().unwrap().clone()
} }
pub fn conn(self: &Arc<Self>) -> RwLockWriteGuard<'_, MinecraftConnection<TcpStream>> { pub fn write_packet(self: &Arc<Self>, packet: &Packet) -> Result<(), ServerError> {
self.conn.write().unwrap() let state = self.state();
let mut packet = packet.clone();
let mut cancelled = false;
for handler in self.server.packet_handlers(
|o| o.on_outcoming_packet_priority()
).iter() {
handler.on_outcoming_packet(self.clone(), &mut packet, &mut cancelled, state.clone())?;
packet.get_mut().set_position(0);
}
if !cancelled {
self.conn.write().unwrap().write_packet(&packet)?;
}
Ok(())
}
pub fn read_packet(self: &Arc<Self>) -> Result<Packet, ServerError> {
let state = self.state();
let mut conn = self.conn.read().unwrap().try_clone()?; // так можно делать т.к сокет это просто поинтер
loop {
let mut packet = conn.read_packet()?;
let mut cancelled = false;
for handler in self.server.packet_handlers(
|o| o.on_incoming_packet_priority()
).iter() {
handler.on_incoming_packet(self.clone(), &mut packet, &mut cancelled, state.clone())?;
packet.get_mut().set_position(0);
}
if !cancelled {
break Ok(packet);
}
}
}
pub fn close(self: &Arc<Self>) {
self.conn.write().unwrap().close();
}
pub fn set_compression(self: &Arc<Self>, threshold: Option<usize>) {
self.conn.write().unwrap().set_compression(threshold);
} }
pub fn protocol_helper(self: &Arc<Self>) -> ProtocolHelper { pub fn protocol_helper(self: &Arc<Self>) -> ProtocolHelper {

View File

@ -31,8 +31,8 @@ impl ProtocolHelper {
pub fn leave_configuration(&self) -> Result<(), ServerError> { pub fn leave_configuration(&self) -> Result<(), ServerError> {
match self.state { match self.state {
ConnectionState::Configuration => { ConnectionState::Configuration => {
self.client.conn().write_packet(&Packet::empty(0x03))?; self.client.write_packet(&Packet::empty(0x03))?;
self.client.conn().read_packet()?; self.client.read_packet()?;
self.client.set_state(ConnectionState::Play)?; self.client.set_state(ConnectionState::Play)?;
Ok(()) Ok(())
}, },
@ -44,8 +44,8 @@ impl ProtocolHelper {
pub fn enter_configuration(&self) -> Result<(), ServerError> { pub fn enter_configuration(&self) -> Result<(), ServerError> {
match self.state { match self.state {
ConnectionState::Play => { ConnectionState::Play => {
self.client.conn().write_packet(&Packet::empty(0x6F))?; self.client.write_packet(&Packet::empty(0x6F))?;
self.client.conn().read_packet()?; self.client.read_packet()?;
self.client.set_state(ConnectionState::Configuration)?; self.client.set_state(ConnectionState::Configuration)?;
Ok(()) Ok(())
}, },
@ -58,14 +58,14 @@ impl ProtocolHelper {
match self.state { match self.state {
ConnectionState::Play => { ConnectionState::Play => {
let time = SystemTime::now(); let time = SystemTime::now();
self.client.conn().write_packet(&Packet::empty(0x36))?; self.client.write_packet(&Packet::empty(0x36))?;
self.client.conn().read_packet()?; self.client.read_packet()?;
Ok(SystemTime::now().duration_since(time).unwrap()) Ok(SystemTime::now().duration_since(time).unwrap())
}, },
ConnectionState::Configuration => { ConnectionState::Configuration => {
let time = SystemTime::now(); let time = SystemTime::now();
self.client.conn().write_packet(&Packet::empty(0x05))?; self.client.write_packet(&Packet::empty(0x05))?;
self.client.conn().read_packet()?; self.client.read_packet()?;
Ok(SystemTime::now().duration_since(time).unwrap()) Ok(SystemTime::now().duration_since(time).unwrap())
}, },
_ => Err(ServerError::UnexpectedState) _ => Err(ServerError::UnexpectedState)
@ -89,11 +89,11 @@ impl ProtocolHelper {
packet packet
}, },
_ => { _ => {
self.client.conn().close(); self.client.close();
return Ok(()) return Ok(())
}, },
}; };
self.client.conn().write_packet(&packet)?; self.client.write_packet(&packet)?;
Ok(()) Ok(())
} }
@ -103,9 +103,9 @@ impl ProtocolHelper {
ConnectionState::Configuration => { ConnectionState::Configuration => {
let mut packet = Packet::empty(0x00); let mut packet = Packet::empty(0x00);
packet.write_string(id)?; packet.write_string(id)?;
self.client.conn().write_packet(&packet)?; self.client.write_packet(&packet)?;
let mut packet = self.client.conn().read_packet()?; let mut packet = self.client.read_packet()?;
packet.read_string()?; packet.read_string()?;
let data = if packet.read_boolean()? { let data = if packet.read_boolean()? {
let n = packet.read_usize_varint()?; let n = packet.read_usize_varint()?;
@ -128,9 +128,9 @@ impl ProtocolHelper {
packet.write_varint(id)?; packet.write_varint(id)?;
packet.write_string(channel)?; packet.write_string(channel)?;
packet.write_bytes(data)?; packet.write_bytes(data)?;
self.client.conn().write_packet(&packet)?; self.client.write_packet(&packet)?;
let mut packet = self.client.conn().read_packet()?; let mut packet = self.client.read_packet()?;
let identifier = packet.read_varint()?; let identifier = packet.read_varint()?;
let data = if packet.read_boolean()? { let data = if packet.read_boolean()? {
let mut data = Vec::new(); let mut data = Vec::new();
@ -154,7 +154,7 @@ impl ProtocolHelper {
}; };
packet.write_string(channel)?; packet.write_string(channel)?;
packet.write_bytes(data)?; packet.write_bytes(data)?;
self.client.conn().write_packet(&packet)?; self.client.write_packet(&packet)?;
Ok(()) Ok(())
} }
} }

View File

@ -3,7 +3,7 @@ use std::{io::Read, sync::Arc};
use super::{player::context::{ClientContext, ClientInfo, Handshake, PlayerInfo}, ServerError}; use super::{player::context::{ClientContext, ClientInfo, Handshake, PlayerInfo}, ServerError};
use rust_mc_proto::{DataReader, DataWriter, Packet}; use rust_mc_proto::{DataReader, DataWriter, Packet};
use crate::{read_packet, server::data::text_component::TextComponent, trigger_event, write_packet}; use crate::{server::data::text_component::TextComponent, trigger_event};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ConnectionState { pub enum ConnectionState {
@ -21,7 +21,7 @@ pub fn handle_connection(
// Получение пакетов производится через client.conn(), // Получение пакетов производится через client.conn(),
// ВАЖНО: не помещать сам client.conn() в переменные, // ВАЖНО: не помещать сам client.conn() в переменные,
// он должен сразу убиваться иначе соединение гдето задедлочится // он должен сразу убиваться иначе соединение гдето задедлочится
let mut packet = read_packet!(client, Handshake); let mut packet = client.read_packet()?;
if packet.id() != 0x00 { if packet.id() != 0x00 {
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет рукопожатия"))); return Err(ServerError::UnknownPacket(format!("Неизвестный пакет рукопожатия")));
@ -40,7 +40,7 @@ pub fn handle_connection(
loop { loop {
// Чтение запроса // Чтение запроса
let packet = read_packet!(client, Status); let packet = client.read_packet()?;
match packet.id() { match packet.id() {
0x00 => { // Запрос статуса 0x00 => { // Запрос статуса
@ -61,10 +61,10 @@ pub fn handle_connection(
// Отправка статуса // Отправка статуса
packet.write_string(&status)?; packet.write_string(&status)?;
write_packet!(client, Status, packet); client.write_packet(&packet)?;
}, },
0x01 => { // Пинг 0x01 => { // Пинг
write_packet!(client, Status, packet); client.write_packet(&packet)?;
// Просто отправляем этот же пакет обратно // Просто отправляем этот же пакет обратно
// ID такой-же, содержание тоже, так почему бы и нет? // ID такой-же, содержание тоже, так почему бы и нет?
}, },
@ -78,7 +78,7 @@ pub fn handle_connection(
client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login
// Читаем пакет Login Start // Читаем пакет Login Start
let mut packet = read_packet!(client, Login); let mut packet = client.read_packet()?;
let name = packet.read_string()?; let name = packet.read_string()?;
let uuid = packet.read_uuid()?; let uuid = packet.read_uuid()?;
@ -91,18 +91,18 @@ pub fn handle_connection(
// Отправляем пакет Set Compression если сжатие указано // Отправляем пакет Set Compression если сжатие указано
if let Some(threshold) = client.server.config.server.compression_threshold { if let Some(threshold) = client.server.config.server.compression_threshold {
write_packet!(client, Login, Packet::build(0x03, |p| p.write_usize_varint(threshold))?); client.write_packet(&Packet::build(0x03, |p| p.write_usize_varint(threshold))?)?;
client.conn().set_compression(Some(threshold)); // Устанавливаем сжатие на соединении client.set_compression(Some(threshold)); // Устанавливаем сжатие на соединении
} }
// Отправка пакета Login Success // Отправка пакета Login Success
write_packet!(client, Login, Packet::build(0x02, |p| { client.write_packet(&Packet::build(0x02, |p| {
p.write_uuid(&uuid)?; p.write_uuid(&uuid)?;
p.write_string(&name)?; p.write_string(&name)?;
p.write_varint(0) p.write_varint(0)
})?); })?)?;
let packet = read_packet!(client, Login); let packet = client.read_packet()?;
if packet.id() != 0x03 { if packet.id() != 0x03 {
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Login Acknowledged"))); return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Login Acknowledged")));
@ -113,7 +113,7 @@ pub fn handle_connection(
// Получение бренда клиента из Serverbound Plugin Message // Получение бренда клиента из Serverbound Plugin Message
// Identifier канала откуда берется бренд: minecraft:brand // Identifier канала откуда берется бренд: minecraft:brand
let brand = loop { let brand = loop {
let mut packet = read_packet!(client, Configuration); let mut packet = client.read_packet()?;
if packet.id() == 0x02 { // Пакет Serverbound Plugin Message if packet.id() == 0x02 { // Пакет Serverbound Plugin Message
let identifier = packet.read_string()?; let identifier = packet.read_string()?;
@ -131,7 +131,7 @@ pub fn handle_connection(
}; };
}; };
let mut packet = read_packet!(client, Configuration); let mut packet = client.read_packet()?;
// Пакет Client Information // Пакет Client Information
if packet.id() != 0x00 { if packet.id() != 0x00 {
@ -163,9 +163,9 @@ pub fn handle_connection(
// TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото // TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото
write_packet!(client, Configuration, Packet::empty(0x03)); client.write_packet(&Packet::empty(0x03))?;
let packet = read_packet!(client, Configuration); let packet = client.read_packet()?;
if packet.id() != 0x03 { if packet.id() != 0x03 {
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Acknowledge Finish Configuration"))); return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Acknowledge Finish Configuration")));