From 6073c7ada684f9785c31958c9cea917573ed2d79 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Fri, 2 May 2025 01:03:06 +0300 Subject: [PATCH] add a player info to the client context --- Cargo.lock | 1 + Cargo.toml | 1 + src/context.rs | 50 +++++++++++++++++++++++++++----------------------- src/main.rs | 42 ++++++++++++++++++++++++++++++------------ src/player.rs | 28 ++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 src/player.rs diff --git a/Cargo.lock b/Cargo.lock index aa30f91..a9e32ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -664,6 +664,7 @@ dependencies = [ "serde_json", "serde_with", "toml", + "uuid", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9c05274..cc4f586 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ palette = "0.7.6" fastnbt = "2.5.0" colog = "1.3.0" log = "0.4.27" +uuid = "1.16.0" diff --git a/src/context.rs b/src/context.rs index 7e5843a..579c011 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,9 +1,9 @@ -use std::{net::{SocketAddr, TcpStream}, sync::{atomic::{AtomicI32, AtomicU16, Ordering}, Arc, RwLock, RwLockWriteGuard}}; +use std::{net::{SocketAddr, TcpStream}, sync::{Arc, RwLock, RwLockWriteGuard}}; use itertools::Itertools; use rust_mc_proto::{MinecraftConnection, Packet}; -use crate::{config::Config, data::ServerError}; +use crate::{config::Config, data::ServerError, player::{ClientInfo, Handshake, PlayerInfo}}; pub struct ServerContext { pub config: Arc, @@ -55,9 +55,9 @@ pub struct ClientContext { pub server: Arc, pub conn: RwLock>, pub addr: SocketAddr, - protocol_version: AtomicI32, - server_address: RwLock, - server_port: AtomicU16, + pub handshake: RwLock>, + pub client_info: RwLock>, + pub player_info: RwLock> } impl ClientContext { @@ -69,33 +69,34 @@ impl ClientContext { server, addr: conn.get_ref().peer_addr().unwrap(), conn: RwLock::new(conn), - protocol_version: AtomicI32::default(), - server_address: RwLock::new(String::new()), - server_port: AtomicU16::default() + handshake: RwLock::new(None), + client_info: RwLock::new(None), + player_info: RwLock::new(None) } } - pub fn handshake( - self: &Arc, - protocol_version: i32, - server_address: String, - server_port: u16 - ) -> () { - self.protocol_version.store(protocol_version, Ordering::SeqCst); - self.server_port.store(server_port, Ordering::SeqCst); - *self.server_address.write().unwrap() = server_address; + pub fn set_handshake(self: &Arc, handshake: Handshake) { + *self.handshake.write().unwrap() = Some(handshake); } - pub fn protocol_version(self: &Arc) -> i32 { - self.protocol_version.load(Ordering::SeqCst) + pub fn set_client_info(self: &Arc, client_info: ClientInfo) { + *self.client_info.write().unwrap() = Some(client_info); } - pub fn server_port(self: &Arc) -> u16 { - self.server_port.load(Ordering::SeqCst) + pub fn set_player_info(self: &Arc, player_info: PlayerInfo) { + *self.player_info.write().unwrap() = Some(player_info); } - pub fn server_address(self: &Arc) -> String { - self.server_address.read().unwrap().clone() + pub fn handshake(self: &Arc) -> Option { + self.handshake.read().unwrap().clone() + } + + pub fn client_info(self: &Arc) -> Option { + self.client_info.read().unwrap().clone() + } + + pub fn player_info(self: &Arc) -> Option { + self.player_info.read().unwrap().clone() } pub fn conn(self: &Arc) -> RwLockWriteGuard<'_, MinecraftConnection> { @@ -116,3 +117,6 @@ pub trait PacketHandler: Sync + Send { fn on_outcoming_packet(&self, _: Arc, _: &mut Packet) -> Result<(), ServerError> { Ok(()) } } +pub struct Player { + +} diff --git a/src/main.rs b/src/main.rs index 79e59b8..8a5b3da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use std::{env::args, io::Read, net::TcpListener, path::PathBuf, sync::Arc, threa use config::Config; use context::{ClientContext, Listener, PacketHandler, ServerContext}; use log::{debug, error, info}; +use player::{ClientInfo, Handshake, PlayerInfo}; use rust_mc_proto::{DataReader, DataWriter, MinecraftConnection, Packet}; use data::{ServerError, TextComponent}; @@ -11,6 +12,7 @@ use pohuy::Pohuy; pub mod config; pub mod data; pub mod context; +pub mod player; pub mod pohuy; @@ -38,7 +40,7 @@ impl Listener for ExampleListener { \"favicon\": \"data:image/png;base64,\", \"enforcesSecureChat\": false }}", - client.protocol_version(), + client.handshake().unwrap().protocol_version, TextComponent::builder() .text("Hello World! ") .extra(vec![ @@ -47,7 +49,7 @@ impl Listener for ExampleListener { .color("gold") .extra(vec![ TextComponent::builder() - .text(&client.protocol_version().to_string()) + .text(&client.handshake().unwrap().protocol_version.to_string()) .underlined(true) .build() ]) @@ -57,7 +59,10 @@ impl Listener for ExampleListener { .color("green") .extra(vec![ TextComponent::builder() - .text(&format!("{}:{}", client.server_address(), client.server_port())) + .text(&format!("{}:{}", + client.handshake().unwrap().server_address, + client.handshake().unwrap().server_port + )) .underlined(true) .build() ]) @@ -178,7 +183,7 @@ fn handle_connection( debug!("server_port: {server_port}"); debug!("next_state: {next_state}"); - client.handshake(protocol_version, server_address, server_port); + client.set_handshake(Handshake { protocol_version, server_address, server_port }); match next_state { 1 => { // Тип подключения - статус @@ -228,11 +233,13 @@ fn handle_connection( // Читаем пакет Login Start let mut packet = client.conn().read_packet()?; - let player_name = packet.read_string()?; - let player_uuid = packet.read_uuid()?; + let name = packet.read_string()?; + let uuid = packet.read_uuid()?; - debug!("name: {player_name}"); - debug!("uuid: {player_uuid}"); + debug!("name: {name}"); + debug!("uuid: {uuid}"); + + client.set_player_info(PlayerInfo { name: name.clone(), uuid: uuid.clone() }); if client.server.config.server.online_mode { // TODO: encryption packets @@ -246,8 +253,8 @@ fn handle_connection( // Отправка пакета Login Success client.conn().write_packet(&Packet::build(0x02, |p| { - p.write_uuid(&player_uuid)?; - p.write_string(&player_name)?; + p.write_uuid(&uuid)?; + p.write_string(&name)?; p.write_varint(0) })?)?; @@ -299,8 +306,6 @@ fn handle_connection( let allow_server_listings = packet.read_boolean()?; // allows showing player in server listings in status let particle_status = packet.read_varint()?; // 0 for all, 1 for decreased, 2 for minimal - // TODO: Сделать запись всех этих полезных данных в клиент контекст - debug!("locale: {locale}"); debug!("view_distance: {view_distance}"); debug!("chat_mode: {chat_mode}"); @@ -311,6 +316,19 @@ fn handle_connection( debug!("allow_server_listings: {allow_server_listings}"); debug!("particle_status: {particle_status}"); + client.set_client_info(ClientInfo { + brand, + locale, + view_distance, + chat_mode, + chat_colors, + displayed_skin_parts, + main_hand, + enable_text_filtering, + allow_server_listings, + particle_status + }); + // TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото client.conn().write_packet(&Packet::empty(0x03))?; diff --git a/src/player.rs b/src/player.rs new file mode 100644 index 0000000..b0a3c21 --- /dev/null +++ b/src/player.rs @@ -0,0 +1,28 @@ +use uuid::Uuid; + +#[derive(Clone)] +pub struct Handshake { + pub protocol_version: i32, + pub server_address: String, + pub server_port: u16, +} + +#[derive(Clone)] +pub struct ClientInfo { + pub brand: String, + pub locale: String, + pub view_distance: i8, + pub chat_mode: i32, + pub chat_colors: bool, + pub displayed_skin_parts: u8, + pub main_hand: i32, + pub enable_text_filtering: bool, + pub allow_server_listings: bool, + pub particle_status: i32 +} + +#[derive(Clone)] +pub struct PlayerInfo { + pub name: String, + pub uuid: Uuid +} \ No newline at end of file