add a player info to the client context

This commit is contained in:
MeexReay 2025-05-02 01:03:06 +03:00
parent b7231a1ce4
commit 6073c7ada6
5 changed files with 87 additions and 35 deletions

1
Cargo.lock generated
View File

@ -664,6 +664,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_with", "serde_with",
"toml", "toml",
"uuid",
] ]
[[package]] [[package]]

View File

@ -15,3 +15,4 @@ palette = "0.7.6"
fastnbt = "2.5.0" fastnbt = "2.5.0"
colog = "1.3.0" colog = "1.3.0"
log = "0.4.27" log = "0.4.27"
uuid = "1.16.0"

View File

@ -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 itertools::Itertools;
use rust_mc_proto::{MinecraftConnection, Packet}; 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 struct ServerContext {
pub config: Arc<Config>, pub config: Arc<Config>,
@ -55,9 +55,9 @@ pub struct ClientContext {
pub server: Arc<ServerContext>, pub server: Arc<ServerContext>,
pub conn: RwLock<MinecraftConnection<TcpStream>>, pub conn: RwLock<MinecraftConnection<TcpStream>>,
pub addr: SocketAddr, pub addr: SocketAddr,
protocol_version: AtomicI32, pub handshake: RwLock<Option<Handshake>>,
server_address: RwLock<String>, pub client_info: RwLock<Option<ClientInfo>>,
server_port: AtomicU16, pub player_info: RwLock<Option<PlayerInfo>>
} }
impl ClientContext { impl ClientContext {
@ -69,33 +69,34 @@ impl ClientContext {
server, server,
addr: conn.get_ref().peer_addr().unwrap(), addr: conn.get_ref().peer_addr().unwrap(),
conn: RwLock::new(conn), conn: RwLock::new(conn),
protocol_version: AtomicI32::default(), handshake: RwLock::new(None),
server_address: RwLock::new(String::new()), client_info: RwLock::new(None),
server_port: AtomicU16::default() player_info: RwLock::new(None)
} }
} }
pub fn handshake( pub fn set_handshake(self: &Arc<Self>, handshake: Handshake) {
self: &Arc<Self>, *self.handshake.write().unwrap() = Some(handshake);
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 protocol_version(self: &Arc<Self>) -> i32 { pub fn set_client_info(self: &Arc<Self>, client_info: ClientInfo) {
self.protocol_version.load(Ordering::SeqCst) *self.client_info.write().unwrap() = Some(client_info);
} }
pub fn server_port(self: &Arc<Self>) -> u16 { pub fn set_player_info(self: &Arc<Self>, player_info: PlayerInfo) {
self.server_port.load(Ordering::SeqCst) *self.player_info.write().unwrap() = Some(player_info);
} }
pub fn server_address(self: &Arc<Self>) -> String { pub fn handshake(self: &Arc<Self>) -> Option<Handshake> {
self.server_address.read().unwrap().clone() self.handshake.read().unwrap().clone()
}
pub fn client_info(self: &Arc<Self>) -> Option<ClientInfo> {
self.client_info.read().unwrap().clone()
}
pub fn player_info(self: &Arc<Self>) -> Option<PlayerInfo> {
self.player_info.read().unwrap().clone()
} }
pub fn conn(self: &Arc<Self>) -> RwLockWriteGuard<'_, MinecraftConnection<TcpStream>> { pub fn conn(self: &Arc<Self>) -> RwLockWriteGuard<'_, MinecraftConnection<TcpStream>> {
@ -116,3 +117,6 @@ pub trait PacketHandler: Sync + Send {
fn on_outcoming_packet(&self, _: Arc<ClientContext>, _: &mut Packet) -> Result<(), ServerError> { Ok(()) } fn on_outcoming_packet(&self, _: Arc<ClientContext>, _: &mut Packet) -> Result<(), ServerError> { Ok(()) }
} }
pub struct Player {
}

View File

@ -3,6 +3,7 @@ use std::{env::args, io::Read, net::TcpListener, path::PathBuf, sync::Arc, threa
use config::Config; use config::Config;
use context::{ClientContext, Listener, PacketHandler, ServerContext}; use context::{ClientContext, Listener, PacketHandler, ServerContext};
use log::{debug, error, info}; use log::{debug, error, info};
use player::{ClientInfo, Handshake, PlayerInfo};
use rust_mc_proto::{DataReader, DataWriter, MinecraftConnection, Packet}; use rust_mc_proto::{DataReader, DataWriter, MinecraftConnection, Packet};
use data::{ServerError, TextComponent}; use data::{ServerError, TextComponent};
@ -11,6 +12,7 @@ use pohuy::Pohuy;
pub mod config; pub mod config;
pub mod data; pub mod data;
pub mod context; pub mod context;
pub mod player;
pub mod pohuy; pub mod pohuy;
@ -38,7 +40,7 @@ impl Listener for ExampleListener {
\"favicon\": \"data:image/png;base64,<data>\", \"favicon\": \"data:image/png;base64,<data>\",
\"enforcesSecureChat\": false \"enforcesSecureChat\": false
}}", }}",
client.protocol_version(), client.handshake().unwrap().protocol_version,
TextComponent::builder() TextComponent::builder()
.text("Hello World! ") .text("Hello World! ")
.extra(vec![ .extra(vec![
@ -47,7 +49,7 @@ impl Listener for ExampleListener {
.color("gold") .color("gold")
.extra(vec![ .extra(vec![
TextComponent::builder() TextComponent::builder()
.text(&client.protocol_version().to_string()) .text(&client.handshake().unwrap().protocol_version.to_string())
.underlined(true) .underlined(true)
.build() .build()
]) ])
@ -57,7 +59,10 @@ impl Listener for ExampleListener {
.color("green") .color("green")
.extra(vec![ .extra(vec![
TextComponent::builder() TextComponent::builder()
.text(&format!("{}:{}", client.server_address(), client.server_port())) .text(&format!("{}:{}",
client.handshake().unwrap().server_address,
client.handshake().unwrap().server_port
))
.underlined(true) .underlined(true)
.build() .build()
]) ])
@ -178,7 +183,7 @@ fn handle_connection(
debug!("server_port: {server_port}"); debug!("server_port: {server_port}");
debug!("next_state: {next_state}"); 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 { match next_state {
1 => { // Тип подключения - статус 1 => { // Тип подключения - статус
@ -228,11 +233,13 @@ fn handle_connection(
// Читаем пакет Login Start // Читаем пакет Login Start
let mut packet = client.conn().read_packet()?; let mut packet = client.conn().read_packet()?;
let player_name = packet.read_string()?; let name = packet.read_string()?;
let player_uuid = packet.read_uuid()?; let uuid = packet.read_uuid()?;
debug!("name: {player_name}"); debug!("name: {name}");
debug!("uuid: {player_uuid}"); debug!("uuid: {uuid}");
client.set_player_info(PlayerInfo { name: name.clone(), uuid: uuid.clone() });
if client.server.config.server.online_mode { if client.server.config.server.online_mode {
// TODO: encryption packets // TODO: encryption packets
@ -246,8 +253,8 @@ fn handle_connection(
// Отправка пакета Login Success // Отправка пакета Login Success
client.conn().write_packet(&Packet::build(0x02, |p| { client.conn().write_packet(&Packet::build(0x02, |p| {
p.write_uuid(&player_uuid)?; p.write_uuid(&uuid)?;
p.write_string(&player_name)?; p.write_string(&name)?;
p.write_varint(0) 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 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 let particle_status = packet.read_varint()?; // 0 for all, 1 for decreased, 2 for minimal
// TODO: Сделать запись всех этих полезных данных в клиент контекст
debug!("locale: {locale}"); debug!("locale: {locale}");
debug!("view_distance: {view_distance}"); debug!("view_distance: {view_distance}");
debug!("chat_mode: {chat_mode}"); debug!("chat_mode: {chat_mode}");
@ -311,6 +316,19 @@ fn handle_connection(
debug!("allow_server_listings: {allow_server_listings}"); debug!("allow_server_listings: {allow_server_listings}");
debug!("particle_status: {particle_status}"); 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'ы чтобы они подмешивали сюда чото // TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото
client.conn().write_packet(&Packet::empty(0x03))?; client.conn().write_packet(&Packet::empty(0x03))?;

28
src/player.rs Normal file
View File

@ -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
}