steel_core/player/player_data_storage/
known_players.rs1use tokio::io;
2use uuid::Uuid;
3use wincode::{SchemaRead, SchemaWrite};
4
5use super::{decode_file, encode_file};
6use crate::player::{GAME_PROFILE_CACHE_LIMIT, KnownPlayer, KnownPlayers};
7
8const KNOWN_PLAYERS_MAGIC: [u8; 4] = *b"STLK";
9pub(super) const KNOWN_PLAYERS_STORAGE_VERSION: u16 = 1;
10const KNOWN_PLAYERS_DATA_VERSION: i32 = 1;
11
12#[derive(SchemaWrite, SchemaRead)]
13pub(super) struct KnownPlayersFile {
14 data_version: i32,
15 players: Vec<KnownPlayerFile>,
16}
17
18#[derive(SchemaWrite, SchemaRead)]
19struct KnownPlayerFile {
20 uuid: [u8; 16],
21 last_known_name: String,
22 expires_at_millis: i64,
23}
24
25impl KnownPlayersFile {
26 pub(super) fn from_known_players(players: &KnownPlayers) -> Self {
27 Self {
28 data_version: KNOWN_PLAYERS_DATA_VERSION,
29 players: players
30 .entries()
31 .iter()
32 .take(GAME_PROFILE_CACHE_LIMIT)
33 .map(|player| KnownPlayerFile {
34 uuid: *player.uuid().as_bytes(),
35 last_known_name: player.last_known_name().to_owned(),
36 expires_at_millis: player.expires_at_millis(),
37 })
38 .collect(),
39 }
40 }
41
42 pub(super) fn into_known_players(self) -> io::Result<KnownPlayers> {
43 if self.data_version != KNOWN_PLAYERS_DATA_VERSION {
44 return Err(io::Error::new(
45 io::ErrorKind::InvalidData,
46 format!(
47 "unsupported known player index payload version {}",
48 self.data_version
49 ),
50 ));
51 }
52 Ok(KnownPlayers::from_entries(self.players.into_iter().map(
53 |player| {
54 KnownPlayer::with_expiration(
55 Uuid::from_bytes(player.uuid),
56 player.last_known_name,
57 player.expires_at_millis,
58 )
59 },
60 )))
61 }
62}
63
64pub(super) fn encode_known_players_file(file: &KnownPlayersFile) -> io::Result<Vec<u8>> {
65 encode_file(
66 KNOWN_PLAYERS_MAGIC,
67 KNOWN_PLAYERS_STORAGE_VERSION,
68 wincode::serialize(file),
69 )
70}
71
72pub(super) fn decode_known_players_file(bytes: &[u8]) -> io::Result<KnownPlayersFile> {
73 let payload = decode_file(KNOWN_PLAYERS_MAGIC, KNOWN_PLAYERS_STORAGE_VERSION, bytes)?;
74 wincode::deserialize(&payload)
75 .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error.to_string()))
76}