Browse Source

async EntityGateway

pbs
jake 4 years ago
parent
commit
8d49c50cc5
  1. 3
      Cargo.toml
  2. 85
      src/bin/main.rs
  3. 2
      src/common/mainloop.rs
  4. 9
      src/common/serverstate.rs
  5. 29
      src/entity/gateway/entitygateway.rs
  6. 41
      src/entity/gateway/inmemory.rs
  7. 57
      src/login/character.rs
  8. 13
      src/login/login.rs
  9. 3
      src/patch/patch.rs
  10. 1
      src/ship/drops/mod.rs
  11. 91
      src/ship/items.rs
  12. 10
      src/ship/packet/handler/auth.rs
  13. 4
      src/ship/packet/handler/communication.rs
  14. 123
      src/ship/packet/handler/direct_message.rs
  15. 4
      src/ship/packet/handler/lobby.rs
  16. 22
      src/ship/packet/handler/message.rs
  17. 4
      src/ship/packet/handler/settings.rs
  18. 29
      src/ship/ship.rs

3
Cargo.toml

@ -7,7 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
libpso = { git = "http://git.sharnoth.com/jake/libpso" } libpso = { git = "http://git.sharnoth.com/jake/libpso" }
async-std = { version = "1.5.0", features = ["unstable"] } async-std = { version = "1.5.0", features = ["unstable"] }
futures = "0.3.4"
futures = "0.3.5"
rand = "0.7.3" rand = "0.7.3"
rand_chacha = "0.2.2" rand_chacha = "0.2.2"
mio = "0.6" mio = "0.6"
@ -27,4 +27,5 @@ enum-utils = "0.1.2"
derive_more = { version = "0.99.3", features = ["display"]} derive_more = { version = "0.99.3", features = ["display"]}
thiserror = "1.0.15" thiserror = "1.0.15"
ages-prs = "0.1" ages-prs = "0.1"
async-trait = "0.1.31"

85
src/bin/main.rs

