diff --git a/src/server/event/mod.rs b/src/server/event/mod.rs index b7fb86b..1477b8e 100644 --- a/src/server/event/mod.rs +++ b/src/server/event/mod.rs @@ -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); diff --git a/src/server/player/context.rs b/src/server/player/context.rs index ce0f5a7..b72c4ce 100644 --- a/src/server/player/context.rs +++ b/src/server/player/context.rs @@ -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 crate::server::{context::ServerContext, protocol::ConnectionState, ServerError}; @@ -91,8 +91,48 @@ impl ClientContext { self.state.read().unwrap().clone() } - pub fn conn(self: &Arc) -> RwLockWriteGuard<'_, MinecraftConnection> { - self.conn.write().unwrap() + pub fn write_packet(self: &Arc, packet: &Packet) -> Result<(), ServerError> { + 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) -> Result { + 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.conn.write().unwrap().close(); + } + + pub fn set_compression(self: &Arc, threshold: Option) { + self.conn.write().unwrap().set_compression(threshold); } pub fn protocol_helper(self: &Arc) -> ProtocolHelper { diff --git a/src/server/player/protocol.rs b/src/server/player/protocol.rs index e4efb2a..1fdfcf1 100644 --- a/src/server/player/protocol.rs +++ b/src/server/player/protocol.rs @@ -31,8 +31,8 @@ impl ProtocolHelper { pub fn leave_configuration(&self) -> Result<(), ServerError> { match self.state { ConnectionState::Configuration => { - self.client.conn().write_packet(&Packet::empty(0x03))?; - self.client.conn().read_packet()?; + self.client.write_packet(&Packet::empty(0x03))?; + self.client.read_packet()?; self.client.set_state(ConnectionState::Play)?; Ok(()) }, @@ -44,8 +44,8 @@ impl ProtocolHelper { pub fn enter_configuration(&self) -> Result<(), ServerError> { match self.state { ConnectionState::Play => { - self.client.conn().write_packet(&Packet::empty(0x6F))?; - self.client.conn().read_packet()?; + self.client.write_packet(&Packet::empty(0x6F))?; + self.client.read_packet()?; self.client.set_state(ConnectionState::Configuration)?; Ok(()) }, @@ -58,14 +58,14 @@ impl ProtocolHelper { match self.state { ConnectionState::Play => { let time = SystemTime::now(); - self.client.conn().write_packet(&Packet::empty(0x36))?; - self.client.conn().read_packet()?; + self.client.write_packet(&Packet::empty(0x36))?; + self.client.read_packet()?; Ok(SystemTime::now().duration_since(time).unwrap()) }, ConnectionState::Configuration => { let time = SystemTime::now(); - self.client.conn().write_packet(&Packet::empty(0x05))?; - self.client.conn().read_packet()?; + self.client.write_packet(&Packet::empty(0x05))?; + self.client.read_packet()?; Ok(SystemTime::now().duration_since(time).unwrap()) }, _ => Err(ServerError::UnexpectedState) @@ -89,11 +89,11 @@ impl ProtocolHelper { packet }, _ => { - self.client.conn().close(); + self.client.close(); return Ok(()) }, }; - self.client.conn().write_packet(&packet)?; + self.client.write_packet(&packet)?; Ok(()) } @@ -103,9 +103,9 @@ impl ProtocolHelper { ConnectionState::Configuration => { let mut packet = Packet::empty(0x00); 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()?; let data = if packet.read_boolean()? { let n = packet.read_usize_varint()?; @@ -128,9 +128,9 @@ impl ProtocolHelper { packet.write_varint(id)?; packet.write_string(channel)?; 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 data = if packet.read_boolean()? { let mut data = Vec::new(); @@ -154,7 +154,7 @@ impl ProtocolHelper { }; packet.write_string(channel)?; packet.write_bytes(data)?; - self.client.conn().write_packet(&packet)?; + self.client.write_packet(&packet)?; Ok(()) } } \ No newline at end of file diff --git a/src/server/protocol.rs b/src/server/protocol.rs index 38bcac8..0423e69 100644 --- a/src/server/protocol.rs +++ b/src/server/protocol.rs @@ -3,7 +3,7 @@ use std::{io::Read, sync::Arc}; use super::{player::context::{ClientContext, ClientInfo, Handshake, PlayerInfo}, ServerError}; 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)] pub enum ConnectionState { @@ -21,7 +21,7 @@ pub fn handle_connection( // Получение пакетов производится через client.conn(), // ВАЖНО: не помещать сам client.conn() в переменные, // он должен сразу убиваться иначе соединение гдето задедлочится - let mut packet = read_packet!(client, Handshake); + let mut packet = client.read_packet()?; if packet.id() != 0x00 { return Err(ServerError::UnknownPacket(format!("Неизвестный пакет рукопожатия"))); @@ -40,7 +40,7 @@ pub fn handle_connection( loop { // Чтение запроса - let packet = read_packet!(client, Status); + let packet = client.read_packet()?; match packet.id() { 0x00 => { // Запрос статуса @@ -61,10 +61,10 @@ pub fn handle_connection( // Отправка статуса packet.write_string(&status)?; - write_packet!(client, Status, packet); + client.write_packet(&packet)?; }, 0x01 => { // Пинг - write_packet!(client, Status, packet); + client.write_packet(&packet)?; // Просто отправляем этот же пакет обратно // ID такой-же, содержание тоже, так почему бы и нет? }, @@ -78,7 +78,7 @@ pub fn handle_connection( client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login // Читаем пакет Login Start - let mut packet = read_packet!(client, Login); + let mut packet = client.read_packet()?; let name = packet.read_string()?; let uuid = packet.read_uuid()?; @@ -91,18 +91,18 @@ pub fn handle_connection( // Отправляем пакет Set Compression если сжатие указано if let Some(threshold) = client.server.config.server.compression_threshold { - write_packet!(client, Login, Packet::build(0x03, |p| p.write_usize_varint(threshold))?); - client.conn().set_compression(Some(threshold)); // Устанавливаем сжатие на соединении + client.write_packet(&Packet::build(0x03, |p| p.write_usize_varint(threshold))?)?; + client.set_compression(Some(threshold)); // Устанавливаем сжатие на соединении } // Отправка пакета Login Success - write_packet!(client, Login, Packet::build(0x02, |p| { + client.write_packet(&Packet::build(0x02, |p| { p.write_uuid(&uuid)?; p.write_string(&name)?; p.write_varint(0) - })?); + })?)?; - let packet = read_packet!(client, Login); + let packet = client.read_packet()?; if packet.id() != 0x03 { return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Login Acknowledged"))); @@ -113,7 +113,7 @@ pub fn handle_connection( // Получение бренда клиента из Serverbound Plugin Message // Identifier канала откуда берется бренд: minecraft:brand let brand = loop { - let mut packet = read_packet!(client, Configuration); + let mut packet = client.read_packet()?; if packet.id() == 0x02 { // Пакет Serverbound Plugin Message 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 if packet.id() != 0x00 { @@ -163,9 +163,9 @@ pub fn handle_connection( // 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 { return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Acknowledge Finish Configuration")));