Skip to main content

steel_core/player/player_data_storage/
known_players.rs

1use 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}