@ -44,52 +44,53 @@ fn setup_logger() {
fn main() { fn main() {
setup_logger(); setup_logger();
let mut entity_gateway = InMemoryGateway::new();
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).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();
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: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
None,],
tekked: true,
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,
} }
),
location: ItemLocation::Inventory {
character_id: character.id,
slot: 0,
equipped: true,
}
});
}
}).await;
}
async_std::task::block_on(async move {
let patch = async_std::task::spawn(async { let patch = async_std::task::spawn(async {
info!("[patch] starting server"); info!("[patch] starting server");
let patch_config = load_config(); let patch_config = load_config();

2
src/common/mainloop.rs

@ -165,7 +165,7 @@ async fn server_state_loop<STATE, S, R, E>(mut state: STATE,
} }
}, },
ClientAction::Packet(client_id, pkt) => { ClientAction::Packet(client_id, pkt) => {
let pkts = state.handle(client_id, &pkt);
let pkts = state.handle(client_id, &pkt).await;
match pkts { match pkts {
Ok(pkts) => { Ok(pkts) => {
for (client_id, pkt) in pkts { for (client_id, pkt) in pkts {

9
src/common/serverstate.rs

@ -9,22 +9,23 @@ pub enum OnConnect<S: SendServerPacket> {
Cipher((Box<dyn PSOCipher + Send + Sync>, Box<dyn PSOCipher + Send + Sync>)), 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>; fn from_bytes(data: &[u8]) -> Result<Self, PacketParseError>;
} }
pub trait SendServerPacket: Sized {
pub trait SendServerPacket: Sized + Sync {
fn as_bytes(&self) -> Vec<u8>; fn as_bytes(&self) -> Vec<u8>;
} }
#[async_trait::async_trait]
pub trait ServerState { pub trait ServerState {
type SendPacket: SendServerPacket; type SendPacket: SendServerPacket;
type RecvPacket: RecvServerPacket; type RecvPacket: RecvServerPacket;
type PacketError; type PacketError;
fn on_connect(&mut self, id: ClientId) -> Vec<OnConnect<Self::SendPacket>>; 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)>; fn on_disconnect(&mut self, id: ClientId) -> Vec<(ClientId, Self::SendPacket)>;
} }

29
src/entity/gateway/entitygateway.rs

@ -2,28 +2,29 @@ use crate::entity::account::*;
use crate::entity::character::*; use crate::entity::character::*;
use crate::entity::item::*; 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!() unimplemented!()
} }
fn get_user_by_id(&self, _id: UserAccountId) -> Option<UserAccountEntity> {
async fn get_user_by_id(&self, _id: UserAccountId) -> Option<UserAccountEntity> {
unimplemented!(); unimplemented!();
} }
fn get_user_by_name(&self, _username: String) -> Option<UserAccountEntity> {
async fn get_user_by_name(&self, _username: String) -> Option<UserAccountEntity> {
unimplemented!(); unimplemented!();
} }
fn save_user(&mut self, _user: &UserAccountEntity) {
async fn save_user(&mut self, _user: &UserAccountEntity) {
unimplemented!(); unimplemented!();
} }
fn create_user_settings(&mut self, _settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> {
async fn create_user_settings(&mut self, _settings: NewUserSettingsEntity) -> Option<UserSettingsEntity> {
unimplemented!(); 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!(); unimplemented!();
} }
@ -31,31 +32,31 @@ pub trait EntityGateway {
unimplemented!(); unimplemented!();
} }
fn create_character(&mut self, _char: NewCharacterEntity) -> Option<CharacterEntity> {
async fn create_character(&mut self, _char: NewCharacterEntity) -> Option<CharacterEntity> {
unimplemented!(); 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!(); unimplemented!();
} }
fn save_character(&mut self, _char: &CharacterEntity) {
async fn save_character(&mut self, _char: &CharacterEntity) {
unimplemented!(); 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!(); unimplemented!();
} }
fn create_item(&mut self, _item: NewItemEntity) -> Option<ItemEntity> {
async fn create_item(&mut self, _item: NewItemEntity) -> Option<ItemEntity> {
unimplemented!(); unimplemented!();
} }
fn save_item(&mut self, _item: &ItemEntity) {
async fn save_item(&mut self, _item: &ItemEntity) {
unimplemented!(); unimplemented!();
} }
fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec<ItemEntity> {
async fn get_items_by_character(&self, _char: &CharacterEntity) -> Vec<ItemEntity> {
unimplemented!(); unimplemented!();
} }
} }

41
src/entity/gateway/inmemory.rs

@ -26,8 +26,9 @@ impl InMemoryGateway {
} }
} }
#[async_trait::async_trait]
impl EntityGateway for InMemoryGateway { 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 mut users = self.users.lock().unwrap();
let id = users let id = users
.iter() .iter()
@ -48,12 +49,12 @@ impl EntityGateway for InMemoryGateway {
Some(user) 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(); let users = self.users.lock().unwrap();
users.get(&id).map(|k| k.clone()) 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(); let users = self.users.lock().unwrap();
users users
.iter() .iter()
@ -61,20 +62,12 @@ impl EntityGateway for InMemoryGateway {
.map(|(_, k)| k.clone()) .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(); let mut users = self.users.lock().unwrap();
users.insert(user.id, user.clone()); 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 mut user_settings = self.user_settings.lock().unwrap();
let id = user_settings let id = user_settings
.iter() .iter()
@ -89,7 +82,15 @@ impl EntityGateway for InMemoryGateway {
Some(new_settings) 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 characters = self.characters.lock().unwrap();
let mut chars = [None; 4]; let mut chars = [None; 4];
characters characters
@ -99,7 +100,7 @@ impl EntityGateway for InMemoryGateway {
chars 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 mut characters = self.characters.lock().unwrap();
let id = characters let id = characters
.iter() .iter()
@ -126,16 +127,16 @@ impl EntityGateway for InMemoryGateway {
Some(new_character) 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(); let mut characters = self.characters.lock().unwrap();
characters.insert(char.id, char.clone()); 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) 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 mut items = self.items.lock().unwrap();
let id = items let id = items
.iter() .iter()
@ -150,12 +151,12 @@ impl EntityGateway for InMemoryGateway {
Some(new_item) 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(); let mut items = self.items.lock().unwrap();
items.insert(item.id, item.clone()); 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(); let items = self.items.lock().unwrap();
items items
.iter() .iter()

57
src/login/character.rs

@ -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); //let mut character = entity_gateway.new_character_by_user(&user);
//new_character_from_preview(&mut char, preview); //new_character_from_preview(&mut char, preview);
let mut character = new_character_from_preview(user, 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; 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 { let new_weapon = match character.char_class {
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber, 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, character_id: character.id,
slot: 0, slot: 0,
equipped: true, equipped: true,
}});
}}).await;
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
@ -239,7 +239,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE
character_id: character.id, character_id: character.id,
slot: 1, slot: 1,
equipped: true, equipped: true,
}});
}}).await;
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
@ -259,7 +259,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE
character_id: character.id, character_id: character.id,
slot: 2, slot: 2,
equipped: true, equipped: true,
}});
}}).await;
for _ in 0..4 { for _ in 0..4 {
entity_gateway.create_item( entity_gateway.create_item(
@ -272,7 +272,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE
character_id: character.id, character_id: character.id,
slot: 3, slot: 3,
equipped: false, equipped: false,
}});
}}).await;
entity_gateway.create_item( entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Tool ( item: ItemDetail::Tool (
@ -283,7 +283,7 @@ fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAccountE
character_id: character.id, character_id: character.id,
slot: 4, slot: 4,
equipped: false, 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))?; 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) => { Ok(user) => {
let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new());
response.guildcard = user.guildcard; 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 client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
let user = client.user.as_ref().unwrap(); 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?) // 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, Some(settings) => settings,
None => { None => {
let user_settings = NewUserSettingsEntity::new(user.id); 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]) 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))?; let client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
if client.characters.is_none() { 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 { 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 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 bytes = guildcard_data.guildcard.as_bytes();
let mut crc = crc32::Digest::new(crc32::IEEE); 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 client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap(); let mut user = client.user.as_mut().unwrap();
user.flags = setflag.flags; user.flags = setflag.flags;
self.entity_gateway.save_user(&user);
self.entity_gateway.save_user(&user).await;
Ok(None.into_iter()) Ok(None.into_iter())
} }
@ -460,11 +460,11 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
// TODO: move USERFLAGS over to SessionAction // 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 client = self.clients.get_mut(&id).ok_or(CharacterError::ClientNotFound(id))?;
let mut user = client.user.as_mut().unwrap(); let mut user = client.user.as_mut().unwrap();
if user.flags == USERFLAG_NEWCHAR { 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 { if user.flags == USERFLAG_DRESSINGROOM {
// TODO: dressing room stuff // TODO: dressing room stuff
@ -473,7 +473,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
client.session.action = SessionAction::SelectCharacter; client.session.action = SessionAction::SelectCharacter;
client.session.character_slot = preview.slot as u8; client.session.character_slot = preview.slot as u8;
user.flags = 0; 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, Ok(vec![SendCharacterPacket::LoginResponse(LoginResponse::by_char_select(user.guildcard,
user.team_id.unwrap_or(1), user.team_id.unwrap_or(1),
client.session)), client.session)),
@ -495,6 +495,7 @@ impl<EG: EntityGateway> CharacterServerState<EG> {
} }
} }
#[async_trait::async_trait]
impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { impl<EG: EntityGateway> ServerState for CharacterServerState<EG> {
type SendPacket = SendCharacterPacket; type SendPacket = SendCharacterPacket;
type RecvPacket = RecvCharacterPacket; 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> { -> Result<Box<dyn Iterator<Item = (ClientId, SendCharacterPacket)> + Send>, CharacterError> {
Ok(match pkt { Ok(match pkt {
RecvCharacterPacket::Login(login) => { 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))) Box::new(self.send_ship_list(id, login)?.into_iter().map(move |pkt| (id, pkt)))
} }
else { 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) => { 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) => { 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) => { RecvCharacterPacket::Checksum(_checksum) => {
Box::new(self.validate_checksum().into_iter().map(move |pkt| (id, pkt))) Box::new(self.validate_checksum().into_iter().map(move |pkt| (id, pkt)))
}, },
RecvCharacterPacket::GuildcardDataRequest(_request) => { 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) => { RecvCharacterPacket::GuildcardDataChunkRequest(request) => {
Box::new(self.guildcard_data_chunk(id, request.chunk, request.again)?.into_iter().map(move |pkt| (id, pkt))) 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))) Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt)))
}, },
RecvCharacterPacket::SetFlag(flag) => { 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) => { RecvCharacterPacket::ParamDataChunkRequest(request) => {
Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt))) Box::new(self.param_data_chunk_request(id, request)?.into_iter().map(move |pkt| (id, pkt)))
}, },
RecvCharacterPacket::CharacterPreview(preview) => { 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) => { RecvCharacterPacket::MenuSelect(menuselect) => {
Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt))) Box::new(self.select_ship(menuselect)?.into_iter().map(move |pkt| (id, pkt)))

