You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.7 KiB

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<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
teams: &Teams<EG>,
) -> Result<Vec<PlayerTeamInfo>, 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::<Vec<_>>()
.await)
}
pub async fn team_info<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
teams: &Teams<EG>,
) -> Result<TeamInfo, ShipError>
where
EG: EntityGateway + Clone + 'static,
{
Ok(TeamInfo {
clients: player_team_info_list(id, client_location, clients, teams).await?,
})
}
pub async fn lobby_team_list<EG>(id: ClientId,
client_location: &ClientLocation,
clients: &Clients,
teams: &Teams<EG>,
) -> Result<TeamLobbyList, ShipError>
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,
}
}