108 lines
3.7 KiB
Rust
108 lines
3.7 KiB
Rust
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,
|
|
}
|
|
}
|