1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 10:14:06 +02:00

parse the rest of the userinfo

This commit is contained in:
Robin Appelman 2021-07-21 23:43:49 +02:00
commit 56c0bbaea9
2 changed files with 65 additions and 29 deletions

View file

@ -1,18 +1,65 @@
use crate::demo::message::packetentities::EntityId; use crate::demo::message::packetentities::EntityId;
use crate::demo::packet::stringtable::{ExtraData, StringTableEntry}; use crate::demo::packet::stringtable::{ExtraData, StringTableEntry};
use crate::demo::parser::gamestateanalyser::UserId;
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};
use bitbuffer::{ use bitbuffer::{BitRead, BitReadBuffer, BitReadStream, BitWrite, BitWriteStream, LittleEndian};
BitReadBuffer, BitReadStream, BitWrite, BitWriteSized, BitWriteStream, LittleEndian,
}; #[derive(BitRead, Debug)]
struct RawPlayerInfo {
pub name_bytes: [u8; 32],
pub user_id: u32,
#[size = 32]
pub steam_id: String,
pub extra: u32, // all my sources say these 4 bytes don't exist
pub friends_id: u32,
#[size = 32]
pub friends_name_bytes: [u8; 32], // seem to all be 0 now
pub is_fake_player: u8,
pub is_hl_tv: u8,
pub is_replay: u8,
pub custom_file: [u32; 4],
pub files_downloaded: u32,
}
#[derive(BitWrite, Debug, Clone)]
pub struct PlayerInfo {
#[size = 32]
pub name: String,
pub user_id: u32,
#[size = 32]
pub steam_id: String,
pub extra: u32, // all my sources say these 4 bytes don't exist
pub friends_id: u32,
#[size = 32]
pub friends_name_bytes: [u8; 32], // seem to all be 0 now
pub is_fake_player: u8,
pub is_hl_tv: u8,
pub is_replay: u8,
pub custom_file: [u32; 4],
pub files_downloaded: u32,
}
impl From<RawPlayerInfo> for PlayerInfo {
fn from(raw: RawPlayerInfo) -> Self {
PlayerInfo {
name: String::from_utf8_lossy(&raw.name_bytes).to_string(),
user_id: raw.user_id,
steam_id: raw.steam_id,
extra: raw.extra,
friends_id: raw.friends_id,
friends_name_bytes: raw.friends_name_bytes,
is_fake_player: raw.is_fake_player,
is_hl_tv: raw.is_hl_tv,
is_replay: raw.is_replay,
custom_file: raw.custom_file,
files_downloaded: raw.files_downloaded,
}
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct UserInfo { pub struct UserInfo {
pub steam_id: String,
pub user_id: UserId,
pub entity_id: EntityId, pub entity_id: EntityId,
pub name: String, pub player_info: PlayerInfo,
pub rest_data: Vec<u8>,
} }
impl UserInfo { impl UserInfo {
@ -21,24 +68,16 @@ impl UserInfo {
data: Option<Stream>, data: Option<Stream>,
) -> ReadResult<Option<Self>> { ) -> ReadResult<Option<Self>> {
if let Some(mut data) = data { if let Some(mut data) = data {
let name: String = data // extra decode step to gracefully handle malformed utf8 names
.read_sized(32) let raw_info: RawPlayerInfo = data.clone().read()?;
.unwrap_or_else(|_| "Malformed Name".into());
let user_id: UserId = data.read::<u32>()?.into();
let steam_id: String = data.read_sized(32)?;
let rest_data = data.read_sized(data.bits_left() / 8)?;
match text match text
.map(|text| text.parse::<u32>().map(|id| (id + 1).into())) .map(|text| text.parse::<u32>().map(|id| (id + 1).into()))
.unwrap_or_else(|| Ok((user_id.0 as u32).into())) .unwrap_or_else(|| Ok((raw_info.user_id).into()))
{ {
Ok(entity_id) if !steam_id.is_empty() => Ok(Some(UserInfo { Ok(entity_id) if !raw_info.steam_id.is_empty() => Ok(Some(UserInfo {
steam_id, player_info: raw_info.into(),
user_id,
entity_id, entity_id,
name,
rest_data,
})), })),
_ => Ok(None), _ => Ok(None),
} }
@ -52,10 +91,7 @@ impl UserInfo {
let mut extra_data = Vec::with_capacity(128); let mut extra_data = Vec::with_capacity(128);
{ {
let mut stream = BitWriteStream::new(&mut extra_data, LittleEndian); let mut stream = BitWriteStream::new(&mut extra_data, LittleEndian);
self.name.write_sized(&mut stream, 32)?; self.player_info.write(&mut stream)?;
(self.user_id.0 as u32).write(&mut stream)?;
self.steam_id.write_sized(&mut stream, 32)?;
self.rest_data.write(&mut stream)?;
} }
Ok(StringTableEntry { Ok(StringTableEntry {

View file

@ -224,9 +224,9 @@ impl From<crate::demo::data::UserInfo> for UserInfo {
fn from(info: crate::demo::data::UserInfo) -> Self { fn from(info: crate::demo::data::UserInfo) -> Self {
UserInfo { UserInfo {
classes: ClassList::default(), classes: ClassList::default(),
name: info.name, name: info.player_info.name,
user_id: info.user_id, user_id: info.player_info.user_id.into(),
steam_id: info.steam_id, steam_id: info.player_info.steam_id,
entity_id: info.entity_id, entity_id: info.entity_id,
team: Team::default(), team: Team::default(),
} }
@ -392,7 +392,7 @@ impl Analyser {
if let Some(user_info) = crate::demo::data::UserInfo::parse_from_string_table(text, data)? { if let Some(user_info) = crate::demo::data::UserInfo::parse_from_string_table(text, data)? {
self.state self.state
.users .users
.entry(user_info.user_id) .entry(user_info.player_info.user_id.into())
.and_modify(|info| { .and_modify(|info| {
info.entity_id = user_info.entity_id; info.entity_id = user_info.entity_id;
}) })