2023-01-28 20:12:20 -07:00

94 lines
3.9 KiB
Rust

use libpso::packet::ship::*;
use crate::common::serverstate::ClientId;
use crate::ship::ship::{Clients, ShipEvent};
use crate::ship::location::{ClientLocation, LobbyId, ClientLocationError};
use crate::ship::packet::builder::{player_info};
use crate::ship::items::state::ItemState;
use futures::future::join_all;
pub async fn join_lobby(id: ClientId,
lobby: LobbyId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &ItemState,
event: ShipEvent)
-> Result<JoinLobby, anyhow::Error> {
let lobby_clients = client_location.get_clients_in_lobby(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?;
let playerinfo = join_all(
lobby_clients.into_iter()
.map(|area_client| {
let item_state = item_state.clone();
async move {
clients.with(area_client.client, |client| Box::pin(async move {
let inventory = item_state.get_character_inventory(&client.character).await?;
Ok(player_info(0x100, client, &area_client, &inventory).await)
})).await?
}}))
.await
.into_iter()
.collect::<Result<Vec<_>, anyhow::Error>>()?;
let client_block = clients.with(id, |client| Box::pin(async move {
client.block as u16
})).await?;
let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let leader = client_location.get_lobby_leader(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?;
Ok(JoinLobby {
client: area_client.local_client.id(),
leader: leader.local_client.id(),
one: 1,
lobby: lobby.id(),
block: client_block,
event: event.into(),
padding: 0,
playerinfo,
})
}
pub async fn add_to_lobby(id: ClientId,
lobby: LobbyId,
client_location: &ClientLocation,
clients: &Clients,
item_state: &ItemState,
event: ShipEvent)
-> Result<AddToLobby, anyhow::Error> {
let area_client = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?;
let leader = client_location.get_lobby_leader(lobby).await.map_err(|err| -> ClientLocationError { err.into() })?;
clients.with(id, |client| {
let item_state = item_state.clone();
Box::pin(async move {
let inventory = item_state.get_character_inventory(&client.character).await?;
Ok(AddToLobby {
flag: 1,
client: area_client.local_client.id(),
leader: leader.local_client.id(),
one: 1,
lobby: lobby.id(),
block: client.block as u16,
event: event.into(),
padding: 0,
playerinfo: player_info(0x100, client, &area_client, &inventory).await,
})
})}).await?
}
pub async fn remove_from_lobby(id: ClientId,
client_location: &ClientLocation)
-> Result<LeaveLobby, anyhow::Error> {
let prev_area_index = client_location.get_local_client(id).await.map_err(|err| -> ClientLocationError { err.into() })?.local_client.id();
let prev_area_leader_index = client_location
.get_area_leader(client_location
.get_area(id)
.await
.map_err(|err| -> ClientLocationError { err.into() })?)
.await
.map_err(|err| -> ClientLocationError { err.into() })?.local_client.id();
Ok(LeaveLobby {
client: prev_area_index,
leader: prev_area_leader_index,
_padding: 0,
})
}