azalea_auth/
game_profile.rs

1use std::{collections::HashMap, sync::Arc};
2
3use azalea_buf::AzBuf;
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7#[derive(AzBuf, Debug, Clone, Default, Eq, PartialEq)]
8pub struct GameProfile {
9    /// The UUID of the player.
10    pub uuid: Uuid,
11    /// The username of the player.
12    pub name: String,
13    // this is an arc to make GameProfile cheaper to clone when the properties are big
14    pub properties: Arc<HashMap<String, ProfilePropertyValue>>,
15}
16
17impl GameProfile {
18    pub fn new(uuid: Uuid, name: String) -> Self {
19        GameProfile {
20            uuid,
21            name,
22            properties: Arc::new(HashMap::new()),
23        }
24    }
25}
26
27impl From<SerializableGameProfile> for GameProfile {
28    fn from(value: SerializableGameProfile) -> Self {
29        let mut properties = HashMap::new();
30        for value in value.properties {
31            properties.insert(
32                value.name,
33                ProfilePropertyValue {
34                    value: value.value,
35                    signature: value.signature,
36                },
37            );
38        }
39        Self {
40            uuid: value.id,
41            name: value.name,
42            properties: Arc::new(properties),
43        }
44    }
45}
46
47#[derive(AzBuf, Debug, Clone, Eq, PartialEq)]
48pub struct ProfilePropertyValue {
49    pub value: String,
50    pub signature: Option<String>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct SerializableGameProfile {
55    pub id: Uuid,
56    pub name: String,
57    pub properties: Vec<SerializableProfilePropertyValue>,
58}
59
60impl From<GameProfile> for SerializableGameProfile {
61    fn from(value: GameProfile) -> Self {
62        let mut properties = Vec::new();
63        for (key, value) in &*value.properties {
64            properties.push(SerializableProfilePropertyValue {
65                name: key.clone(),
66                value: value.value.clone(),
67                signature: value.signature.clone(),
68            });
69        }
70        Self {
71            id: value.uuid,
72            name: value.name,
73            properties,
74        }
75    }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct SerializableProfilePropertyValue {
80    pub name: String,
81    pub value: String,
82    pub signature: Option<String>,
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_deserialize_game_profile() {
91        let json = r#"{
92            "id": "f1a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c6",
93            "name": "Notch",
94            "properties": [
95                {
96                    "name": "qwer",
97                    "value": "asdf",
98                    "signature": "zxcv"
99                }
100            ]
101        }"#;
102        let profile =
103            GameProfile::from(serde_json::from_str::<SerializableGameProfile>(json).unwrap());
104        assert_eq!(
105            profile,
106            GameProfile {
107                uuid: Uuid::parse_str("f1a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c6").unwrap(),
108                name: "Notch".to_string(),
109                properties: {
110                    let mut map = HashMap::new();
111                    map.insert(
112                        "qwer".to_string(),
113                        ProfilePropertyValue {
114                            value: "asdf".to_string(),
115                            signature: Some("zxcv".to_string()),
116                        },
117                    );
118                    map.into()
119                },
120            }
121        );
122    }
123}