diff options
Diffstat (limited to 'server/src/customer/mod.rs')
-rw-r--r-- | server/src/customer/mod.rs | 60 |
1 files changed, 34 insertions, 26 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) } |