use futures::stream::{FuturesOrdered, StreamExt}; use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::entity::gateway::EntityGateway; use crate::ship::client::{Clients, ClientState}; use crate::ship::teams::Teams; use crate::ship::location::ClientLocation; use crate::ship::ship::ShipError; use crate::entity::team::TeamEntity; pub fn client_team_state_changed(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> ClientTeamStateChanged { ClientTeamStateChanged { unknown: 0, guildcard: client.user.guildcard(), team_id: team.id.0, unknown2: [0;2], privilege: 0x40, // TODO: improve team_name: libpso::utf8_to_utf16_array!(team.name, 14), unknown3: 0x00986C84, // TODO: what if we omit this? } } fn player_team_info(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> PlayerTeamInfo { PlayerTeamInfo { guildcard: client.user.guildcard(), team_id: team.id.0, info: 0, info2: 0, privilege: 0x40, // TODO: improve team_name: libpso::utf8_to_utf16_array!(team.name, 14), unknown: 0x00986C84, // TODO: what if we omit this? guildcard_again: client.user.guildcard(), client_id: client_id.0 as u32, character_name: libpso::utf8_to_utf16_array!(client.character.name, 12), unknown2: 0, unknown3: 0, team_flag: team.team_flag, } } pub fn team_info_individual(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> TeamInfo { TeamInfo { clients: vec![player_team_info(client_id, client, team)] } } pub async fn player_team_info_list(id: ClientId, client_location: &ClientLocation, clients: &Clients, teams: &Teams, ) -> Result, ShipError> where EG: EntityGateway + Clone + 'static, { Ok(futures::stream::iter(client_location.get_all_clients_by_client(id).await?.into_iter()) .filter_map(|area_client| { let clients = clients.clone(); async move { clients.with(area_client.client, |client| { let mut teams = teams.clone(); Box::pin(async move { let team = teams.get_team(area_client.client).await.ok()??; Some(player_team_info(area_client.client, client, &team)) })}).await.ok()? }}) .collect::>() .await) } pub async fn team_info(id: ClientId, client_location: &ClientLocation, clients: &Clients, teams: &Teams, ) -> Result where EG: EntityGateway + Clone + 'static, { Ok(TeamInfo { clients: player_team_info_list(id, client_location, clients, teams).await?, }) } pub async fn lobby_team_list(id: ClientId, client_location: &ClientLocation, clients: &Clients, teams: &Teams, ) -> Result where EG: EntityGateway + Clone + 'static, { Ok(TeamLobbyList { clients: player_team_info_list(id, client_location, clients, teams).await?, }) } pub fn team_invitation_info(client_id: ClientId, client: &ClientState, team: &TeamEntity) -> TeamInvitationInfo { TeamInvitationInfo { guildcard: client.user.guildcard(), team_id: team.id.0, unknown: [0; 2], team_name: libpso::utf8_to_utf16_array!(team.name, 14), unknown2: 0x00986C84, // TODO: what if we omit this? team_flag: team.team_flag, } }