diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/world.rs | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/src/world.rs b/src/world.rs index 9de51d7..b42a1db 100644 --- a/src/world.rs +++ b/src/world.rs @@ -13,6 +13,7 @@ use crate::{ playerstate::{PlayerState, RoomPos}, Encyclopedia, controls::Control, + errors::{AnyError}, Result, aerr, worldmessages::WorldMessage, @@ -32,6 +33,11 @@ pub struct World<'a, 'b> { default_dispatcher: Dispatcher<'a, 'b> } +#[derive(Debug)] +pub enum MigrationError { + PlayerError(AnyError), + RoomError(AnyError) +} impl <'a, 'b>World<'a, 'b> { @@ -91,18 +97,37 @@ impl <'a, 'b>World<'a, 'b> { } self.rooms.insert(id.clone(), room); } - // todo: log any that occurs (and still return it) - self.rooms.get_mut(id).ok_or(aerr!("can't get room after loading it")) + Ok(self.rooms.get_mut(id).expect("can't get room after loading it")) } - fn add_loaded_player(&mut self, state: PlayerState) -> Result<()> { + fn add_loaded_player(&mut self, state: PlayerState) -> std::result::Result<(), MigrationError> { let roomid = state.clone().room.unwrap_or_else(|| self.default_room.clone()); - let room = self.get_room_mut(&roomid)?; - room.add_player(&state)?; + let room = self.get_room_mut(&roomid).map_err(|e| MigrationError::RoomError(e))?; + room.add_player(&state).map_err(|e| MigrationError::PlayerError(e))?; self.players.insert(state.id, roomid); Ok(()) } + fn try_add_loaded_player(&mut self, mut state: PlayerState, backups: &[Option<RoomId>]) -> Result<()> { + match self.add_loaded_player(state.clone()){ + Err(MigrationError::RoomError(e)) => { + println!("could not add player {:?} to room {:?}: {:?}", state.id, state.room, e); + if let Some((first, rest)) = backups.split_first(){ + state.room = first.clone(); + state.pos = RoomPos::Unknown; + self.try_add_loaded_player(state, rest) + } else { + Err(e) + } + } + Err(MigrationError::PlayerError(e)) => { + println!("could not load player {:?} to room {:?}: {:?}", state.id, state.room, e); + Err(e) + } + Ok(()) => Ok(()) + } + } + pub fn add_player(&mut self, playerid: &PlayerId) -> Result<()> { let mut state = match self.persistence.load_player(playerid.clone()) { Ok(state) => {state} @@ -118,15 +143,7 @@ impl <'a, 'b>World<'a, 'b> { state.respawn(); } - if let Err(_e) = self.add_loaded_player(state.clone()){ - state.room = None; - state.pos = RoomPos::Unknown; - if let Err(_e) = self.add_loaded_player(state.clone()) { - state.room = Some(purgatory::purgatory_id()); - self.add_loaded_player(state)?; - } - } - Ok(()) + self.try_add_loaded_player(state, &[None]) } fn discorporate_player(&mut self, playerid: &PlayerId) -> Result<PlayerState> { @@ -153,18 +170,7 @@ impl <'a, 'b>World<'a, 'b> { let old_room = state.room; state.room = Some(destination); state.pos = roompos; - if let Err(_e) = self.add_loaded_player(state.clone()){ - state.room = old_room; - state.pos = RoomPos::Unknown; - if let Err(_e) = self.add_loaded_player(state.clone()) { - state.room = None; - if let Err(_e) = self.add_loaded_player(state.clone()) { - state.room = Some(purgatory::purgatory_id()); - self.add_loaded_player(state)?; - } - } - } - Ok(()) + self.try_add_loaded_player(state, &[old_room, None]) } |
