Skip to main content

steel_core/player/profile/
mod.rs

1//! Player profile helpers for name validation, offline UUIDs, and known player lookup
2
3mod 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
11pub use steel_registry::GameProfile;
12use uuid::{Builder, Uuid, Variant, Version};
13
14/// Returns whether a name is valid for online login and profile lookup.
15#[must_use]
16pub fn is_valid_player_name(name: &str) -> bool {
17    (3..=16).contains(&name.len())
18        && name
19            .chars()
20            .all(|character| character.is_ascii_alphanumeric() || character == '_')
21}
22
23/// Generates vanilla's deterministic offline-mode UUID for a player name.
24#[must_use]
25pub fn offline_uuid(username: &str) -> Uuid {
26    Builder::from_md5_bytes(md5::compute(format!("OfflinePlayer:{username}")).0)
27        .with_version(Version::Md5)
28        .with_variant(Variant::RFC4122)
29        .into_uuid()
30}
31
32#[cfg(test)]
33mod tests {
34    use super::{is_valid_player_name, offline_uuid};
35
36    #[test]
37    fn validates_vanilla_player_names() {
38        assert!(is_valid_player_name("Steve"));
39        assert!(is_valid_player_name("Alex_123"));
40        assert!(!is_valid_player_name("ab"));
41        assert!(!is_valid_player_name("name-with-dash"));
42        assert!(!is_valid_player_name("way_too_long_player_name"));
43    }
44
45    #[test]
46    fn offline_uuid_matches_vanilla_name_uuid() {
47        assert_eq!(
48            offline_uuid("Steve").to_string(),
49            "5627dd98-e6be-3c21-b8a8-e92344183641"
50        );
51    }
52}