use libpso::packet::ship::*; use networking::serverstate::ClientId; use maps::Holiday; use client::Clients; use location::{ClientLocation, LobbyId, ClientLocationError}; use crate::player_info; use 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: Holiday) -> Result { 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::, 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: Holiday) -> Result { 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 { 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, }) }