13
src/login/login.rs

@ -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 username = array_to_utf8(pkt.username).map_err(|_err| AccountStatus::Error)?;
let password = array_to_utf8(pkt.password).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)?; let verified = bcrypt::verify(password, user.password.as_str()).map_err(|_err| AccountStatus::Error)?;
match verified { match verified {
true => if user.banned { 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) => { Ok(_user) => {
let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.session)); let response = SendLoginPacket::LoginResponse(LoginResponse::by_status(AccountStatus::Ok, pkt.session));
let ip = net::Ipv4Addr::new(127,0,0,1); 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> { impl<EG: EntityGateway> ServerState for LoginServerState<EG> {
type SendPacket = SendLoginPacket; type SendPacket = SendLoginPacket;
type RecvPacket = RecvLoginPacket; 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> { -> Result<Box<dyn Iterator<Item = (ClientId, Self::SendPacket)> + Send>, LoginError> {
Ok(match pkt { Ok(match pkt {
RecvLoginPacket::Login(login) => { RecvLoginPacket::Login(login) => {
Box::new(self.validate_login(login)
Box::new(self.validate_login(login).await
.into_iter() .into_iter()
.map(move |pkt| { .map(move |pkt| {
(id, pkt) (id, pkt)

3
src/patch/patch.rs

@ -154,6 +154,7 @@ impl PatchServerState {
} }
} }
#[async_trait::async_trait]
impl ServerState for PatchServerState { impl ServerState for PatchServerState {
type SendPacket = SendPatchPacket; type SendPacket = SendPatchPacket;
type RecvPacket = RecvPatchPacket; 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> { -> Result<Box<dyn Iterator<Item = (ClientId, SendPatchPacket)> + Send>, PatchError> {
Ok(match pkt { Ok(match pkt {
RecvPatchPacket::PatchWelcomeReply(_pkt) => { RecvPatchPacket::PatchWelcomeReply(_pkt) => {

1
src/ship/drops/mod.rs

@ -91,6 +91,7 @@ pub enum ItemDropType {
Meseta(u32), Meseta(u32),
} }
#[derive(Clone, Debug)]
pub struct ItemDrop { pub struct ItemDrop {
pub map_area: MapArea, pub map_area: MapArea,
pub x: f32, pub x: f32,

91
src/ship/items.rs

@ -1,6 +1,7 @@
use std::collections::{HashMap, BTreeMap}; use std::collections::{HashMap, BTreeMap};
use libpso::character::character;//::InventoryItem;
use thiserror::Error; use thiserror::Error;
use futures::future::join_all;
use libpso::character::character;//::InventoryItem;
use crate::entity::gateway::EntityGateway; use crate::entity::gateway::EntityGateway;
use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::character::{CharacterEntity, CharacterEntityId};
use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, ItemLocation}; use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, ItemLocation};
@ -189,8 +190,8 @@ impl ItemManager {
} }
// TODO: Result // 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() let inventory_items = items.into_iter()
.filter_map(|item| { .filter_map(|item| {
match item.location { match item.location {
@ -289,7 +290,7 @@ impl ItemManager {
.map(Clone::clone) .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 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 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))?; let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
@ -356,7 +357,7 @@ impl ItemManager {
slot: inventory.len(), slot: inventory.len(),
equipped: false, equipped: false,
}, },
}); // TODO: error check
}).await; // TODO: error check
inventory.push(inventory_item); inventory.push(inventory_item);
} // else something went very wrong TODO: log it } // else something went very wrong TODO: log it
TriggerCreateItem::Yes TriggerCreateItem::Yes
@ -411,14 +412,14 @@ impl ItemManager {
slot: inventory.len(), slot: inventory.len(),
equipped: false, equipped: false,
}, },
}); // TODO: error check
}).await; // TODO: error check
}; };
} // else something went very wrong TODO: log it } // else something went very wrong TODO: log it
trigger_create trigger_create
}, },
FloorItemType::Meseta(meseta) => { FloorItemType::Meseta(meseta) => {
character.meseta = std::cmp::min(character.meseta + meseta.0, 999999); character.meseta = std::cmp::min(character.meseta + meseta.0, 999999);
entity_gateway.save_character(&character);
entity_gateway.save_character(&character).await;
TriggerCreateItem::No TriggerCreateItem::No
} }
}; };
@ -426,7 +427,7 @@ impl ItemManager {
Ok(trigger_create) 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 { let item = match item_drop.item {
ItemDropType::Weapon(w) => FloorItemType::Individual(ItemDetail::Weapon(w)), ItemDropType::Weapon(w) => FloorItemType::Individual(ItemDetail::Weapon(w)),
ItemDropType::Armor(w) => FloorItemType::Individual(ItemDetail::Armor(w)), ItemDropType::Armor(w) => FloorItemType::Individual(ItemDetail::Armor(w)),
@ -440,6 +441,8 @@ impl ItemManager {
ItemDropType::Meseta(m) => FloorItemType::Meseta(Meseta(m)) ItemDropType::Meseta(m) => FloorItemType::Meseta(Meseta(m))
}; };
//let eg = Arc::new(Mutex::new(entity_gateway.clone()))
let entity_id = match &item { let entity_id = match &item {
FloorItemType::Individual(i) => { FloorItemType::Individual(i) => {
let entity = entity_gateway.create_item(NewItemEntity { let entity = entity_gateway.create_item(NewItemEntity {
@ -451,26 +454,37 @@ impl ItemManager {
y: item_drop.y, y: item_drop.y,
z: item_drop.z, z: item_drop.z,
} }
}).ok_or(ItemManagerError::EntityGatewayError)?;
}).await.ok_or(ItemManagerError::EntityGatewayError)?;
ActiveItemEntityId::Individual(entity.id) ActiveItemEntityId::Individual(entity.id)
}, },
FloorItemType::Stacked(tool, count) => { 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> { .map(|entity| -> Result<ItemEntityId, ItemManagerError> {
let e = entity.ok_or(ItemManagerError::EntityGatewayError)?; 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) 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::<Result<Vec<_>, _>>()?)
//ActiveItemEntityId::Stacked(entities.collect().await?)
}, },
FloorItemType::Meseta(m) => ActiveItemEntityId::Meseta(m.clone()), 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) 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, entity_gateway: &mut EG,
character: &CharacterEntity, character: &CharacterEntity,
inventory_item: InventoryItem, inventory_item: InventoryItem,
@ -532,7 +546,7 @@ impl ItemManager {
y: item_drop_location.2, y: item_drop_location.2,
z: item_drop_location.3, z: item_drop_location.3,
} }
}); // TODO: error check
}).await; // TODO: error check
} // else something went very wrong: TODO: log it } // else something went very wrong: TODO: log it
}, },
FloorItemType::Stacked(tool, _count) => { FloorItemType::Stacked(tool, _count) => {
@ -547,7 +561,7 @@ impl ItemManager {
y: item_drop_location.2, y: item_drop_location.2,
z: item_drop_location.3, z: item_drop_location.3,
}, },
}); // TODO: error check
}).await; // TODO: error check
} }
} // else something went very wrong TODO: log it } // else something went very wrong TODO: log it
}, },
@ -558,7 +572,7 @@ impl ItemManager {
Ok(()) 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, entity_gateway: &mut EG,
character: &mut CharacterEntity, character: &mut CharacterEntity,
drop_location: ItemDropLocation, drop_location: ItemDropLocation,
@ -570,7 +584,7 @@ impl ItemManager {
return Err(ItemManagerError::CouldNotDropMeseta) return Err(ItemManagerError::CouldNotDropMeseta)
} }
character.meseta -= amount; 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 item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?();
let floor_item = FloorItem { let floor_item = FloorItem {
@ -587,7 +601,7 @@ impl ItemManager {
Ok(floor_item) 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, entity_gateway: &mut EG,
character: &CharacterEntity, character: &CharacterEntity,
inventory_item: InventoryItem, inventory_item: InventoryItem,
@ -611,9 +625,26 @@ impl ItemManager {
let dropped_entities = entity_ids.drain(..amount).collect::<Vec<_>>(); 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 { entity_gateway.save_item(&ItemEntity {
id: *entity_id,
id: *de,
item: ItemDetail::Tool(*tool), item: ItemDetail::Tool(*tool),
location: ItemLocation::SharedFloor { location: ItemLocation::SharedFloor {
map_area: drop_location.map_area, map_area: drop_location.map_area,
@ -621,8 +652,8 @@ impl ItemManager {
y: 0.0, y: 0.0,
z: drop_location.z, z: drop_location.z,
} }
})
});
}).await
}
let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?(); let item_id = self.room_item_id_counter.get_mut(room_id).ok_or(ItemManagerError::NoCharacter(character.id))?();
let floor_item = FloorItem { let floor_item = FloorItem {

10
src/ship/packet/handler/auth.rs

@ -6,28 +6,28 @@ use crate::login::login::get_login_status;
use crate::entity::gateway::EntityGateway; use crate::entity::gateway::EntityGateway;
use crate::ship::items::ItemManager; use crate::ship::items::ItemManager;
pub fn validate_login<EG: EntityGateway>(id: ClientId,
pub async fn validate_login<EG: EntityGateway>(id: ClientId,
pkt: &Login, pkt: &Login,
entity_gateway: &mut EG, entity_gateway: &mut EG,
clients: &mut Clients, clients: &mut Clients,
item_manager: &mut ItemManager, item_manager: &mut ItemManager,
ship_name: &String) ship_name: &String)
-> Result<Vec<SendShipPacket>, ShipError> { -> Result<Vec<SendShipPacket>, ShipError> {
Ok(match get_login_status(entity_gateway, pkt) {
Ok(match get_login_status(entity_gateway, pkt).await {
Ok(user) => { Ok(user) => {
let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new()); let mut response = LoginResponse::by_status(AccountStatus::Ok, Session::new());
response.guildcard = user.id.0 as u32; response.guildcard = user.id.0 as u32;
response.team_id = user.team_id.map_or(31, |ti| ti) 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 let character = characters
.get(pkt.session.character_slot as usize) .get(pkt.session.character_slot as usize)
.ok_or(ShipError::InvalidSlot(id, pkt.session.character_slot as u32))?.as_ref() .ok_or(ShipError::InvalidSlot(id, pkt.session.character_slot as u32))?.as_ref()
.ok_or(ShipError::NoCharacterInSlot(id, pkt.session.character_slot as u32))? .ok_or(ShipError::NoCharacterInSlot(id, pkt.session.character_slot as u32))?
.clone(); .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))?; .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)); clients.insert(id, ClientState::new(user, settings, character, pkt.session));
vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))] vec![SendShipPacket::LoginResponse(response), SendShipPacket::ShipBlockList(ShipBlockList::new(&&ship_name, 3))]
}, },

4
src/ship/packet/handler/communication.rs

@ -35,13 +35,13 @@ pub fn request_infoboard(id: ClientId,
Box::new(vec![(id, SendShipPacket::ViewInfoboardResponse(ViewInfoboardResponse {response: r}))].into_iter()) 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, new_infoboard: &WriteInfoboard,
clients: &mut Clients, clients: &mut Clients,
entity_gateway: &mut EG) entity_gateway: &mut EG)
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
client.character.info_board.update_infoboard(new_infoboard); 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()) Box::new(None.into_iter())
} }

