use std::cmp::{Eq, PartialEq};
use std::hash::{Hash, Hasher};
use std::{collections::HashMap, fmt, sync::Arc};
use ustr::Ustr;
use crate::{ARCHIPELAGO_NAME, Error, ProtocolError, protocol::*};
#[derive(Debug, Clone)]
pub struct Player {
team: u32,
slot: u32,
alias: String,
name: Ustr,
game: Ustr,
group_members: Vec<Arc<Player>>,
}
impl Player {
pub(crate) fn hydrate(
network: NetworkPlayer,
slot_info: &NetworkSlot,
players: &HashMap<(u32, u32), Arc<Player>>,
) -> Result<Self, Error> {
let team = network.team;
Ok(Player {
team,
slot: network.slot,
alias: network.alias,
name: network.name,
game: slot_info.game,
group_members: slot_info
.group_members
.iter()
.copied()
.map(|slot| {
players
.get(&(team, slot))
.cloned()
.ok_or(ProtocolError::MissingPlayer { team, slot })
})
.collect::<Result<_, _>>()?,
})
}
pub(crate) fn archipelago(team: u32) -> Self {
Player {
team,
slot: 0,
alias: "Archipelago".into(),
name: *ARCHIPELAGO_NAME,
game: *ARCHIPELAGO_NAME,
group_members: Default::default(),
}
}
pub(crate) fn with_alias(&self, alias: String) -> Option<Self> {
if self.alias == alias {
None
} else {
Some(Player {
alias,
..self.clone()
})
}
}
pub fn team(&self) -> u32 {
self.team
}
pub fn slot(&self) -> u32 {
self.slot
}
pub fn alias(&self) -> &str {
self.alias.as_str()
}
pub fn name(&self) -> Ustr {
self.name
}
pub fn game(&self) -> Ustr {
self.game
}
pub fn group_members(&self) -> &[Arc<Player>] {
&self.group_members
}
}
impl fmt::Display for Player {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.alias.fmt(f)
}
}
impl PartialEq for Player {
fn eq(&self, other: &Self) -> bool {
self.team == other.team && self.slot == other.slot
}
}
impl Eq for Player {}
impl Hash for Player {
fn hash<H: Hasher>(&self, state: &mut H) {
self.team.hash(state);
self.slot.hash(state);
}
}