async EntityGateway
This commit is contained in:
		
							parent
							
								
									ddee920080
								
							
						
					
					
						commit
						8d49c50cc5
					
				| @ -7,7 +7,7 @@ edition = "2018" | ||||
| [dependencies] | ||||
| libpso = { git = "http://git.sharnoth.com/jake/libpso" } | ||||
| async-std = { version = "1.5.0", features = ["unstable"] } | ||||
| futures = "0.3.4" | ||||
| futures = "0.3.5" | ||||
| rand = "0.7.3" | ||||
| rand_chacha = "0.2.2" | ||||
| mio = "0.6" | ||||
| @ -27,4 +27,5 @@ enum-utils = "0.1.2" | ||||
| derive_more = { version = "0.99.3", features = ["display"]} | ||||
| thiserror = "1.0.15" | ||||
| ages-prs = "0.1" | ||||
| async-trait = "0.1.31" | ||||
| 
 | ||||
|  | ||||
| @ -44,52 +44,53 @@ fn setup_logger() { | ||||
| 
 | ||||
| fn main() { | ||||
|     setup_logger(); | ||||
|     let mut entity_gateway = InMemoryGateway::new(); | ||||
| 
 | ||||
|     for i in 0..5 { | ||||
|         let fake_user = NewUserAccountEntity { | ||||
|             username: if i == 0 { "hi".to_string() } else { format!("hi{}", i+1) }, | ||||
|             password: bcrypt::hash("qwer", 5).unwrap(), | ||||
|             guildcard: i + 1, | ||||
|             team_id: None, | ||||
|             banned: false, | ||||
|             muted_until: SystemTime::now(), | ||||
|             created_at: SystemTime::now(), | ||||
|             flags: 0, | ||||
|         }; | ||||
|         let fake_user = entity_gateway.create_user(fake_user).unwrap(); | ||||
|         entity_gateway.create_user_settings(NewUserSettingsEntity::new(fake_user.id)); | ||||
|         let mut character = NewCharacterEntity::new(fake_user.id); | ||||
|         character.name = format!("Test Char {}", i*2); | ||||
|         entity_gateway.create_character(character); | ||||
|         let mut character = NewCharacterEntity::new(fake_user.id); | ||||
|         character.slot = 2; | ||||
|         character.name = "no progress".into(); | ||||
|         character.exp = 80000000; | ||||
|         let character = entity_gateway.create_character(character).unwrap(); | ||||
| 
 | ||||
|         entity_gateway.create_item( | ||||
|             NewItemEntity { | ||||
|                 item: ItemDetail::Weapon( | ||||
|                     item::weapon::Weapon { | ||||
|                         weapon: item::weapon::WeaponType::Raygun, | ||||
|                         grind: 5, | ||||
|                         special: Some(item::weapon::WeaponSpecial::Hell), | ||||
|                         attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), | ||||
|                         Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), | ||||
|                         None,], | ||||
|                         tekked: true, | ||||
|                     } | ||||
|                 ), | ||||
|                 location: ItemLocation::Inventory { | ||||
|                     character_id: character.id, | ||||
|                     slot: 0, | ||||
|                     equipped: true, | ||||
|                 } | ||||
|             }); | ||||
|     } | ||||
| 
 | ||||
|     async_std::task::block_on(async move { | ||||
|         let mut entity_gateway = InMemoryGateway::new(); | ||||
| 
 | ||||
|         for i in 0..5 { | ||||
|             let fake_user = NewUserAccountEntity { | ||||
|                 username: if i == 0 { "hi".to_string() } else { format!("hi{}", i+1) }, | ||||
|                 password: bcrypt::hash("qwer", 5).unwrap(), | ||||
|                 guildcard: i + 1, | ||||
|                 team_id: None, | ||||
|                 banned: false, | ||||
|                 muted_until: SystemTime::now(), | ||||
|                 created_at: SystemTime::now(), | ||||
|                 flags: 0, | ||||
|             }; | ||||
|             let fake_user = entity_gateway.create_user(fake_user).await.unwrap(); | ||||
|             entity_gateway.create_user_settings(NewUserSettingsEntity::new(fake_user.id)).await; | ||||
|             let mut character = NewCharacterEntity::new(fake_user.id); | ||||
|             character.name = format!("Test Char {}", i*2); | ||||
|             entity_gateway.create_character(character).await; | ||||
|             let mut character = NewCharacterEntity::new(fake_user.id); | ||||
|             character.slot = 2; | ||||
|             character.name = "no progress".into(); | ||||
|             character.exp = 80000000; | ||||
|             character.meseta = 999999; | ||||
|             let character = entity_gateway.create_character(character).await.unwrap(); | ||||
| 
 | ||||
|             entity_gateway.create_item( | ||||
|                 NewItemEntity { | ||||
|                     item: ItemDetail::Weapon( | ||||
|                         item::weapon::Weapon { | ||||
|                             weapon: item::weapon::WeaponType::Raygun, | ||||
|                             grind: 5, | ||||
|                             special: Some(item::weapon::WeaponSpecial::Hell), | ||||
|                             attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), | ||||
|                                     Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), | ||||
|                                     None,], | ||||
|                             tekked: false, | ||||
|                         } | ||||
|                     ), | ||||
|                     location: ItemLocation::Inventory { | ||||
|                         character_id: character.id, | ||||
|                         slot: 0, | ||||
|                         equipped: true, | ||||
|                     } | ||||
|                 }).await; | ||||
|         } | ||||
| 
 | ||||
