steel_core/player/profile/
mod.rs1mod known_players;
4mod lookup;
5
6pub(crate) use known_players::{GAME_PROFILE_CACHE_LIMIT, KnownPlayerNameLookup};
7pub use known_players::{KnownPlayer, KnownPlayers};
8pub use lookup::ProfileLookupError;
9pub(crate) use lookup::lookup_online_profile;
10
11use serde::{Deserialize, Serialize};
12use steel_protocol::packets::login::{GameProfileProperty, LoginGameProfile};
13use uuid::{Builder, Uuid, Variant, Version};
14
15#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
17#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
18pub enum GameProfileAction {
19 ForcedNameChange,
21 UsingBannedSkin,
23}
24
25#[derive(Deserialize, Clone, Debug)]
27pub struct GameProfile {
28 pub id: Uuid,
30 pub name: String,
32 pub properties: Vec<GameProfileProperty>,
34 #[serde(rename = "profileActions")]
36 pub profile_actions: Option<Vec<GameProfileAction>>,
37}
38
39impl<'a> From<&'a GameProfile> for LoginGameProfile<'a> {
40 fn from(profile: &'a GameProfile) -> Self {
41 LoginGameProfile {
42 id: profile.id,
43 name: &profile.name,
44 properties: &profile.properties,
45 }
46 }
47}
48
49#[must_use]
51pub fn is_valid_player_name(name: &str) -> bool {
52 (3..=16).contains(&name.len())
53 && name
54 .chars()
55 .all(|character| character.is_ascii_alphanumeric() || character == '_')
56}
57
58#[must_use]
60pub fn offline_uuid(username: &str) -> Uuid {
61 Builder::from_md5_bytes(md5::compute(format!("OfflinePlayer:{username}")).0)
62 .with_version(Version::Md5)
63 .with_variant(Variant::RFC4122)
64 .into_uuid()
65}
66
67#[cfg(test)]
68mod tests {
69 use super::{is_valid_player_name, offline_uuid};
70
71 #[test]
72 fn validates_vanilla_player_names() {
73 assert!(is_valid_player_name("Steve"));
74 assert!(is_valid_player_name("Alex_123"));
75 assert!(!is_valid_player_name("ab"));
76 assert!(!is_valid_player_name("name-with-dash"));
77 assert!(!is_valid_player_name("way_too_long_player_name"));
78 }
79
80 #[test]
81 fn offline_uuid_matches_vanilla_name_uuid() {
82 assert_eq!(
83 offline_uuid("Steve").to_string(),
84 "5627dd98-e6be-3c21-b8a8-e92344183641"
85 );
86 }
87}