diff --git a/Cargo.lock b/Cargo.lock index a9e32ae..3ba9702 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,6 +103,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + [[package]] name = "bumpalo" version = "3.17.0" @@ -197,6 +203,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "darling" version = "0.20.11" @@ -232,6 +244,20 @@ dependencies = [ "syn", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deranged" version = "0.4.0" @@ -317,6 +343,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.3" @@ -448,6 +480,16 @@ version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.27" @@ -514,6 +556,19 @@ dependencies = [ "syn", ] +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "phf" version = "0.11.3" @@ -610,6 +665,15 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.11.1" @@ -654,6 +718,7 @@ name = "rust_minecraft_server" version = "0.1.0" dependencies = [ "colog", + "dashmap", "fastnbt", "itertools", "log", @@ -679,6 +744,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.219" @@ -783,6 +854,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + [[package]] name = "strsim" version = "0.11.1" diff --git a/Cargo.toml b/Cargo.toml index cc4f586..73391a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ fastnbt = "2.5.0" colog = "1.3.0" log = "0.4.27" uuid = "1.16.0" +dashmap = "6.1.0" diff --git a/src/context.rs b/src/context.rs index 579c011..561bdd1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,12 +1,15 @@ -use std::{net::{SocketAddr, TcpStream}, sync::{Arc, RwLock, RwLockWriteGuard}}; +use std::{hash::Hash, net::{SocketAddr, TcpStream}, sync::{Arc, RwLock, RwLockWriteGuard}}; +use dashmap::DashMap; use itertools::Itertools; use rust_mc_proto::{MinecraftConnection, Packet}; +use uuid::Uuid; use crate::{config::Config, data::ServerError, player::{ClientInfo, Handshake, PlayerInfo}}; pub struct ServerContext { pub config: Arc, + pub clients: DashMap>, listeners: Vec>, handlers: Vec> } @@ -16,10 +19,44 @@ impl ServerContext { ServerContext { config, listeners: Vec::new(), - handlers: Vec::new() + handlers: Vec::new(), + clients: DashMap::new() } } + pub fn get_player_by_uuid(self: &Arc, uuid: Uuid) -> Option> { + self.clients.iter() + .find(|o| { + let info = o.player_info(); + if let Some(info) = info { + info.uuid == uuid + } else { + false + } + }) + .map(|o| o.clone()) + } + + pub fn get_player_by_name(self: &Arc, name: &str) -> Option> { + self.clients.iter() + .find(|o| { + let info = o.player_info(); + if let Some(info) = info { + info.name == name + } else { + false + } + }) + .map(|o| o.clone()) + } + + pub fn players(self: &Arc) -> Vec> { + self.clients.iter() + .filter(|o| o.player_info().is_some()) + .map(|o| o.clone()) + .collect() + } + pub fn add_packet_handler(&mut self, handler: Box) { self.handlers.push(handler); } @@ -60,6 +97,21 @@ pub struct ClientContext { pub player_info: RwLock> } +impl PartialEq for ClientContext { + fn eq(&self, other: &Self) -> bool { + self.addr == other.addr + } +} + +impl Hash for ClientContext { + fn hash(&self, state: &mut H) { + self.addr.hash(state); + } +} + +impl Eq for ClientContext {} + + impl ClientContext { pub fn new( server: Arc, diff --git a/src/main.rs b/src/main.rs index 8a5b3da..3841eeb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -144,17 +144,21 @@ fn main() { // Создаем контекст клиента // Передавется во все листенеры и хандлеры чтобы определять именно этот клиент - let client = Arc::new(ClientContext::new(server, conn)); + let client = Arc::new(ClientContext::new(server.clone(), conn)); + + server.clients.insert(client.addr, client.clone()); // Обработка подключения // Если ошибка -> выводим - match handle_connection(client) { + match handle_connection(client.clone()) { Ok(_) => {}, Err(error) => { error!("Ошибка подключения: {error:?}"); }, }; + server.clients.remove(&client.addr); + info!("Отключение: {}", addr); }); }