|         let patch = async_std::task::spawn(async { | ||||
|             info!("[patch] starting server"); | ||||
|             let patch_config = load_config(); | ||||
|  | ||||
| @ -165,7 +165,7 @@ async fn server_state_loop<STATE, S, R, E>(mut state: STATE, | ||||
|                     } | ||||
|                 }, | ||||
|                 ClientAction::Packet(client_id, pkt) => { | ||||
|                     let pkts = state.handle(client_id, &pkt); | ||||
|                     let pkts = state.handle(client_id, &pkt).await; | ||||
|                     match pkts { | ||||
|                         Ok(pkts) => { | ||||
|                             for (client_id, pkt) in pkts { | ||||
|  | ||||
| @ -9,22 +9,23 @@ pub enum OnConnect<S: SendServerPacket> { | ||||
|     Cipher((Box<dyn PSOCipher + Send + Sync>, Box<dyn PSOCipher + Send + Sync>)), | ||||
| } | ||||
| 
 | ||||
| pub trait RecvServerPacket: Sized { | ||||
| pub trait RecvServerPacket: Sized + Sync { | ||||
|     fn from_bytes(data: &[u8]) -> Result<Self, PacketParseError>; | ||||
| } | ||||
| 
 | ||||
| pub trait SendServerPacket: Sized { | ||||
| pub trait SendServerPacket: Sized + Sync { | ||||
|     fn as_bytes(&self) -> Vec<u8>; | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| pub trait ServerState { | ||||
|     type SendPacket: SendServerPacket; | ||||
|     type RecvPacket: RecvServerPacket; | ||||
|     type PacketError; | ||||
|     
 | ||||
|     fn on_connect(&mut self, id: ClientId) -> Vec<OnConnect<Self::SendPacket>>; | ||||
|     fn handle(&mut self, id: ClientId, pkt: &Self::RecvPacket) | ||||
|               -> Result<Box<dyn Iterator<Item = (ClientId, Self::SendPacket)> + Send>, Self::PacketError>; | ||||
|     async fn handle(&mut self, id: ClientId, pkt: &Self::RecvPacket) | ||||
|                     -> Result<Box<dyn Iterator<Item = (ClientId, Self::SendPacket)> + Send>, Self::PacketError>; | ||||
|     fn on_disconnect(&mut self, id: ClientId) -> Vec<(ClientId, Self::SendPacket)>; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,28 +2,29 @@ use crate::entity::account::*; | ||||
| use crate::entity::character::*; | ||||
| use crate::entity::item::*; | ||||
| 
 | ||||
| pub trait EntityGateway { | ||||
|     fn create_user(&mut self, _user: NewUserAccountEntity) -> Option<UserAccountEntity> { | ||||
| #[async_trait::async_trait] | ||||
| pub trait EntityGateway: Send + Sync + Clone { | ||||
|     async fn create_user(&mut self, _user: NewUserAccountEntity) -> Option<UserAccountEntity> { | ||||
|         unimplemented!() | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_by_id(&self, _id: UserAccountId) -> Option<UserAccountEntity> { | ||||
|     async fn get_user_by_id(&self, _id: UserAccountId) -> Option<UserAccountEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_by_name(&self, _username: String) -> Option<UserAccountEntity> { | ||||
|     async fn get_user_by_name(&self, _username: String) -> Option<UserAccountEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn save_user(&mut self, _user: &UserAccountEntity) { | ||||
|     async fn save_user(&mut self, _user: &UserAccountEntity) { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn create_user_settings(&mut self, _settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> { | ||||
|     async fn create_user_settings(&mut self, _settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option<UserSettingsEntity> { | ||||
|     async fn get_user_settings_by_user(&self, _user: &UserAccountEntity) -> Option<UserSettingsEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
| @ -31,31 +32,31 @@ pub trait EntityGateway { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn create_character(&mut self, _char: NewCharacterEntity) -> Option<CharacterEntity> { | ||||
|     async fn create_character(&mut self, _char: NewCharacterEntity) -> Option<CharacterEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn get_characters_by_user(&self, _user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] { | ||||
|     async fn get_characters_by_user(&self, _user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn save_character(&mut self, _char: &CharacterEntity) { | ||||
|     async fn save_character(&mut self, _char: &CharacterEntity) { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity { | ||||
|     async fn get_guild_card_data_by_user(&self, _user: &UserAccountEntity) -> GuildCardDataEntity { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn create_item(&mut self, _item: NewItemEntity) -> Option<ItemEntity> { | ||||
|     async fn create_item(&mut self, _item: NewItemEntity) -> Option<ItemEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn save_item(&mut self, _item: &ItemEntity) { | ||||
|     async fn save_item(&mut self, _item: &ItemEntity) { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| 
 | ||||
|     fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec<ItemEntity> { | ||||
|     async fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec<ItemEntity> { | ||||
|         unimplemented!(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -26,8 +26,9 @@ impl InMemoryGateway { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| impl EntityGateway for InMemoryGateway { | ||||
|     fn create_user(&mut self, user: NewUserAccountEntity) -> Option<UserAccountEntity> { | ||||
|     async fn create_user(&mut self, user: NewUserAccountEntity) -> Option<UserAccountEntity> { | ||||
|         let mut users = self.users.lock().unwrap(); | ||||
|         let id = users | ||||
|             .iter() | ||||
| @ -48,12 +49,12 @@ impl EntityGateway for InMemoryGateway { | ||||
|         Some(user) | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_by_id(&self, id: UserAccountId) -> Option<UserAccountEntity> { | ||||
|     async fn get_user_by_id(&self, id: UserAccountId) -> Option<UserAccountEntity> { | ||||
|         let users = self.users.lock().unwrap(); | ||||
|         users.get(&id).map(|k| k.clone()) | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_by_name(&self, username: String) -> Option<UserAccountEntity> { | ||||
|     async fn get_user_by_name(&self, username: String) -> Option<UserAccountEntity> { | ||||
|         let users = self.users.lock().unwrap(); | ||||
|         users | ||||
|             .iter() | ||||
| @ -61,20 +62,12 @@ impl EntityGateway for InMemoryGateway { | ||||
|             .map(|(_, k)| k.clone()) | ||||
|     } | ||||
| 
 | ||||
|     fn save_user(&mut self, user: &UserAccountEntity) { | ||||
|     async fn save_user(&mut self, user: &UserAccountEntity) { | ||||
|         let mut users = self.users.lock().unwrap(); | ||||
|         users.insert(user.id, user.clone()); | ||||
|     } | ||||
| 
 | ||||
|     fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option<UserSettingsEntity> { | ||||
|         let user_settings = self.user_settings.lock().unwrap(); | ||||
|         user_settings | ||||
|             .iter() | ||||
|             .find(|(_, k)| k.user_id == user.id) | ||||
|             .map(|(_, k)| k.clone()) | ||||
|     } | ||||
| 
 | ||||
|     fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> { | ||||
|     async fn create_user_settings(&mut self, settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> { | ||||
|         let mut user_settings = self.user_settings.lock().unwrap(); | ||||
|         let id = user_settings | ||||
|             .iter() | ||||
| @ -89,7 +82,15 @@ impl EntityGateway for InMemoryGateway { | ||||
|         Some(new_settings) | ||||
|     } | ||||
| 
 | ||||
|     fn get_characters_by_user(&self, user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] { | ||||
|     async fn get_user_settings_by_user(&self, user: &UserAccountEntity) -> Option<UserSettingsEntity> { | ||||
|         let user_settings = self.user_settings.lock().unwrap(); | ||||
|         user_settings | ||||
|             .iter() | ||||
|             .find(|(_, k)| k.user_id == user.id) | ||||
|             .map(|(_, k)| k.clone()) | ||||
|     } | ||||
| 
 | ||||
|     async fn get_characters_by_user(&self, user: &UserAccountEntity) -> [Option<CharacterEntity>; 4] { | ||||
|         let characters = self.characters.lock().unwrap(); | ||||
|         let mut chars = [None; 4]; | ||||
|         characters | ||||
| @ -99,7 +100,7 @@ impl EntityGateway for InMemoryGateway { | ||||
|         chars | ||||
|     } | ||||
| 
 | ||||
|     fn create_character(&mut self, character: NewCharacterEntity) -> Option<CharacterEntity> { | ||||
|     async fn create_character(&mut self, character: NewCharacterEntity) -> Option<CharacterEntity> { | ||||
|         let mut characters = self.characters.lock().unwrap(); | ||||
|         let id = characters | ||||
|             .iter() | ||||
| @ -126,16 +127,16 @@ impl EntityGateway for InMemoryGateway { | ||||
|         Some(new_character) | ||||
|     } | ||||
| 
 | ||||
|     fn save_character(&mut self, char: &CharacterEntity) { | ||||
|     async fn save_character(&mut self, char: &CharacterEntity) { | ||||
|         let mut characters = self.characters.lock().unwrap(); | ||||
|         characters.insert(char.id, char.clone()); | ||||
|     } | ||||
| 
 | ||||
|     fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> GuildCardDataEntity { | ||||
|     async fn get_guild_card_data_by_user(&self, user: &UserAccountEntity) -> GuildCardDataEntity { | ||||
|         GuildCardDataEntity::new(user.id) | ||||
|     } | ||||
| 
 | ||||
|     fn create_item(&mut self, item: NewItemEntity) -> Option<ItemEntity> { | ||||
|     async fn create_item(&mut self, item: NewItemEntity) -> Option<ItemEntity> { | ||||
|         let mut items = self.items.lock().unwrap(); | ||||
|         let id = items | ||||
|             .iter() | ||||
| @ -150,12 +151,12 @@ impl EntityGateway for InMemoryGateway { | ||||
|         Some(new_item) | ||||
|     } | ||||
| 
 | ||||
|     fn save_item(&mut self, item: &ItemEntity) { | ||||
|     async fn save_item(&mut self, item: &ItemEntity) { | ||||
|         let mut items = self.items.lock().unwrap(); | ||||
|         items.insert(item.id, item.clone()); | ||||
|     } | ||||
| 
 | ||||
|     fn get_items_by_character(&self, character: &CharacterEntity) -> Vec<ItemEntity> { | ||||
|     async fn get_items_by_character(&self, character: &CharacterEntity) -> Vec<ItemEntity> { | ||||
|         let items = self.items.lock().unwrap(); | ||||
|         items | ||||
|             .iter() | ||||
|  | ||||
| @ -190,7 +190,7 @@ pub struct CharacterServerState<EG: EntityGateway> { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) { | ||||
| async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountEntity, preview: &CharacterPreview) { | ||||
|     //let mut character = entity_gateway.new_character_by_user(&user);
 | ||||
|     //new_character_from_preview(&mut char, preview);
 | ||||
|     let mut character = new_character_from_preview(user, preview); | ||||
| @ -201,7 +201,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
| 
 | ||||
|     character.meseta = 300; | ||||
| 
 | ||||
|     let character = entity_gateway.create_character(character).unwrap(); | ||||
|     let character = entity_gateway.create_character(character).await.unwrap(); | ||||
| 
 | ||||
|     let new_weapon = match character.char_class { | ||||
|         CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber, | ||||
| @ -224,7 +224,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
|                 character_id: character.id, | ||||
|                 slot: 0, | ||||
|                 equipped: true, | ||||
|             }}); | ||||
|             }}).await; | ||||
| 
 | ||||
|     entity_gateway.create_item( | ||||
|         NewItemEntity { | ||||
| @ -239,7 +239,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
|                 character_id: character.id, | ||||
|                 slot: 1, | ||||
|             equipped: true, | ||||
|             }}); | ||||
|             }}).await; | ||||
| 
 | ||||
|     entity_gateway.create_item( | ||||
|         NewItemEntity { | ||||
| @ -259,7 +259,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
|                 character_id: character.id, | ||||
|                 slot: 2, | ||||
|                 equipped: true, | ||||
|             }}); | ||||
|             }}).await; | ||||
| 
 | ||||
|     for _ in 0..4 { | ||||
|         entity_gateway.create_item( | ||||
| @ -272,7 +272,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
|                     character_id: character.id, | ||||
|                     slot: 3, | ||||
|                     equipped: false, | ||||
|                 }}); | ||||
|                 }}).await; | ||||
|         entity_gateway.create_item( | ||||
|             NewItemEntity { | ||||
|                 item: ItemDetail::Tool ( | ||||
| @ -283,7 +283,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE | ||||
|                     character_id: character.id, | ||||
|                     slot: 4, | ||||
|                     equipped: false, | ||||
|                 }}); | ||||
|                 }}).await; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -307,9 +307,9 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|     async fn validate_login(&mut self, id: ClientId, pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         Ok(match get_login_status(&self.entity_gateway, pkt) { | ||||
|         Ok(match get_login_status(&self.entity_gateway, pkt).await { | ||||
|             Ok(user) => { | ||||
|                 let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); | ||||
|                 response.guildcard = user.guildcard; | ||||
| @ -337,16 +337,16 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         ]) | ||||
|     } | ||||
| 
 | ||||
|     fn get_settings(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|     async fn get_settings(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         let user = client.user.as_ref().unwrap(); | ||||
| 
 | ||||
|         // TODO: this should error (data should be added on account creation, why did I copy this silly sylv logic?)
 | ||||
|         let settings = match self.entity_gateway.get_user_settings_by_user(&user) { | ||||
|         let settings = match self.entity_gateway.get_user_settings_by_user(&user).await { | ||||
|             Some(settings) => settings, | ||||
|             None => { | ||||
|                 let user_settings = NewUserSettingsEntity::new(user.id); | ||||
|                 self.entity_gateway.create_user_settings(user_settings).unwrap() | ||||
|                 self.entity_gateway.create_user_settings(user_settings).await.unwrap() | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
| @ -357,10 +357,10 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         Ok(vec![pkt]) | ||||
|     } | ||||
| 
 | ||||
|     fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|     async fn char_select(&mut self, id: ClientId, select: &CharSelect) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         if client.characters.is_none() { | ||||
|             client.characters = Some(self.entity_gateway.get_characters_by_user(client.user.as_ref().unwrap())); | ||||
|             client.characters = Some(self.entity_gateway.get_characters_by_user(client.user.as_ref().unwrap()).await); | ||||
|         } | ||||
| 
 | ||||
|         if select.reason == 0 { | ||||
| @ -403,9 +403,9 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         })] | ||||
|     } | ||||
| 
 | ||||
|     fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|     async fn guildcard_data_header(&mut self, id: ClientId) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         let guildcard_data = self.entity_gateway.get_guild_card_data_by_user(client.user.as_ref().unwrap()); | ||||
|         let guildcard_data = self.entity_gateway.get_guild_card_data_by_user(client.user.as_ref().unwrap()).await; | ||||
| 
 | ||||
|         let bytes = guildcard_data.guildcard.as_bytes(); | ||||
|         let mut crc = crc32::Digest::new(crc32::IEEE); | ||||
| @ -431,11 +431,11 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result<std::option::IntoIter<SendCharacterPacket>, CharacterError> { | ||||
|     async fn set_flag(&mut self, id: ClientId, setflag: &SetFlag) -> Result<std::option::IntoIter<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         let mut user = client.user.as_mut().unwrap(); | ||||
|         user.flags = setflag.flags; | ||||
|         self.entity_gateway.save_user(&user); | ||||
|         self.entity_gateway.save_user(&user).await; | ||||
|         Ok(None.into_iter()) | ||||
|     } | ||||
| 
 | ||||
| @ -460,11 +460,11 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
| 
 | ||||
| 
 | ||||
|     // TODO: move USERFLAGS over to SessionAction
 | ||||
|     fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|     async fn character_preview(&mut self, id: ClientId, preview: &CharacterPreview) -> Result<Vec<SendCharacterPacket>, CharacterError> { | ||||
|         let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?; | ||||
|         let mut user = client.user.as_mut().unwrap(); | ||||
|         if user.flags == USERFLAG_NEWCHAR { | ||||
|             new_character(&mut self.entity_gateway, &user, preview) | ||||
|             new_character(&mut self.entity_gateway, &user, preview).await | ||||
|         } | ||||
|         if user.flags == USERFLAG_DRESSINGROOM { | ||||
|             // TODO: dressing room stuff
 | ||||
| @ -473,7 +473,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|         client.session.action = SessionAction::SelectCharacter; | ||||
|         client.session.character_slot = preview.slot as u8; | ||||
|         user.flags = 0; | ||||
|         self.entity_gateway.save_user(&user); | ||||
|         self.entity_gateway.save_user(&user).await; | ||||
|         Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard, | ||||
|                                                                                  user.team_id.unwrap_or(1), | ||||
|                                                                                  client.session)), | ||||
| @ -495,6 +495,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { | ||||
|     type SendPacket = SendCharacterPacket; | ||||
|     type RecvPacket = RecvCharacterPacket; | ||||
| @ -516,7 +517,7 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { | ||||
|         ] | ||||
|     } | ||||
| 
 | ||||
|     fn handle(&mut self, id: ClientId, pkt: &RecvCharacterPacket) | ||||
|     async fn handle(&mut self, id: ClientId, pkt: &RecvCharacterPacket) | ||||
|               -> Result<Box<dyn Iterator<Item = (ClientId, SendCharacterPacket)> + Send>, CharacterError> { | ||||
|         Ok(match pkt { | ||||
|             RecvCharacterPacket::Login(login) => { | ||||
| @ -524,20 +525,20 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { | ||||
|                     Box::new(self.send_ship_list(id, login)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 } | ||||
|                 else { | ||||
|                     Box::new(self.validate_login(id, login)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                     Box::new(self.validate_login(id, login).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 } | ||||
|             }, | ||||
|             RecvCharacterPacket::RequestSettings(_req) => { | ||||
|                 Box::new(self.get_settings(id)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 Box::new(self.get_settings(id).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::CharSelect(sel) => { | ||||
|                 Box::new(self.char_select(id, sel)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 Box::new(self.char_select(id, sel).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::Checksum(_checksum) => { | ||||
|                 Box::new(self.validate_checksum().into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::GuildcardDataRequest(_request) => { | ||||
|                 Box::new(self.guildcard_data_header(id)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 Box::new(self.guildcard_data_header(id).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::GuildcardDataChunkRequest(request) => { | ||||
|                 Box::new(self.guildcard_data_chunk(id, request.chunk, request.again)?.into_iter().map(move |pkt| (id, pkt))) | ||||
| @ -546,13 +547,13 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { | ||||
|                 Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::SetFlag(flag) => { | ||||
|                 Box::new(self.set_flag(id, flag)?.map(move |pkt| (id, pkt))) | ||||
|                 Box::new(self.set_flag(id, flag).await?.map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::ParamDataChunkRequest(request) => { | ||||
|                 Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::CharacterPreview(preview) => { | ||||
|                 Box::new(self.character_preview(id, preview)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 Box::new(self.character_preview(id, preview).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvCharacterPacket::MenuSelect(menuselect) => { | ||||
|                 Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|  | ||||
| @ -56,10 +56,10 @@ impl SendServerPacket for SendLoginPacket { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pub fn get_login_status(entity_gateway: &impl EntityGateway, pkt: &Login) -> Result<UserAccountEntity, AccountStatus> { | ||||
| pub async fn get_login_status(entity_gateway: &impl EntityGateway, pkt: &Login) -> Result<UserAccountEntity, AccountStatus> { | ||||
|     let username = array_to_utf8(pkt.username).map_err(|_err| AccountStatus::Error)?; | ||||
|     let password = array_to_utf8(pkt.password).map_err(|_err| AccountStatus::Error)?; | ||||
|     let user = entity_gateway.get_user_by_name(username).ok_or(AccountStatus::InvalidUser)?; | ||||
|     let user = entity_gateway.get_user_by_name(username).await.ok_or(AccountStatus::InvalidUser)?; | ||||
|     let verified = bcrypt::verify(password, user.password.as_str()).map_err(|_err| AccountStatus::Error)?; | ||||
|     match verified { | ||||
|         true => if user.banned { | ||||
| @ -84,8 +84,8 @@ impl<EG: EntityGateway> LoginServerState<EG> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn validate_login(&mut self, pkt: &Login) -> Vec<SendLoginPacket> { | ||||
|         match get_login_status(&self.entity_gateway, pkt) { | ||||
|     async fn validate_login(&mut self, pkt: &Login) -> Vec<SendLoginPacket> { | ||||
|         match get_login_status(&self.entity_gateway, pkt).await { | ||||
|             Ok(_user) => { | ||||
|                 let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.session)); | ||||
|                 let ip = net::Ipv4Addr::new(127,0,0,1); | ||||
| @ -100,6 +100,7 @@ impl<EG: EntityGateway> LoginServerState<EG> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| impl<EG: EntityGateway> ServerState for LoginServerState<EG> { | ||||
|     type SendPacket = SendLoginPacket; | ||||
|     type RecvPacket = RecvLoginPacket; | ||||
| @ -119,11 +120,11 @@ impl<EG: EntityGateway> ServerState for LoginServerState<EG> { | ||||
|         ] | ||||
|     } | ||||
| 
 | ||||
|     fn handle(&mut self, id: ClientId, pkt: &Self::RecvPacket) | ||||
|     async fn handle(&mut self, id: ClientId, pkt: &Self::RecvPacket) | ||||
|               -> Result<Box<dyn Iterator<Item = (ClientId, Self::SendPacket)> + Send>, LoginError> { | ||||
|         Ok(match pkt { | ||||
|             RecvLoginPacket::Login(login) => { | ||||
|                 Box::new(self.validate_login(login) | ||||
|                 Box::new(self.validate_login(login).await | ||||
|                          .into_iter() | ||||
|                          .map(move |pkt| { | ||||
|                              (id, pkt) | ||||
|  | ||||
| @ -154,6 +154,7 @@ impl PatchServerState { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| impl ServerState for PatchServerState { | ||||
|     type SendPacket = SendPatchPacket; | ||||
|     type RecvPacket = RecvPatchPacket; | ||||
| @ -169,7 +170,7 @@ impl ServerState for PatchServerState { | ||||
|         ] | ||||
|     } | ||||
| 
 | ||||
|     fn handle(&mut self, id: ClientId, pkt: &RecvPatchPacket) | ||||
|     async fn handle(&mut self, id: ClientId, pkt: &RecvPatchPacket) | ||||
|               -> Result<Box<dyn Iterator<Item = (ClientId, SendPatchPacket)> + Send>, PatchError> { | ||||
|         Ok(match pkt { | ||||
|             RecvPatchPacket::PatchWelcomeReply(_pkt) => { | ||||
|  | ||||
| @ -91,6 +91,7 @@ pub enum ItemDropType { | ||||
|     Meseta(u32), | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct ItemDrop { | ||||
|     pub map_area: MapArea, | ||||
|     pub x: f32, | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| use std::collections::{HashMap, BTreeMap}; | ||||
| use libpso::character::character;//::InventoryItem;
 | ||||
| use thiserror::Error; | ||||
| use futures::future::join_all; | ||||
| use libpso::character::character;//::InventoryItem;
 | ||||
| use crate::entity::gateway::EntityGateway; | ||||
| use crate::entity::character::{CharacterEntity, CharacterEntityId}; | ||||
| use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, ItemLocation}; | ||||
| @ -189,8 +190,8 @@ impl ItemManager { | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Result
 | ||||
|     pub fn load_character<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) { | ||||
|         let items = entity_gateway.get_items_by_character(&character); | ||||
|     pub async fn load_character<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) { | ||||
|         let items = entity_gateway.get_items_by_character(&character).await; | ||||
|         let inventory_items = items.into_iter() | ||||
|             .filter_map(|item| { | ||||
|                 match item.location { | ||||
| @ -289,7 +290,7 @@ impl ItemManager { | ||||
|             .map(Clone::clone) | ||||
|     } | ||||
| 
 | ||||
|     pub fn character_picks_up_item<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, floor_item: FloorItem) -> Result<TriggerCreateItem, ItemManagerError> { | ||||
|     pub async fn character_picks_up_item<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &mut CharacterEntity, floor_item: FloorItem) -> Result<TriggerCreateItem, ItemManagerError> { | ||||
|         let local_floor = self.character_floor.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; | ||||
|         let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; | ||||
|         let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; | ||||
| @ -356,7 +357,7 @@ impl ItemManager { | ||||
|                             slot: inventory.len(), | ||||
|                             equipped: false, | ||||
|                         }, | ||||
|                     }); // TODO: error check
 | ||||
|                     }).await; // TODO: error check
 | ||||
|                     inventory.push(inventory_item); | ||||
|                 } // else something went very wrong TODO: log it
 | ||||
|                 TriggerCreateItem::Yes | ||||
| @ -411,14 +412,14 @@ impl ItemManager { | ||||
|                                 slot: inventory.len(), | ||||
|                                 equipped: false, | ||||
|                             }, | ||||
|                         }); // TODO: error check
 | ||||
|                         }).await; // TODO: error check
 | ||||
|                     }; | ||||
|                 } // else something went very wrong TODO: log it
 | ||||
|                 trigger_create | ||||
|             }, | ||||
|             FloorItemType::Meseta(meseta) => { | ||||
|                 character.meseta = std::cmp::min(character.meseta + meseta.0, 999999); | ||||
|                 entity_gateway.save_character(&character); | ||||
|                 entity_gateway.save_character(&character).await; | ||||
|                 TriggerCreateItem::No | ||||
|             } | ||||
|         }; | ||||
| @ -426,7 +427,7 @@ impl ItemManager { | ||||
|         Ok(trigger_create) | ||||
|     } | ||||
| 
 | ||||
|     pub fn enemy_drop_item_on_local_floor<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity, item_drop: ItemDrop) -> Result<&FloorItem, ItemManagerError> { | ||||
|     pub async fn enemy_drop_item_on_local_floor<EG: EntityGateway>(&mut self, entity_gateway: &mut EG, character: &CharacterEntity, item_drop: ItemDrop) -> Result<&FloorItem, ItemManagerError> { | ||||
|         let item = match item_drop.item { | ||||
|             ItemDropType::Weapon(w) => FloorItemType::Individual(ItemDetail::Weapon(w)), | ||||
|             ItemDropType::Armor(w) => FloorItemType::Individual(ItemDetail::Armor(w)), | ||||
| @ -440,6 +441,8 @@ impl ItemManager { | ||||
|             ItemDropType::Meseta(m) => FloorItemType::Meseta(Meseta(m)) | ||||
|         }; | ||||
| 
 | ||||
| 
 | ||||
|         //let eg = Arc::new(Mutex::new(entity_gateway.clone()))
 | ||||
|         let entity_id = match &item { | ||||
|             FloorItemType::Individual(i) => { | ||||
|                 let entity = entity_gateway.create_item(NewItemEntity { | ||||
| @ -451,26 +454,37 @@ impl ItemManager { | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     } | ||||
|                 }).ok_or(ItemManagerError::EntityGatewayError)?; | ||||
|                 }).await.ok_or(ItemManagerError::EntityGatewayError)?; | ||||
|                 ActiveItemEntityId::Individual(entity.id) | ||||
|             }, | ||||
|             FloorItemType::Stacked(tool, count) => { | ||||
|                 let entities = (0..*count).map(|_| { | ||||
|                     entity_gateway.create_item(NewItemEntity { | ||||
|                         item: ItemDetail::Tool(*tool), | ||||
|                         location: ItemLocation::LocalFloor { | ||||
|                             character_id: character.id, | ||||
|                             map_area: item_drop.map_area, | ||||
|                             x: item_drop.x, | ||||
|                             y: item_drop.y, | ||||
|                             z: item_drop.z, | ||||
|                         } | ||||
|                     })}) | ||||
|                 let entities = (0..*count) | ||||
|                     .map(|_| { | ||||
|                         let mut eg = entity_gateway.clone(); | ||||
|                         let item_drop = item_drop.clone(); | ||||
|                         async move { | ||||
|                             eg.create_item(NewItemEntity { | ||||
|                                 item: ItemDetail::Tool(*tool), | ||||
|                                 location: ItemLocation::LocalFloor { | ||||
|                                     character_id: character.id, | ||||
|                                     map_area: item_drop.map_area, | ||||
|                                     x: item_drop.x, | ||||
|                                     y: item_drop.y, | ||||
|                                     z: item_drop.z, | ||||
|                                 } | ||||
|                             }).await | ||||
|                         }}); | ||||
|                 let entities = join_all(entities).await.into_iter() | ||||
|                     .map(|entity| -> Result<ItemEntityId, ItemManagerError> { | ||||
|                         let e = entity.ok_or(ItemManagerError::EntityGatewayError)?; | ||||
|                         // I am not able to manually specify a closure return type when also using the async keyword
 | ||||
|                         Ok(e.id) | ||||
|                         //let result: Result<ItemEntityId, ItemManagerError> = Ok(e.id);
 | ||||
|                         //result
 | ||||
|                     }); | ||||
|                 //ActiveItemEntityId::Stacked(join_all(entities).await.into_iter().collect::<Result<Vec<_>, _>>()?)
 | ||||
|                 ActiveItemEntityId::Stacked(entities.collect::<Result<Vec<_>, _>>()?) | ||||
|                 //ActiveItemEntityId::Stacked(entities.collect().await?)
 | ||||
|             }, | ||||
|             FloorItemType::Meseta(m) => ActiveItemEntityId::Meseta(m.clone()), | ||||
|         }; | ||||
| @ -492,7 +506,7 @@ impl ItemManager { | ||||
|         self.character_floor.get(&character.id).ok_or(ItemManagerError::Idunnoman)?.last().ok_or(ItemManagerError::Idunnoman) | ||||
|     } | ||||
| 
 | ||||
|     pub fn player_drop_item_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|     pub async fn player_drop_item_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|                                                                entity_gateway: &mut EG, | ||||
|                                                                character: &CharacterEntity, | ||||
|                                                                inventory_item: InventoryItem, | ||||
| @ -532,7 +546,7 @@ impl ItemManager { | ||||
|                             y: item_drop_location.2, | ||||
|                             z: item_drop_location.3, | ||||
|                         } | ||||
|                     }); // TODO: error check
 | ||||
|                     }).await; // TODO: error check
 | ||||
|                 } // else something went very wrong: TODO: log it 
 | ||||
|             }, | ||||
|             FloorItemType::Stacked(tool, _count) => { | ||||
| @ -547,7 +561,7 @@ impl ItemManager { | ||||
|                                 y: item_drop_location.2, | ||||
|                                 z: item_drop_location.3, | ||||
|                             }, | ||||
|                         }); // TODO: error check
 | ||||
|                         }).await; // TODO: error check
 | ||||
|                     } | ||||
|                 } // else something went very wrong TODO: log it
 | ||||
|             }, | ||||
| @ -558,7 +572,7 @@ impl ItemManager { | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn player_drops_meseta_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|     pub async fn player_drops_meseta_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|                                                                   entity_gateway: &mut EG, | ||||
|                                                                   character: &mut CharacterEntity, | ||||
|                                                                   drop_location: ItemDropLocation, | ||||
| @ -570,7 +584,7 @@ impl ItemManager { | ||||
|             return Err(ItemManagerError::CouldNotDropMeseta) | ||||
|         } | ||||
|         character.meseta -= amount; | ||||
|         entity_gateway.save_character(&character); | ||||
|         entity_gateway.save_character(&character).await; | ||||
| 
 | ||||
|         let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); | ||||
|         let floor_item = FloorItem { | ||||
| @ -587,7 +601,7 @@ impl ItemManager { | ||||
|         Ok(floor_item) | ||||
|     } | ||||
| 
 | ||||
|     pub fn player_drops_partial_stack_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|     pub async fn player_drops_partial_stack_on_shared_floor<EG: EntityGateway>(&mut self, | ||||
|                                                                          entity_gateway: &mut EG, | ||||
|                                                                          character: &CharacterEntity, | ||||
|                                                                          inventory_item: InventoryItem, | ||||
| @ -611,9 +625,26 @@ impl ItemManager { | ||||
| 
 | ||||
|             let dropped_entities = entity_ids.drain(..amount).collect::<Vec<_>>(); | ||||
| 
 | ||||
|             dropped_entities.iter().for_each(|entity_id| { | ||||
|             /* | ||||
|             dropped_entities.iter().map(|entity_id| { | ||||
|                 let mut eg = entity_gateway.clone(); | ||||
|                 let tool = tool.clone(); | ||||
|                 async move { | ||||
|                     eg.save_item(&ItemEntity { | ||||
|                         id: *entity_id, | ||||
|                         item: ItemDetail::Tool(tool), | ||||
|                         location: ItemLocation::SharedFloor { | ||||
|                             map_area: drop_location.map_area, | ||||
|                             x: drop_location.x, | ||||
|                             y: 0.0, | ||||
|                             z: drop_location.z, | ||||
|                         } | ||||
|                     }).await | ||||
|                 }}).await; | ||||
|             */ | ||||
|             for de in dropped_entities.iter() { | ||||
|                 entity_gateway.save_item(&ItemEntity { | ||||
|                     id: *entity_id, | ||||
|                     id: *de, | ||||
|                     item: ItemDetail::Tool(*tool), | ||||
|                     location: ItemLocation::SharedFloor { | ||||
|                         map_area: drop_location.map_area, | ||||
| @ -621,8 +652,8 @@ impl ItemManager { | ||||
|                         y: 0.0, | ||||
|                         z: drop_location.z, | ||||
|                     } | ||||
|                 }) | ||||
|             }); | ||||
|                 }).await | ||||
|             } | ||||
| 
 | ||||
|             let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); | ||||
|             let floor_item = FloorItem { | ||||
|  | ||||
| @ -6,28 +6,28 @@ use crate::login::login::get_login_status; | ||||
| use crate::entity::gateway::EntityGateway; | ||||
| use crate::ship::items::ItemManager; | ||||
| 
 | ||||
| pub fn validate_login<EG: EntityGateway>(id: ClientId, | ||||
| pub async fn validate_login<EG: EntityGateway>(id: ClientId, | ||||
|                                          pkt: &Login, | ||||
|                                          entity_gateway: &mut EG, | ||||
|                                          clients: &mut Clients, | ||||
|                                          item_manager: &mut ItemManager, | ||||
|                                          ship_name: &String) | ||||
|                                          -> Result<Vec<SendShipPacket>, ShipError> { | ||||
|     Ok(match get_login_status(entity_gateway, pkt) { | ||||
|     Ok(match get_login_status(entity_gateway, pkt).await { | ||||
|         Ok(user) => { | ||||
|             let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); | ||||
|             response.guildcard = user.id.0 as u32; | ||||
|             response.team_id = user.team_id.map_or(31, |ti| ti) as u32; | ||||
|             let characters = entity_gateway.get_characters_by_user(&user); | ||||
|             let characters = entity_gateway.get_characters_by_user(&user).await; | ||||
|             let character = characters | ||||
|                 .get(pkt.session.character_slot as usize) | ||||
|                 .ok_or(ShipError::InvalidSlot(id, pkt.session.character_slot as u32))?.as_ref() | ||||
|                 .ok_or(ShipError::NoCharacterInSlot(id, pkt.session.character_slot as u32))? | ||||
|                 .clone(); | ||||
|             let settings = entity_gateway.get_user_settings_by_user(&user) | ||||
|             let settings = entity_gateway.get_user_settings_by_user(&user).await | ||||
|                 .ok_or(ShipError::ClientNotFound(id))?; | ||||
| 
 | ||||
|             item_manager.load_character(entity_gateway, &character); | ||||
|             item_manager.load_character(entity_gateway, &character).await; | ||||
|             clients.insert(id, ClientState::new(user, settings, character, pkt.session)); | ||||
|             vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))] | ||||
|         }, | ||||
|  | ||||
| @ -35,13 +35,13 @@ pub fn request_infoboard(id: ClientId, | ||||
|     Box::new(vec![(id, SendShipPacket::ViewInfoboardResponse(ViewInfoboardResponse {response: r}))].into_iter()) | ||||
| } | ||||
| 
 | ||||
| pub fn write_infoboard<EG: EntityGateway>(id: ClientId, | ||||
| pub async fn write_infoboard<EG: EntityGateway>(id: ClientId, | ||||
|                                           new_infoboard: &WriteInfoboard, | ||||
|                                           clients: &mut Clients, | ||||
|                                           entity_gateway: &mut EG) | ||||
|                        -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { | ||||
|     let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); | ||||
|     client.character.info_board.update_infoboard(new_infoboard); | ||||
|     entity_gateway.save_character(&client.character); | ||||
|     entity_gateway.save_character(&client.character).await; | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
|  | ||||
| @ -44,14 +44,14 @@ pub fn guildcard_send(id: ClientId, | ||||
|     send_to_client(id, target as u8, msg, &client_location) | ||||
| } | ||||
| 
 | ||||
| pub fn request_item<EG>(id: ClientId, | ||||
|                         request_item: &RequestItem, | ||||
|                         entity_gateway: &mut EG, | ||||
|                         client_location: &ClientLocation, | ||||
|                         clients: &mut Clients, | ||||
|                         rooms: &mut Rooms, | ||||
|                         item_manager: &mut ItemManager) | ||||
|                         -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| pub async fn request_item<EG>(id: ClientId, | ||||
|                               request_item: &RequestItem, | ||||
|                               entity_gateway: &mut EG, | ||||
|                               client_location: &ClientLocation, | ||||
|                               clients: &mut Clients, | ||||
|                               rooms: &mut Rooms, | ||||
|                               item_manager: &mut ItemManager) | ||||
|                               -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| where | ||||
|     EG: EntityGateway | ||||
| { | ||||
| @ -68,6 +68,7 @@ where | ||||
| 
 | ||||
|     let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||
| 
 | ||||
|     /* | ||||
|     let item_drop_packets = clients_in_area.into_iter() | ||||
|         .filter_map(|area_client| { | ||||
|             room.drop_table.get_drop(&monster.map_area, &monster.monster).map(|item_drop_type| { | ||||
| @ -75,7 +76,7 @@ where | ||||
|                 (area_client, item_drop_type) | ||||
|             }) | ||||
|         }) | ||||
|         .map(|(area_client, item_drop_type)| -> Result<_, ShipError> { | ||||
|         .map(|(area_client, item_drop_type)| async { | ||||
|             let item_drop = ItemDrop { | ||||
|                 map_area: monster.map_area, | ||||
|                 x: request_item.x, | ||||
| @ -84,26 +85,62 @@ where | ||||
|                 item: item_drop_type, | ||||
|             }; | ||||
|             let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|             let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).unwrap(); // TODO: unwrap
 | ||||
|             let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await.unwrap(); // TODO: unwrap
 | ||||
|             let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; | ||||
|             Ok((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) | ||||
| 
 | ||||
|             // I am not able to manually specify a closure return type when also using the async keyword
 | ||||
|             let result: Result<(ClientId, SendShipPacket), ShipError> = Ok((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); | ||||
|             result | ||||
|         }) | ||||
|         .map(|item_drop_pkt| async { | ||||
|             item_drop_pkt.await | ||||
|         }); | ||||
| 
 | ||||
|     let item_drop_packets = join_all(item_drop_packets).await.into_iter() | ||||
|         .filter_map(|item_drop_pkt| { | ||||
|             // TODO: log errors here
 | ||||
|             item_drop_pkt.ok() | ||||
|         }) | ||||
|         .collect::<Vec<_>>(); // TODO: can EntityGateway be Sync?
 | ||||
|         }); | ||||
| 
 | ||||
|         //.collect::<Vec<_>>(); // TODO: can EntityGateway be Sync?
 | ||||
| 
 | ||||
|     Ok(Box::new(item_drop_packets)) | ||||
|      */ | ||||
| 
 | ||||
|     let client_and_drop = clients_in_area.into_iter() | ||||
|         .filter_map(|area_client| { | ||||
|             room.drop_table.get_drop(&monster.map_area, &monster.monster).map(|item_drop_type| { | ||||
|                 warn!("drop is? {:?}", item_drop_type); | ||||
|                 (area_client, item_drop_type) | ||||
|             }) | ||||
|         }); | ||||
| 
 | ||||
|     let mut item_drop_packets = Vec::new(); | ||||
|     for (area_client, item_drop) in client_and_drop { | ||||
|         let item_drop = ItemDrop { | ||||
|             map_area: monster.map_area, | ||||
|             x: request_item.x, | ||||
|             y: request_item.y, | ||||
|             z: request_item.z, | ||||
|             item: item_drop, | ||||
|         }; | ||||
|         let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|         let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await.unwrap(); // TODO: unwrap
 | ||||
|         let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; | ||||
| 
 | ||||
|         item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); | ||||
|     } | ||||
| 
 | ||||
|     Ok(Box::new(item_drop_packets.into_iter())) | ||||
| } | ||||
| 
 | ||||
| pub fn pickup_item<EG>(id: ClientId, | ||||
|                        pickup_item: &PickupItem, | ||||
|                        entity_gateway: &mut EG, | ||||
|                        client_location: &ClientLocation, | ||||
|                        clients: &mut Clients, | ||||
|                        item_manager: &mut ItemManager) | ||||
|                        -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| pub async fn pickup_item<EG>(id: ClientId, | ||||
|                              pickup_item: &PickupItem, | ||||
|                              entity_gateway: &mut EG, | ||||
|                              client_location: &ClientLocation, | ||||
|                              clients: &mut Clients, | ||||
|                              item_manager: &mut ItemManager) | ||||
|                              -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| where | ||||
|     EG: EntityGateway | ||||
| { | ||||
| @ -118,7 +155,7 @@ where | ||||
|         _ => Some(builder::message::create_item(area_client, &item)?), | ||||
|     }; | ||||
| 
 | ||||
|     match item_manager.character_picks_up_item(entity_gateway, &mut client.character, item) { | ||||
|     match item_manager.character_picks_up_item(entity_gateway, &mut client.character, item).await { | ||||
|         Ok(trigger_create_item) => { | ||||
|             Ok(Box::new(Vec::new().into_iter() | ||||
|                         .chain(clients_in_area.clone().into_iter() | ||||
| @ -142,7 +179,7 @@ where | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn request_box_item<EG>(id: ClientId, | ||||
| pub async fn request_box_item<EG>(id: ClientId, | ||||
|     box_drop_request: &BoxDropRequest, | ||||
|     entity_gateway: &mut EG, | ||||
|     client_location: &ClientLocation, | ||||
| @ -166,14 +203,14 @@ EG: EntityGateway | ||||
| 
 | ||||
|     let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||
| 
 | ||||
|     let item_drop_packets = clients_in_area.into_iter() | ||||
|     /*let item_drop_packets = clients_in_area.into_iter()
 | ||||
|         .filter_map(|area_client| { | ||||
|             room.drop_table.get_box_drop(&box_object.map, &box_object).map(|item_drop_type| { | ||||
|                 warn!("drop is? {:?}", item_drop_type); | ||||
|                 (area_client, item_drop_type) | ||||
|             }) | ||||
|         }) | ||||
|         .map(|(area_client, item_drop_type)| -> Result<_, ShipError> { | ||||
|         .map(async move |(area_client, item_drop_type)| -> Result<_, ShipError> { | ||||
|             let item_drop = ItemDrop { | ||||
|                 map_area: box_object.map, | ||||
|                 x: box_drop_request.x, | ||||
| @ -182,15 +219,47 @@ EG: EntityGateway | ||||
|                 item: item_drop_type, | ||||
|             }; | ||||
|             let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|             let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).unwrap(); // TODO: unwrap
 | ||||
|             let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await.unwrap(); // TODO: unwrap
 | ||||
|             let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; | ||||
|             Ok((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) | ||||
|         }) | ||||
|         .filter_map(|item_drop_pkt| { | ||||
|         /*.filter_map(|item_drop_pkt| {
 | ||||
|             // TODO: log errors here
 | ||||
|             item_drop_pkt.ok() | ||||
|         }) | ||||
|         .collect::<Vec<_>>(); // TODO: can EntityGateway be Sync?
 | ||||
|         .collect::<Vec<_>>(); // TODO: can EntityGateway be Sync?*/
 | ||||
|         ; | ||||
|     let item_drop_packets = join_all(item_drop_packets).await.into_iter() | ||||
|         .filter_map(|item_drop_pkt| { | ||||
|             // TODO: log errors here
 | ||||
|             item_drop_pkt.ok() | ||||
|         }); | ||||
| 
 | ||||
|     Ok(Box::new(item_drop_packets)) | ||||
|     */ | ||||
| 
 | ||||
|     let client_and_drop = clients_in_area.into_iter() | ||||
|         .filter_map(|area_client| { | ||||
|             room.drop_table.get_box_drop(&box_object.map, &box_object).map(|item_drop_type| { | ||||
|                 warn!("drop is? {:?}", item_drop_type); | ||||
|                 (area_client, item_drop_type) | ||||
|             }) | ||||
|         }); | ||||
| 
 | ||||
|     let mut item_drop_packets = Vec::new(); | ||||
|     for (area_client, item_drop) in client_and_drop { | ||||
|         let item_drop = ItemDrop { | ||||
|             map_area: box_object.map, | ||||
|             x: box_drop_request.x, | ||||
|             y: 0.0, | ||||
|             z: box_drop_request.z, | ||||
|             item: item_drop, | ||||
|         }; | ||||
|         let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|         let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?; // TODO: unwrap
 | ||||
|         let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; | ||||
|         item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) | ||||
|     } | ||||
| 
 | ||||
|     Ok(Box::new(item_drop_packets.into_iter())) | ||||
| } | ||||
|  | ||||
| @ -60,7 +60,7 @@ pub fn send_player_to_lobby(id: ClientId, | ||||
|               .map(|c| (c.client, SendShipPacket::AddToLobby(addto.clone())))).collect()) | ||||
| } | ||||
| 
 | ||||
| pub fn change_lobby<EG: EntityGateway>(id: ClientId, | ||||
| pub async fn change_lobby<EG: EntityGateway>(id: ClientId, | ||||
|                     requested_lobby: u32, | ||||
|                     client_location: &mut ClientLocation, | ||||
|                     clients: &Clients, | ||||
| @ -98,7 +98,7 @@ pub fn change_lobby<EG: EntityGateway>(id: ClientId, | ||||
|                 } | ||||
|             } | ||||
|     } | ||||
|     item_manager.load_character(entity_gateway, &client.character); | ||||
|     item_manager.load_character(entity_gateway, &client.character).await; | ||||
|     let join_lobby = packet::builder::lobby::join_lobby(id, lobby, client_location, clients, item_manager, level_table)?; | ||||
|     let addto = packet::builder::lobby::add_to_lobby(id, lobby, client_location, clients, item_manager, level_table)?; | ||||
|     let neighbors = client_location.get_client_neighbors(id).unwrap(); | ||||
|  | ||||
| @ -25,7 +25,7 @@ pub fn request_exp(id: ClientId, | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
| 
 | ||||
| pub fn player_drop_item<EG>(id: ClientId, | ||||
| pub async fn player_drop_item<EG>(id: ClientId, | ||||
|                             player_drop_item: &PlayerDropItem, | ||||
|                             entity_gateway: &mut EG, | ||||
|                             client_location: &ClientLocation, | ||||
| @ -44,7 +44,7 @@ where | ||||
|         .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; | ||||
|     let area = MapArea::from_value(&room.mode.episode(), player_drop_item.area as u32)?; | ||||
|     let item = item_manager.get_inventory_item_by_id(&client.character, ClientItemId(player_drop_item.item_id))?; | ||||
|     item_manager.player_drop_item_on_shared_floor(entity_gateway, &client.character, item, (area, player_drop_item.x, player_drop_item.y, player_drop_item.z))?; | ||||
|     item_manager.player_drop_item_on_shared_floor(entity_gateway, &client.character, item, (area, player_drop_item.x, player_drop_item.y, player_drop_item.z)).await?; | ||||
|     let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||
|     let pdi = player_drop_item.clone(); | ||||
|     Ok(Box::new(clients_in_area.into_iter() | ||||
| @ -77,13 +77,13 @@ pub fn drop_coordinates(id: ClientId, | ||||
|     Ok(Box::new(None.into_iter())) | ||||
| } | ||||
| 
 | ||||
| pub fn split_item_stack<EG>(id: ClientId, | ||||
|                             split_item_stack: &PlayerSplitItemStack, | ||||
|                             entity_gateway: &mut EG, | ||||
|                             client_location: &ClientLocation, | ||||
|                             clients: &mut Clients, | ||||
|                             item_manager: &mut ItemManager) | ||||
|                             -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| pub async fn split_item_stack<EG>(id: ClientId, | ||||
|                                   split_item_stack: &PlayerSplitItemStack, | ||||
|                                   entity_gateway: &mut EG, | ||||
|                                   client_location: &ClientLocation, | ||||
|                                   clients: &mut Clients, | ||||
|                                   item_manager: &mut ItemManager) | ||||
|                                   -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> | ||||
| where | ||||
|     EG: EntityGateway | ||||
| { | ||||
| @ -97,7 +97,7 @@ where | ||||
|     } | ||||
| 
 | ||||
|     if split_item_stack.item_id == 0xFFFFFFFF { | ||||
|         let dropped_meseta = item_manager.player_drops_meseta_on_shared_floor(entity_gateway, &mut client.character, drop_location, split_item_stack.amount as u32)?; | ||||
|         let dropped_meseta = item_manager.player_drops_meseta_on_shared_floor(entity_gateway, &mut client.character, drop_location, split_item_stack.amount as u32).await?; | ||||
| 
 | ||||
|         let dropped_meseta_pkt = builder::message::drop_split_stack(area_client, &dropped_meseta)?; | ||||
|         client.item_drop_location = None; | ||||
| @ -110,7 +110,7 @@ where | ||||
|     } | ||||
|     else { | ||||
|         let item_to_split = item_manager.get_inventory_item_by_id(&client.character, drop_location.item_id)?; | ||||
|         let dropped_item = item_manager.player_drops_partial_stack_on_shared_floor(entity_gateway, &client.character, item_to_split, drop_location, split_item_stack.amount as usize)?; | ||||
|         let dropped_item = item_manager.player_drops_partial_stack_on_shared_floor(entity_gateway, &client.character, item_to_split, drop_location, split_item_stack.amount as usize).await?; | ||||
| 
 | ||||
|         let dropped_item_pkt = builder::message::drop_split_stack(area_client, &dropped_item)?; | ||||
|         client.item_drop_location = None; | ||||
|  | ||||
| @ -3,13 +3,13 @@ use crate::common::serverstate::ClientId; | ||||
| use crate::ship::ship::{SendShipPacket, ShipError, Clients}; | ||||
| use crate::entity::gateway::EntityGateway; | ||||
| 
 | ||||
| pub fn update_config<EG: EntityGateway>(id: ClientId, | ||||
| pub async fn update_config<EG: EntityGateway>(id: ClientId, | ||||
|                                         update_config: &UpdateConfig, | ||||
|                                         clients: &mut Clients, | ||||
|                                         entity_gateway: &mut EG) | ||||
|                                         -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { | ||||
|     let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); | ||||
|     client.character.config.update(update_config); | ||||
|     entity_gateway.save_character(&client.character); | ||||
|     entity_gateway.save_character(&client.character).await; | ||||
|     Box::new(None.into_iter()) | ||||
| } | ||||
|  | ||||
| @ -261,19 +261,19 @@ impl<EG: EntityGateway> ShipServerState<EG> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn message(&mut self, id: ClientId, msg: &Message) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||
|     async fn message(&mut self, id: ClientId, msg: &Message) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||
|         match &msg.msg { | ||||
|             GameMessage::RequestExp(request_exp) => { | ||||
|                 Ok(handler::message::request_exp(id, request_exp, &self.client_location, &self.rooms)) | ||||
|             }, | ||||
|             GameMessage::PlayerDropItem(player_drop_item) => { | ||||
|                 handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager) | ||||
|                 handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager).await | ||||
|             }, | ||||
|             GameMessage::DropCoordinates(drop_coordinates) => { | ||||
|                 handler::message::drop_coordinates(id, drop_coordinates, &self.client_location, &mut self.clients, &self.rooms) | ||||
|             }, | ||||
|             GameMessage::PlayerSplitItemStack(split_item_stack) => { | ||||
|                 handler::message::split_item_stack(id, split_item_stack, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager) | ||||
|                 handler::message::split_item_stack(id, split_item_stack, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager).await | ||||
|             }, | ||||
|             _ => { | ||||
|                 let cmsg = msg.clone(); | ||||
| @ -285,20 +285,20 @@ impl<EG: EntityGateway> ShipServerState<EG> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn direct_message(&mut self, id: ClientId, msg: &DirectMessage) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||
|     async fn direct_message(&mut self, id: ClientId, msg: &DirectMessage) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||
|         let target = msg.flag; | ||||
|         match &msg.msg { | ||||
|             GameMessage::GuildcardSend(guildcard_send) => { | ||||
|                 Ok(handler::direct_message::guildcard_send(id, guildcard_send, target, &self.client_location, &self.clients)) | ||||
|             }, | ||||
|             GameMessage::RequestItem(request_item) => { | ||||
|                 handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager) | ||||
|                 handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager).await | ||||
|             }, | ||||
|             GameMessage::PickupItem(pickup_item) => { | ||||
|                 handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager) | ||||
|                 handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager).await | ||||
|             }, | ||||
|             GameMessage::BoxDropRequest(box_drop_request) => { | ||||
|                 handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager) | ||||
|                 handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager).await | ||||
|             } | ||||
|             _ => { | ||||
|                 let cmsg = msg.clone(); | ||||
| @ -312,6 +312,7 @@ impl<EG: EntityGateway> ShipServerState<EG> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[async_trait::async_trait] | ||||
| impl<EG: EntityGateway> ServerState for ShipServerState<EG> { | ||||
|     type SendPacket = SendShipPacket; | ||||
|     type RecvPacket = RecvShipPacket; | ||||
| @ -331,11 +332,11 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> { | ||||
|         ] | ||||
|     } | ||||
| 
 | ||||
|     fn handle(&mut self, id: ClientId, pkt: &RecvShipPacket) | ||||
|     async fn handle(&mut self, id: ClientId, pkt: &RecvShipPacket) | ||||
|               -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||
|         Ok(match pkt { | ||||
|             RecvShipPacket::Login(login) => { | ||||
|                 Box::new(handler::auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager, &self.name)?.into_iter().map(move |pkt| (id, pkt))) | ||||
|                 Box::new(handler::auth::validate_login(id, login, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager, &self.name).await?.into_iter().map(move |pkt| (id, pkt))) | ||||
|             }, | ||||
|             RecvShipPacket::QuestDetailRequest(questdetailrequest) => { | ||||
|                 match questdetailrequest.menu { | ||||
| @ -375,10 +376,10 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> { | ||||
|                 Box::new(handler::lobby::send_player_to_lobby(id, chardata, &mut self.client_location, &self.clients, &self.item_manager, &self.level_table)?.into_iter()) | ||||
|             }, | ||||
|             RecvShipPacket::Message(msg) => { | ||||
|                 self.message(id, msg)? | ||||
|                 self.message(id, msg).await? | ||||
|             }, | ||||
|             RecvShipPacket::DirectMessage(msg) => { | ||||
|                 self.direct_message(id, msg)? | ||||
|                 self.direct_message(id, msg).await? | ||||
|             }, | ||||
|             RecvShipPacket::PlayerChat(msg) => { | ||||
|                 Box::new(handler::communication::player_chat(id, msg, &self.client_location, &self.clients)?.into_iter()) | ||||
| @ -390,13 +391,13 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> { | ||||
|                 handler::room::room_name_request(id, &self.client_location, &self.rooms) | ||||
|             }, | ||||
|             RecvShipPacket::UpdateConfig(pkt) => { | ||||
|                 handler::settings::update_config(id, pkt, &mut self.clients, &mut self.entity_gateway) | ||||
|                 handler::settings::update_config(id, pkt, &mut self.clients, &mut self.entity_gateway).await | ||||
|             }, | ||||
|             RecvShipPacket::ViewInfoboardRequest(_pkt) => { | ||||
|                 handler::communication::request_infoboard(id, &self.client_location, &self.clients) | ||||
|             }, | ||||
|             RecvShipPacket::WriteInfoboard(pkt) => { | ||||
|                 handler::communication::write_infoboard(id, pkt, &mut self.clients, &mut self.entity_gateway) | ||||
|                 handler::communication::write_infoboard(id, pkt, &mut self.clients, &mut self.entity_gateway).await | ||||
|             }, | ||||
|             RecvShipPacket::RoomListRequest(_req) => { | ||||
|                 handler::room::request_room_list(id, &self.client_location, &self.rooms) | ||||
| @ -415,7 +416,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> { | ||||
|                 handler::room::done_bursting(id, &self.client_location, &mut self.rooms) | ||||
|             }, | ||||
|             RecvShipPacket::LobbySelect(pkt) => { | ||||
|                 Box::new(handler::lobby::change_lobby(id, pkt.lobby, &mut self.client_location, &self.clients, &mut self.item_manager, &self.level_table, &mut self.rooms, &mut self.entity_gateway)?.into_iter()) | ||||
|                 Box::new(handler::lobby::change_lobby(id, pkt.lobby, &mut self.client_location, &self.clients, &mut self.item_manager, &self.level_table, &mut self.rooms, &mut self.entity_gateway).await?.into_iter()) | ||||
|             }, | ||||
|             RecvShipPacket::RequestQuestList(_) => { | ||||
|                 handler::quest::send_quest_category_list(id, &self.quests)? | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user