123
src/ship/packet/handler/direct_message.rs

@ -44,14 +44,14 @@ pub fn guildcard_send(id: ClientId,
send_to_client(id, target as u8, msg, &client_location) 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 where
EG: EntityGateway 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 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| { .filter_map(|area_client| {
room.drop_table.get_drop(&monster.map_area, &monster.monster).map(|item_drop_type| { room.drop_table.get_drop(&monster.map_area, &monster.monster).map(|item_drop_type| {
@ -75,7 +76,7 @@ where
(area_client, item_drop_type) (area_client, item_drop_type)
}) })
}) })
.map(|(area_client, item_drop_type)| -> Result<_, ShipError> {
.map(|(area_client, item_drop_type)| async {
let item_drop = ItemDrop { let item_drop = ItemDrop {
map_area: monster.map_area, map_area: monster.map_area,
x: request_item.x, x: request_item.x,
@ -84,26 +85,62 @@ where
item: item_drop_type, item: item_drop_type,
}; };
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; 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)?; 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| { .filter_map(|item_drop_pkt| {
// TODO: log errors here // TODO: log errors here
item_drop_pkt.ok() 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())) 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 where
EG: EntityGateway EG: EntityGateway
{ {
@ -118,7 +155,7 @@ where
_ => Some(builder::message::create_item(area_client, &item)?), _ => 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(trigger_create_item) => {
Ok(Box::new(Vec::new().into_iter() Ok(Box::new(Vec::new().into_iter()
.chain(clients_in_area.clone().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, box_drop_request: &BoxDropRequest,
entity_gateway: &mut EG, entity_gateway: &mut EG,
client_location: &ClientLocation, 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 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| { .filter_map(|area_client| {
room.drop_table.get_box_drop(&box_object.map, &box_object).map(|item_drop_type| { room.drop_table.get_box_drop(&box_object.map, &box_object).map(|item_drop_type| {
warn!("drop is? {:?}", item_drop_type); warn!("drop is? {:?}", item_drop_type);
(area_client, 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 { let item_drop = ItemDrop {
map_area: box_object.map, map_area: box_object.map,
x: box_drop_request.x, x: box_drop_request.x,
@ -182,15 +219,47 @@ EG: EntityGateway
item: item_drop_type, item: item_drop_type,
}; };
let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; 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)?; 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))))) 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 // TODO: log errors here
item_drop_pkt.ok() 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())) Ok(Box::new(item_drop_packets.into_iter()))
} }

4
src/ship/packet/handler/lobby.rs

@ -60,7 +60,7 @@ pub fn send_player_to_lobby(id: ClientId,
.map(|c| (c.client, SendShipPacket::AddToLobby(addto.clone())))).collect()) .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, requested_lobby: u32,
client_location: &mut ClientLocation, client_location: &mut ClientLocation,
clients: &Clients, 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 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 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(); let neighbors = client_location.get_client_neighbors(id).unwrap();

22
src/ship/packet/handler/message.rs

@ -25,7 +25,7 @@ pub fn request_exp(id: ClientId,
Box::new(None.into_iter()) 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, player_drop_item: &PlayerDropItem,
entity_gateway: &mut EG, entity_gateway: &mut EG,
client_location: &ClientLocation, client_location: &ClientLocation,
@ -44,7 +44,7 @@ where
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; .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 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))?; 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 clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?;
let pdi = player_drop_item.clone(); let pdi = player_drop_item.clone();
Ok(Box::new(clients_in_area.into_iter() Ok(Box::new(clients_in_area.into_iter()
@ -77,13 +77,13 @@ pub fn drop_coordinates(id: ClientId,
Ok(Box::new(None.into_iter())) 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 where
EG: EntityGateway EG: EntityGateway
{ {
@ -97,7 +97,7 @@ where
} }
if split_item_stack.item_id == 0xFFFFFFFF { 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)?; let dropped_meseta_pkt = builder::message::drop_split_stack(area_client, &dropped_meseta)?;
client.item_drop_location = None; client.item_drop_location = None;
@ -110,7 +110,7 @@ where
} }
else { else {
let item_to_split = item_manager.get_inventory_item_by_id(&client.character, drop_location.item_id)?; 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)?; let dropped_item_pkt = builder::message::drop_split_stack(area_client, &dropped_item)?;
client.item_drop_location = None; client.item_drop_location = None;

4
src/ship/packet/handler/settings.rs

@ -3,13 +3,13 @@ use crate::common::serverstate::ClientId;
use crate::ship::ship::{SendShipPacket, ShipError, Clients}; use crate::ship::ship::{SendShipPacket, ShipError, Clients};
use crate::entity::gateway::EntityGateway; 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, update_config: &UpdateConfig,
clients: &mut Clients, clients: &mut Clients,
entity_gateway: &mut EG) entity_gateway: &mut EG)
-> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> {
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap(); let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id)).unwrap();
client.character.config.update(update_config); client.character.config.update(update_config);
entity_gateway.save_character(&client.character);
entity_gateway.save_character(&client.character).await;
Box::new(None.into_iter()) Box::new(None.into_iter())
} }

29
src/ship/ship.rs

@ -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 { match &msg.msg {
GameMessage::RequestExp(request_exp) => { GameMessage::RequestExp(request_exp) => {
Ok(handler::message::request_exp(id, request_exp, &self.client_location, &self.rooms)) Ok(handler::message::request_exp(id, request_exp, &self.client_location, &self.rooms))
}, },
GameMessage::PlayerDropItem(player_drop_item) => { 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) => { GameMessage::DropCoordinates(drop_coordinates) => {
handler::message::drop_coordinates(id, drop_coordinates, &self.client_location, &mut self.clients, &self.rooms) handler::message::drop_coordinates(id, drop_coordinates, &self.client_location, &mut self.clients, &self.rooms)
}, },
GameMessage::PlayerSplitItemStack(split_item_stack) => { 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(); 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; let target = msg.flag;
match &msg.msg { match &msg.msg {
GameMessage::GuildcardSend(guildcard_send) => { GameMessage::GuildcardSend(guildcard_send) => {
Ok(handler::direct_message::guildcard_send(id, guildcard_send, target, &self.client_location, &self.clients)) Ok(handler::direct_message::guildcard_send(id, guildcard_send, target, &self.client_location, &self.clients))
}, },
GameMessage::RequestItem(request_item) => { 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) => { 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) => { 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(); let cmsg = msg.clone();
@ -312,6 +312,7 @@ impl<EG: EntityGateway> ShipServerState<EG> {
} }
} }
#[async_trait::async_trait]
impl<EG: EntityGateway> ServerState for ShipServerState<EG> { impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
type SendPacket = SendShipPacket; type SendPacket = SendShipPacket;
type RecvPacket = RecvShipPacket; 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> { -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> {
Ok(match pkt { Ok(match pkt {
RecvShipPacket::Login(login) => { 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) => { RecvShipPacket::QuestDetailRequest(questdetailrequest) => {
match questdetailrequest.menu { 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()) 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) => { RecvShipPacket::Message(msg) => {
self.message(id, msg)?
self.message(id, msg).await?
}, },
RecvShipPacket::DirectMessage(msg) => { RecvShipPacket::DirectMessage(msg) => {
self.direct_message(id, msg)?
self.direct_message(id, msg).await?
}, },
RecvShipPacket::PlayerChat(msg) => { RecvShipPacket::PlayerChat(msg) => {
Box::new(handler::communication::player_chat(id, msg, &self.client_location, &self.clients)?.into_iter()) 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) handler::room::room_name_request(id, &self.client_location, &self.rooms)
}, },
RecvShipPacket::UpdateConfig(pkt) => { 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) => { RecvShipPacket::ViewInfoboardRequest(_pkt) => {
handler::communication::request_infoboard(id, &self.client_location, &self.clients) handler::communication::request_infoboard(id, &self.client_location, &self.clients)
}, },
RecvShipPacket::WriteInfoboard(pkt) => { 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) => { RecvShipPacket::RoomListRequest(_req) => {
handler::room::request_room_list(id, &self.client_location, &self.rooms) 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) handler::room::done_bursting(id, &self.client_location, &mut self.rooms)
}, },
RecvShipPacket::LobbySelect(pkt) => { 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(_) => { RecvShipPacket::RequestQuestList(_) => {
handler::quest::send_quest_category_list(id, &self.quests)? handler::quest::send_quest_category_list(id, &self.quests)?

Loading…
Cancel
Save