diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/mod.rs | 129 |
1 files changed, 69 insertions, 60 deletions
diff --git a/src/server/mod.rs b/src/server/mod.rs index c9550f7..4f95378 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -5,6 +5,8 @@ use crate::net::Cargo; use crate::world::World; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; use std::thread::{self, JoinHandle}; /// The default port the dedicated graf karto server runs on. @@ -25,85 +27,92 @@ pub fn start_with_port(port: u16, ipv4: bool) -> Result<JoinHandle<()>, io::Erro let addr = unspecified(port, ipv4); let conn_man = ConnectionManager::start(addr)?; - Ok(start(conn_man)) + Ok(start(conn_man).0) } /// Starts a thread on any free system port. Returns an error in case that's not /// possible. -pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, u16), io::Error> { +pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, Arc<AtomicBool>, u16), io::Error> { let addr = unspecified(0, ipv4); let conn_man = ConnectionManager::start(addr)?; let port = conn_man.port(); - Ok((start(conn_man), port)) + let (handle, running) = start(conn_man); + Ok((handle, running, port)) } -fn start(conn_man: ConnectionManager<Cargo>) -> JoinHandle<()> { +fn start(conn_man: ConnectionManager<Cargo>) -> (JoinHandle<()>, Arc<AtomicBool>) { info!("Server started on port {}", conn_man.port()); + let running = Arc::new(AtomicBool::new(true)); + let running_cl = running.clone(); let mut world = World::new(); - thread::spawn(move || loop { - if let Some((user, cargo)) = conn_man.next_packet() { - match cargo { - Cargo::AddRoom(room) => { - let room_id = world.push_room(room.clone()); - conn_man.broadcast(Cargo::SetRoom((room_id, room))); - } - Cargo::AddIcon(icon) => { - let icon_id = world.push_icon(icon.clone()); - conn_man.broadcast(Cargo::SetIcon((icon_id, icon))); - } - Cargo::AddWall(wall) => { - let wall_id = world.push_wall(wall.clone()); - conn_man.broadcast(Cargo::SetWall((wall_id, wall))); - } - Cargo::SetRoom((id, new)) => { - if let Some(old) = world.get_room_mut(id) { - *old = new; - } else { - error!( - "Unable to change room. Room with id `{}` does not exist.", - id - ); + let handle = thread::spawn(move || { + while running_cl.load(Ordering::Relaxed) { + if let Some((_user, cargo)) = conn_man.next_packet() { + match cargo { + Cargo::AddRoom(room) => { + let room_id = world.push_room(room.clone()); + conn_man.broadcast(Cargo::SetRoom((room_id, room))); } - } - Cargo::SetIcon((id, new)) => { - if let Some(old) = world.get_icon_mut(id) { - *old = new; - } else { - error!( - "Unable to change icon. Icon with id `{}` does not exist.", - id - ); + Cargo::AddIcon(icon) => { + let icon_id = world.push_icon(icon.clone()); + conn_man.broadcast(Cargo::SetIcon((icon_id, icon))); } - } - Cargo::SetWall((id, new)) => { - if let Some(old) = world.get_wall_mut(id) { - *old = new; - } else { - error!( - "Unable to change wall. Wall with id `{}` does not exist.", - id - ); + Cargo::AddWall(wall) => { + let wall_id = world.push_wall(wall.clone()); + conn_man.broadcast(Cargo::SetWall((wall_id, wall))); } - } - Cargo::ClearAll => { - world.clear(); - conn_man.broadcast(Cargo::ClearAll); - } - Cargo::Remove(id) => { - if world.remove(id) { - conn_man.broadcast(Cargo::Remove(id)); - } else { - error!("Unable to remove item. No item with id `{}` found.", id); + Cargo::SetRoom((id, new)) => { + if let Some(old) = world.get_room_mut(id) { + *old = new; + } else { + error!( + "Unable to change room. Room with id `{}` does not exist.", + id + ); + } + } + Cargo::SetIcon((id, new)) => { + if let Some(old) = world.get_icon_mut(id) { + *old = new; + } else { + error!( + "Unable to change icon. Icon with id `{}` does not exist.", + id + ); + } + } + Cargo::SetWall((id, new)) => { + if let Some(old) = world.get_wall_mut(id) { + *old = new; + } else { + error!( + "Unable to change wall. Wall with id `{}` does not exist.", + id + ); + } + } + Cargo::ClearAll => { + world.clear(); + conn_man.broadcast(Cargo::ClearAll); + } + Cargo::Remove(id) => { + if world.remove(id) { + conn_man.broadcast(Cargo::Remove(id)); + } else { + error!("Unable to remove item. No item with id `{}` found.", id); + } + } + Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(), + Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => { + error!("This packet is not allowed in the client -> server direction"); } - } - Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(), - Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => { - error!("This packet is not allowed in the client -> server direction"); } } } - }) + }); + + (handle, running) } |
