diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/customer/mod.rs | 60 | ||||
-rw-r--r-- | server/src/main.rs | 1 | ||||
-rw-r--r-- | server/src/state.rs | 13 |
3 files changed, 46 insertions, 28 deletions
diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index 185133e7..0b300b6e 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -24,8 +24,9 @@ use crate::{ protocol::{DemandIndex, ItemIndex, Message, PacketC, PacketS, PlayerID}, state::State, }; +use anyhow::{anyhow, Result}; use glam::{IVec2, Vec2}; -use log::{debug, error}; +use log::{debug, error, warn}; use movement::MovementBase; use pathfinding::{find_path, Path}; use rand::{random, thread_rng}; @@ -81,12 +82,12 @@ struct Customer { pub async fn customer(gstate: Arc<RwLock<State>>, mut grx: broadcast::Receiver<PacketC>) { let mut state = CustomerManager { + disabled: true, customer_id_counter: PlayerID(0), walkable: Default::default(), chairs: Default::default(), items: Default::default(), customers: Default::default(), - disabled: true, demand: DemandState { data: Gamedata::default(), }, @@ -101,7 +102,13 @@ pub async fn customer(gstate: Arc<RwLock<State>>, mut grx: broadcast::Receiver<P loop { tokio::select! { packet = grx.recv() => { - let packet = packet.unwrap(); + let packet = match packet { + Ok(p) => p, + Err(e) => { + warn!("{e}"); + continue; + } + }; match packet { PacketC::PutItem { .. } | PacketC::TakeItem { .. } @@ -115,7 +122,9 @@ pub async fn customer(gstate: Arc<RwLock<State>>, mut grx: broadcast::Receiver<P } _ = interval.tick() => { if !state.disabled { - state.tick(&mut packets_out, 0.04); + if let Err(e) = state.tick(&mut packets_out, 0.04) { + warn!("error caught: {e}") + } for (player,packet) in packets_out.drain(..) { if let Err(e) = gstate.write().await.packet_in(player, packet).await { error!("customer misbehaved: {e}") @@ -159,22 +168,25 @@ impl CustomerManager { self.customers.remove(&id); } PacketC::UpdateMap { - tile: pos, - kind: Some(tile), - .. + tile: pos, kind, .. } => { - let tilename = self.demand.data.tile_name(tile); - if !self.demand.data.is_tile_colliding(tile) { - self.walkable.insert(pos); - } - if tilename == "chair" { - self.chairs.insert(pos, true); + if let Some(kind) = kind { + let tilename = self.demand.data.tile_name(kind); + if !self.demand.data.is_tile_colliding(kind) { + self.walkable.insert(pos); + } + if tilename == "chair" { + self.chairs.insert(pos, true); + } + } else { + self.chairs.remove(&pos); + self.walkable.remove(&pos); } } _ => (), } } - pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) { + pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) -> Result<()> { if self.customers.len() < self.demand.target_customer_count() { self.customer_id_counter.0 -= 1; let id = self.customer_id_counter; @@ -185,13 +197,9 @@ impl CustomerManager { character: -2, }, )); - let chair = select_chair(&mut self.chairs); - let path = find_path( - &self.walkable, - self.demand.data.customer_spawn.as_ivec2(), - chair, - ) - .expect("no path"); + let chair = select_chair(&mut self.chairs).ok_or(anyhow!("no free chair found"))?; + let to = self.demand.data.customer_spawn.as_ivec2(); + let path = find_path(&self.walkable, to, chair).ok_or(anyhow!("no path to {to}"))?; self.customers.insert( id, Customer { @@ -292,7 +300,7 @@ impl CustomerManager { p.movement.position.as_ivec2(), self.demand.data.customer_spawn.as_ivec2(), ) - .expect("no path to exit"); + .ok_or(anyhow!("no path to exit"))?; *self.chairs.get_mut(&chair).unwrap() = true; p.state = CustomerState::Exiting { path } } @@ -310,16 +318,16 @@ impl CustomerManager { for c in customers_to_remove { self.customers.remove(&c).unwrap(); } + Ok(()) } } -pub fn select_chair(chairs: &mut HashMap<IVec2, bool>) -> IVec2 { +pub fn select_chair(chairs: &mut HashMap<IVec2, bool>) -> Option<IVec2> { use rand::seq::IteratorRandom; let (chosen, free) = chairs .iter_mut() .filter(|(_p, free)| **free) - .choose(&mut thread_rng()) - .unwrap(); + .choose(&mut thread_rng())?; *free = false; - *chosen + Some(*chosen) } diff --git a/server/src/main.rs b/server/src/main.rs index 6773bf29..b3e6334d 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -99,6 +99,7 @@ async fn main() -> Result<()> { } }); spawn(async move { + info!("{id:?} joined"); while let Some(Ok(message)) = read.next().await { match message { Message::Text(line) => { diff --git a/server/src/state.rs b/server/src/state.rs index 98f92a24..08d8516a 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -17,7 +17,11 @@ pub struct State { #[derive(Parser)] #[clap(multicall = true)] enum Command { - Start { spec: String }, + Start { + #[arg(default_value = "default-small-default")] + spec: String, + }, + End, } impl State { @@ -60,7 +64,12 @@ impl State { async fn handle_command(&mut self, command: Command) -> Result<()> { match command { Command::Start { spec } => { - self.game.load(self.index.generate(spec)?); + let data = self.index.generate(spec)?; + self.game.load(data); + } + Command::End => { + self.game + .load(self.index.generate("none-lobby-none".to_string())?); } } Ok(()) |