diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-09-30 10:56:34 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-30 10:56:34 -0500 |
| commit | 643fcb98c0e6cdc63218dd39960d9053b209d9a6 (patch) | |
| tree | 6bddb7fe39b8fcc3ab3fb2665574533bb227898a /azalea-auth/src | |
| parent | a80d8d1b242430c4a251876fa67bfd26af7a0de9 (diff) | |
| download | azalea-drasl-643fcb98c0e6cdc63218dd39960d9053b209d9a6.tar.xz | |
1.21.9 (#235)
* start updating to 25w33a
* 1.21.9-pre2
* clippy
* cleanup, and fix c_explode and c_player_rotation
* mc update should be in Changed section in the changelog
* 1.21.9
Diffstat (limited to 'azalea-auth/src')
| -rw-r--r-- | azalea-auth/src/game_profile.rs | 106 |
1 files changed, 94 insertions, 12 deletions
diff --git a/azalea-auth/src/game_profile.rs b/azalea-auth/src/game_profile.rs index c2561a9d..c944bcc4 100644 --- a/azalea-auth/src/game_profile.rs +++ b/azalea-auth/src/game_profile.rs @@ -1,17 +1,51 @@ -use std::{collections::HashMap, sync::Arc}; +use std::{ + io::{self, Write}, + sync::Arc, +}; -use azalea_buf::AzBuf; +use azalea_buf::{ + AzaleaRead, AzaleaReadLimited, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError, +}; +use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use uuid::Uuid; -#[derive(AzBuf, Debug, Clone, Default, Eq, PartialEq)] +/// Information about the player that's usually stored on Mojang's servers. +#[derive(Debug, Clone, Default, Eq, PartialEq)] pub struct GameProfile { /// The UUID of the player. + /// + /// Typically a UUIDv4 for online-mode players and UUIDv3 for offline-mode + /// players. pub uuid: Uuid, /// The username of the player. + /// + /// Limited to 16 bytes. pub name: String, - // this is an arc to make GameProfile cheaper to clone when the properties are big - pub properties: Arc<HashMap<String, ProfilePropertyValue>>, + /// The properties of the player, including their in-game skin and cape. + /// + /// This is an `Arc` to make it cheaper to clone. + pub properties: Arc<GameProfileProperties>, +} +impl AzaleaRead for GameProfile { + fn azalea_read(buf: &mut io::Cursor<&[u8]>) -> Result<Self, BufReadError> { + let uuid = Uuid::azalea_read(buf)?; + let name = String::azalea_read(buf)?; + let properties = GameProfileProperties::azalea_read(buf)?; + Ok(GameProfile { + uuid, + name, + properties: Arc::new(properties), + }) + } +} +impl AzaleaWrite for GameProfile { + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + self.uuid.azalea_write(buf)?; + self.name.azalea_write(buf)?; + self.properties.azalea_write(buf)?; + Ok(()) + } } impl GameProfile { @@ -19,14 +53,14 @@ impl GameProfile { GameProfile { uuid, name, - properties: Arc::new(HashMap::new()), + properties: Arc::new(GameProfileProperties::default()), } } } impl From<SerializableGameProfile> for GameProfile { fn from(value: SerializableGameProfile) -> Self { - let mut properties = HashMap::new(); + let mut properties = IndexMap::new(); for value in value.properties { properties.insert( value.name, @@ -39,16 +73,64 @@ impl From<SerializableGameProfile> for GameProfile { Self { uuid: value.id, name: value.name, - properties: Arc::new(properties), + properties: Arc::new(GameProfileProperties { map: properties }), + } + } +} + +/// The properties of the player, including their in-game skin and cape. +#[derive(Debug, Clone, Default, Eq, PartialEq)] +pub struct GameProfileProperties { + pub map: IndexMap<String, ProfilePropertyValue>, +} +impl AzaleaRead for GameProfileProperties { + fn azalea_read(buf: &mut io::Cursor<&[u8]>) -> Result<Self, BufReadError> { + let mut properties = IndexMap::new(); + let properties_len = u32::azalea_read_var(buf)?; + if properties_len > 16 { + return Err(BufReadError::VecLengthTooLong { + length: properties_len, + max_length: 16, + }); } + for _ in 0..properties_len { + let key = String::azalea_read_limited(buf, 16)?; + let value = ProfilePropertyValue::azalea_read(buf)?; + properties.insert(key, value); + } + Ok(GameProfileProperties { map: properties }) + } +} +impl AzaleaWrite for GameProfileProperties { + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + (self.map.len() as u64).azalea_write_var(buf)?; + for (key, value) in &self.map { + key.azalea_write(buf)?; + value.azalea_write(buf)?; + } + Ok(()) } } -#[derive(AzBuf, Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct ProfilePropertyValue { pub value: String, pub signature: Option<String>, } +impl AzaleaRead for ProfilePropertyValue { + fn azalea_read(buf: &mut io::Cursor<&[u8]>) -> Result<Self, BufReadError> { + let value = String::azalea_read_limited(buf, 32767)?; + let signature = Option::<String>::azalea_read_limited(buf, 1024)?; + Ok(ProfilePropertyValue { value, signature }) + } +} +impl AzaleaWrite for ProfilePropertyValue { + fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { + self.value.azalea_write(buf)?; + self.signature.azalea_write(buf)?; + Ok(()) + } +} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SerializableGameProfile { @@ -60,7 +142,7 @@ pub struct SerializableGameProfile { impl From<GameProfile> for SerializableGameProfile { fn from(value: GameProfile) -> Self { let mut properties = Vec::new(); - for (key, value) in &*value.properties { + for (key, value) in &value.properties.map { properties.push(SerializableProfilePropertyValue { name: key.clone(), value: value.value.clone(), @@ -107,7 +189,7 @@ mod tests { uuid: Uuid::parse_str("f1a2b3c4-d5e6-f7a8-b9c0-d1e2f3a4b5c6").unwrap(), name: "Notch".to_string(), properties: { - let mut map = HashMap::new(); + let mut map = IndexMap::new(); map.insert( "qwer".to_string(), ProfilePropertyValue { @@ -115,7 +197,7 @@ mod tests { signature: Some("zxcv".to_string()), }, ); - map.into() + GameProfileProperties { map }.into() }, } ); |
