clients storage

This commit is contained in:
MeexReay 2025-05-02 02:06:29 +03:00
parent 6073c7ada6
commit 2a40c56a43
4 changed files with 138 additions and 4 deletions

77
Cargo.lock generated
View File

@ -103,6 +103,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.17.0" version = "3.17.0"
@ -197,6 +203,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.20.11" version = "0.20.11"
@ -232,6 +244,20 @@ dependencies = [
"syn", "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]] [[package]]
name = "deranged" name = "deranged"
version = "0.4.0" version = "0.4.0"
@ -317,6 +343,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.3" version = "0.15.3"
@ -448,6 +480,16 @@ version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 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]] [[package]]
name = "log" name = "log"
version = "0.4.27" version = "0.4.27"
@ -514,6 +556,19 @@ dependencies = [
"syn", "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]] [[package]]
name = "phf" name = "phf"
version = "0.11.3" version = "0.11.3"
@ -610,6 +665,15 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 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]] [[package]]
name = "regex" name = "regex"
version = "1.11.1" version = "1.11.1"
@ -654,6 +718,7 @@ name = "rust_minecraft_server"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"colog", "colog",
"dashmap",
"fastnbt", "fastnbt",
"itertools", "itertools",
"log", "log",
@ -679,6 +744,12 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.219" version = "1.0.219"
@ -783,6 +854,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "smallvec"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"

View File

@ -16,3 +16,4 @@ fastnbt = "2.5.0"
colog = "1.3.0" colog = "1.3.0"
log = "0.4.27" log = "0.4.27"
uuid = "1.16.0" uuid = "1.16.0"
dashmap = "6.1.0"

View File

@ -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 itertools::Itertools;
use rust_mc_proto::{MinecraftConnection, Packet}; use rust_mc_proto::{MinecraftConnection, Packet};
use uuid::Uuid;
use crate::{config::Config, data::ServerError, player::{ClientInfo, Handshake, PlayerInfo}}; use crate::{config::Config, data::ServerError, player::{ClientInfo, Handshake, PlayerInfo}};
pub struct ServerContext { pub struct ServerContext {
pub config: Arc<Config>, pub config: Arc<Config>,
pub clients: DashMap<SocketAddr, Arc<ClientContext>>,
listeners: Vec<Box<dyn Listener>>, listeners: Vec<Box<dyn Listener>>,
handlers: Vec<Box<dyn PacketHandler>> handlers: Vec<Box<dyn PacketHandler>>
} }
@ -16,10 +19,44 @@ impl ServerContext {
ServerContext { ServerContext {
config, config,
listeners: Vec::new(), listeners: Vec::new(),
handlers: Vec::new() handlers: Vec::new(),
clients: DashMap::new()
} }
} }
pub fn get_player_by_uuid(self: &Arc<Self>, uuid: Uuid) -> Option<Arc<ClientContext>> {
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<Self>, name: &str) -> Option<Arc<ClientContext>> {
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<Self>) -> Vec<Arc<ClientContext>> {
self.clients.iter()
.filter(|o| o.player_info().is_some())
.map(|o| o.clone())
.collect()
}
pub fn add_packet_handler(&mut self, handler: Box<dyn PacketHandler>) { pub fn add_packet_handler(&mut self, handler: Box<dyn PacketHandler>) {
self.handlers.push(handler); self.handlers.push(handler);
} }
@ -60,6 +97,21 @@ pub struct ClientContext {
pub player_info: RwLock<Option<PlayerInfo>> pub player_info: RwLock<Option<PlayerInfo>>
} }
impl PartialEq for ClientContext {
fn eq(&self, other: &Self) -> bool {
self.addr == other.addr
}
}
impl Hash for ClientContext {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.addr.hash(state);
}
}
impl Eq for ClientContext {}
impl ClientContext { impl ClientContext {
pub fn new( pub fn new(
server: Arc<ServerContext>, server: Arc<ServerContext>,

View File

@ -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(_) => {}, Ok(_) => {},
Err(error) => { Err(error) => {
error!("Ошибка подключения: {error:?}"); error!("Ошибка подключения: {error:?}");
}, },
}; };
server.clients.remove(&client.addr);
info!("Отключение: {}", addr); info!("Отключение: {}", addr);
}); });
} }