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

analyser cleanup

This commit is contained in:
Robin Appelman 2019-08-25 23:49:21 +02:00
commit 4320f2941c
2 changed files with 48 additions and 29 deletions

View file

@ -5,16 +5,26 @@ use crate::demo::packet::datatable::ServerClass;
use crate::demo::parser::ParseBitSkip; use crate::demo::parser::ParseBitSkip;
use crate::demo::sendprop::SendProp; use crate::demo::sendprop::SendProp;
use crate::{Parse, ParseError, ParserState, Result, Stream}; use crate::{Parse, ParseError, ParserState, Result, Stream};
use std::num::ParseIntError;
use std::str::FromStr;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct EntityId(u32); pub struct EntityId(u32);
impl EntityId { impl From<u32> for EntityId {
pub fn new(num: u32) -> Self { fn from(num: u32) -> Self {
EntityId(num) EntityId(num)
} }
} }
impl FromStr for EntityId {
type Err = ParseIntError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
u32::from_str(s).map(EntityId::from)
}
}
#[derive(BitRead, Clone, Copy, Debug)] #[derive(BitRead, Clone, Copy, Debug)]
#[discriminant_bits = 3] #[discriminant_bits = 3]
pub enum PVS { pub enum PVS {

View file

@ -89,6 +89,12 @@ impl Class {
#[derive(Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash)]
pub struct UserId(u8); pub struct UserId(u8);
impl From<u32> for UserId {
fn from(int: u32) -> Self {
UserId((int & 255) as u8)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Spawn { pub struct Spawn {
pub user: UserId, pub user: UserId,
@ -267,7 +273,7 @@ impl Analyser {
fn parse_user_info(&mut self, text: &String, mut data: Stream) -> ReadResult<()> { fn parse_user_info(&mut self, text: &String, mut data: Stream) -> ReadResult<()> {
let name: String = data.read_sized(32).unwrap_or("Malformed Name".into()); let name: String = data.read_sized(32).unwrap_or("Malformed Name".into());
let user_id = UserId((data.read::<u32>()? & 255) as u8); let user_id = data.read::<u32>()?.into();
let steam_id: String = data.read()?; let steam_id: String = data.read()?;
match text.parse() { match text.parse() {
@ -278,7 +284,7 @@ impl Analyser {
steam_id, steam_id,
user_id, user_id,
name, name,
entity_id: EntityId::new(entity_id), entity_id,
}, },
); );
} }
@ -290,56 +296,59 @@ impl Analyser {
} }
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct UserState { pub struct UserState {
pub classes: HashMap<Class, u8>, pub classes: HashMap<Class, u8>,
pub name: String, pub name: String,
#[serde(rename = "userId")]
pub user_id: UserId, pub user_id: UserId,
#[serde(rename = "steamId")]
pub steam_id: String, pub steam_id: String,
pub team: Team, pub team: Team,
} }
impl From<UserInfo> for UserState {
fn from(user: UserInfo) -> Self {
UserState {
classes: HashMap::new(),
team: Team::Other,
name: user.name,
user_id: user.user_id,
steam_id: user.steam_id,
}
}
}
impl UserState { impl UserState {
pub fn from_users_and_spawn( pub fn from_users_and_spawn(
users: HashMap<UserId, UserInfo>, users: HashMap<UserId, UserInfo>,
spawns: Vec<Spawn>, spawns: Vec<Spawn>,
) -> HashMap<UserId, Self> { ) -> HashMap<UserId, Self> {
let mut teams: HashMap<UserId, Team> = HashMap::with_capacity(users.len()); let mut user_states: HashMap<_, _> = users
let mut classes: HashMap<UserId, HashMap<Class, u8>> = HashMap::with_capacity(9); .into_iter()
.map(|(_, user)| (user.user_id, UserState::from(user)))
.collect();
for spawn in spawns { for spawn in spawns {
teams.insert(spawn.user, spawn.team); if let Some(user) = user_states.get_mut(&spawn.user) {
let user_classes = classes.entry(spawn.user).or_default(); user.handle_spawn(&spawn);
let class_spawns = user_classes.entry(spawn.class).or_default(); }
*class_spawns += 1;
} }
users user_states
.into_iter() }
.map(|(_, user)| {
( fn handle_spawn(&mut self, spawn: &Spawn) {
user.user_id, self.team = spawn.team;
UserState { *self.classes.entry(spawn.class).or_default() += 1;
classes: classes.remove(&user.user_id).unwrap_or(HashMap::new()),
team: teams.remove(&user.user_id).unwrap_or(Team::Other),
name: user.name,
user_id: user.user_id,
steam_id: user.steam_id,
},
)
})
.collect()
} }
} }
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct MatchState { pub struct MatchState {
pub chat: Vec<ChatMassage>, pub chat: Vec<ChatMassage>,
pub users: HashMap<UserId, UserState>, pub users: HashMap<UserId, UserState>,
pub deaths: Vec<Death>, pub deaths: Vec<Death>,
pub rounds: Vec<Round>, pub rounds: Vec<Round>,
#[serde(rename = "startTick")]
pub start_tick: u32, pub start_tick: u32,
#[serde(rename = "intervalPerTick")]
pub interval_per_tick: f32, pub interval_per_tick: f32,
} }