aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client_main.rs8
-rw-r--r--src/server/mod.rs129
2 files changed, 74 insertions, 63 deletions
diff --git a/src/client_main.rs b/src/client_main.rs
index 70dd857..43660d7 100644
--- a/src/client_main.rs
+++ b/src/client_main.rs
@@ -32,6 +32,7 @@ pub mod world;
use clap::{App, Arg};
use server::DEFAULT_PORT;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
+use std::sync::atomic::Ordering;
fn main() {
pretty_env_logger::init();
@@ -72,10 +73,10 @@ fn main() {
let server_handle = if !matches.is_present("connect") {
Some({
- let (server_handle, port) =
+ let (server_handle, server_running, port) =
server::start_any_port(use_ipv4).expect("Unable to start local server");
server_port = port;
- server_handle
+ (server_handle, server_running)
})
} else {
None
@@ -111,7 +112,8 @@ fn main() {
client::run(dbg!(server_address));
- if let Some(handle) = server_handle {
+ if let Some((handle, running)) = server_handle {
+ running.store(false, Ordering::Relaxed);
handle.join().expect("Server thread closed unexpectedly.");
}
}
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)
}