From 9cfb13a0ba3e3cfc1201d06780c8f080dfcb5134 Mon Sep 17 00:00:00 2001 From: lukas0008 Date: Sun, 18 Aug 2024 18:07:28 +0200 Subject: [PATCH] Fix: make the server work a bit better - No longer breaks when someone disconnects - Now rayon threads are outside of tokio runtime (again) --- pumpkin/src/main.rs | 158 ++++++++++++++++++++++-------------------- pumpkin/src/server.rs | 2 +- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 7a86f4b4..68f05700 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -12,7 +12,6 @@ use tokio::{ sync::{Mutex, RwLock}, }; - use config::BasicConfiguration; use server::Server; @@ -31,8 +30,7 @@ pub mod util; #[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc; -#[tokio::main] -async fn main() -> io::Result<()> { +fn main() -> io::Result<()> { #[cfg(feature = "dhat-heap")] let _profiler = dhat::Profiler::new_heap(); #[cfg(feature = "dhat-heap")] @@ -42,80 +40,88 @@ async fn main() -> io::Result<()> { use std::time::Instant; // use rcon::RCONServer; - - let time = Instant::now(); - let basic_config = BasicConfiguration::load("configuration.toml"); - - let advanced_configuration = AdvancedConfiguration::load("features.toml"); - - simple_logger::SimpleLogger::new().init().unwrap(); - - let addr: SocketAddr = format!( - "{}:{}", - basic_config.server_address, basic_config.server_port - ) - .parse() - .unwrap(); - - let listener = TcpListener::bind(addr) - .await - .expect("Failed to start TCP Listener"); - - let use_console = advanced_configuration.commands.use_console; - let rcon = advanced_configuration.rcon.clone(); - - let server = Arc::new(RwLock::new(Server::new(( - basic_config, - advanced_configuration, - )))); - log::info!("Started Server took {}ms", time.elapsed().as_millis()); - log::info!("You now can connect to the server, Listening on {}", addr); - - if use_console { - tokio::spawn(async move { - let stdin = std::io::stdin(); - loop { - let mut out = String::new(); - stdin - .read_line(&mut out) - .expect("Failed to read console line"); - handle_command(&mut commands::CommandSender::Console, &out).await; - } - }); - } - // if rcon.enabled { - // tokio::spawn(async move { - // RCONServer::new(&rcon).await.unwrap(); - // }); - // } - let mut current_clients: u32 = 0; - loop { - let (socket, addr) = listener.accept().await?; - log::info!("Accepted connection from: {}", addr); - - if let Err(e) = socket.set_nodelay(true) { - log::error!("failed to set TCP_NODELAY: {e}"); + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + rt.block_on(async { + let time = Instant::now(); + let basic_config = BasicConfiguration::load("configuration.toml"); + + let advanced_configuration = AdvancedConfiguration::load("features.toml"); + + simple_logger::SimpleLogger::new().init().unwrap(); + + let addr: SocketAddr = format!( + "{}:{}", + basic_config.server_address, basic_config.server_port + ) + .parse() + .unwrap(); + + let listener = TcpListener::bind(addr) + .await + .expect("Failed to start TCP Listener"); + + let use_console = advanced_configuration.commands.use_console; + let rcon = advanced_configuration.rcon.clone(); + + let server = Arc::new(RwLock::new(Server::new(( + basic_config, + advanced_configuration, + )))); + log::info!("Started Server took {}ms", time.elapsed().as_millis()); + log::info!("You now can connect to the server, Listening on {}", addr); + + if use_console { + tokio::spawn(async move { + let stdin = std::io::stdin(); + loop { + let mut out = String::new(); + stdin + .read_line(&mut out) + .expect("Failed to read console line"); + handle_command(&mut commands::CommandSender::Console, &out).await; + } + }); } - let server = server.clone(); - - current_clients += 1; - let token = current_clients; // Replace with your token generation logic - let client = Arc::new(Mutex::new(Client::new(token, socket, addr))); - dbg!("a"); - let mut server_guard = server.write().await; - server_guard.add_client(token, Arc::clone(&client)); - drop(server_guard); - - tokio::spawn(async move { - let mut client = client.lock().await; - - //client.connection.readable().await.expect(":c"); - client.poll(server.clone()).await; - if client.closed { + // if rcon.enabled { + // tokio::spawn(async move { + // RCONServer::new(&rcon).await.unwrap(); + // }); + // } + let mut current_clients: u32 = 0; + loop { + let (socket, addr) = listener.accept().await?; + log::info!("Accepted connection from: {}", addr); + + if let Err(e) = socket.set_nodelay(true) { + log::error!("failed to set TCP_NODELAY: {e}"); + } + let server = server.clone(); + + current_clients += 1; + let token = current_clients; // Replace with your token generation logic + let client = Arc::new(Mutex::new(Client::new(token, socket, addr))); + dbg!("a"); + { let mut server_guard = server.write().await; - server_guard.remove_client(&token).await; - current_clients -= 1; + server_guard.add_client(token, Arc::clone(&client)); } - }); - } + + let server = server.clone(); + tokio::spawn(async move { + let mut client = client.lock().await; + + //client.connection.readable().await.expect(":c"); + client.poll(server.clone()).await; + if client.closed { + drop(client); + let mut server_guard = server.write().await; + server_guard.remove_client(&token).await; + current_clients -= 1; + } + }); + } + }) } diff --git a/pumpkin/src/server.rs b/pumpkin/src/server.rs index 87bd85c2..2d3aa969 100644 --- a/pumpkin/src/server.rs +++ b/pumpkin/src/server.rs @@ -319,7 +319,7 @@ impl Server { from.send_packet(packet).await; for (_, client) in self.current_clients.iter().filter(|c| c.0 != &from.token) { // Check if client is a player - let mut client = client.blocking_lock(); + let mut client = client.lock().await; if client.is_player() { client.send_packet(packet).await; }