Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rank update custom event #25

Merged
merged 4 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Python application
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

permissions:
contents: read
Expand Down
4 changes: 2 additions & 2 deletions src/parser/src/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ impl ParserThread {
for (field_info, debug) in self.field_infos[..n_updates].iter().zip(&self.debug_fields) {
let result = bitreader.decode(&field_info.decoder, &self.qf_mapper)?;
// self.game_events_counter.insert(debug.field.full_name.clone());
if debug.field.full_name.contains("Time") {
println!("{:?} {:?} {:?}", debug.path, debug.field.full_name, result);
if debug.field.full_name.contains("Controller") && self.tick < 200 {
println!("{:?} {:?} {:?} {:?}", debug.path, debug.field.full_name, result, self.tick);
}
}
} else {
Expand Down
83 changes: 74 additions & 9 deletions src/parser/src/game_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::stringtables::UserInfo;
use crate::variants::*;
use ahash::AHashMap;
use ahash::RandomState;
use csgoproto::cstrike15_usermessages::CCSUsrMsg_ServerRankUpdate;
use csgoproto::netmessages::csvcmsg_game_event_list::Descriptor_t;
use csgoproto::netmessages::CSVCMsg_GameEventList;
use csgoproto::networkbasetypes::csvcmsg_game_event::Key_t;
Expand All @@ -24,6 +25,8 @@ static INTERNALEVENTFIELDS: &'static [&str] = &[
"assister_pawn",
];
const ENTITYIDNONE: i32 = 2047;
// https://developer.valvesoftware.com/wiki/SteamID
const STEAMID64INDIVIDUALIDENTIFIER: u64 = 0x0110000100000000;

impl Parser {
// Message that should come before first game event
Expand Down Expand Up @@ -81,15 +84,15 @@ impl ParserThread {
});
Ok(())
}
fn find_user_by_userid(&self, userid: i32) -> Option<&UserInfo> {
pub fn find_user_by_userid(&self, userid: i32) -> Option<&UserInfo> {
for player in self.stringtable_players.values() {
if player.userid == userid {
return Some(player);
}
}
return None;
}
fn entity_id_from_userid(&self, userid: i32) -> Option<i32> {
pub fn entity_id_from_userid(&self, userid: i32) -> Option<i32> {
if let Some(userinfo) = self.find_user_by_userid(userid) {
for player in self.players.values() {
if player.steamid == Some(userinfo.steamid) {
Expand All @@ -99,7 +102,7 @@ impl ParserThread {
}
return None;
}
fn find_extra(&self, fields: &Vec<EventField>) -> Result<Vec<EventField>, DemoParserError> {
pub fn find_extra(&self, fields: &Vec<EventField>) -> Result<Vec<EventField>, DemoParserError> {
let mut extra_fields = vec![];
// Always add tick to event
extra_fields.push(EventField {
Expand Down Expand Up @@ -132,7 +135,7 @@ impl ParserThread {
extra_fields.extend(self.find_non_player_props());
Ok(extra_fields)
}
fn generate_empty_fields(&self, prefix: &str) -> Vec<EventField> {
pub fn generate_empty_fields(&self, prefix: &str) -> Vec<EventField> {
let mut extra_fields = vec![];
// when pointer fails for some reason we need to add None to output
for prop_info in &self.prop_controller.prop_infos {
Expand All @@ -159,7 +162,7 @@ impl ParserThread {
extra_fields
}

fn find_non_player_props(&self) -> Vec<EventField> {
pub fn find_non_player_props(&self) -> Vec<EventField> {
let mut extra_fields = vec![];
for prop_info in &self.prop_controller.prop_infos {
let fields = match prop_info.prop_type {
Expand All @@ -172,7 +175,7 @@ impl ParserThread {
extra_fields
}

fn find_other_rules_props(&self, prop_info: &PropInfo) -> Vec<EventField> {
pub fn find_other_rules_props(&self, prop_info: &PropInfo) -> Vec<EventField> {
let mut extra_fields = vec![];
let prop = match self.rules_entity_id {
Some(entid) => match self.get_prop_from_ent(&prop_info.id, &entid) {
Expand All @@ -187,7 +190,7 @@ impl ParserThread {
});
extra_fields
}
fn find_other_team_props(&self, prop_info: &PropInfo) -> Vec<EventField> {
pub fn find_other_team_props(&self, prop_info: &PropInfo) -> Vec<EventField> {
let mut extra_fields = vec![];
let t = self.teams.team2_entid;
let ct = self.teams.team3_entid;
Expand Down Expand Up @@ -259,7 +262,7 @@ impl ParserThread {
}
extra_pairs
}
fn create_player_name_field(&self, entity_id: i32, prefix: &str) -> EventField {
pub fn create_player_name_field(&self, entity_id: i32, prefix: &str) -> EventField {
if entity_id == ENTITYIDNONE {
return EventField {
name: prefix.to_owned() + "_name",
Expand All @@ -278,7 +281,7 @@ impl ParserThread {
data: data,
}
}
fn create_player_steamid_field(&self, entity_id: i32, prefix: &str) -> EventField {
pub fn create_player_steamid_field(&self, entity_id: i32, prefix: &str) -> EventField {
if entity_id == ENTITYIDNONE {
return EventField {
name: prefix.to_owned() + "_steamid",
Expand All @@ -297,6 +300,68 @@ impl ParserThread {
data: data,
}
}
pub fn player_from_steamid32(&self, steamid32: i32) -> Option<i32> {
for (_entid, player) in &self.players {
if let Some(steamid) = player.steamid {
if steamid - STEAMID64INDIVIDUALIDENTIFIER == steamid32 as u64 {
return Some(player.player_entity_id.unwrap());
}
}
}
None
}
pub fn create_custom_event_rank_update(&mut self, msg_bytes: &[u8]) -> Result<(), DemoParserError> {
if !self.wanted_events.contains(&"rank_update".to_string()) {
return Ok(());
}
let update_msg: CCSUsrMsg_ServerRankUpdate = match Message::parse_from_bytes(&msg_bytes) {
Ok(m) => m,
Err(_e) => return Err(DemoParserError::MalformedMessage),
};

for update in update_msg.rank_update {
let mut fields = vec![];

let entity_id = match self.player_from_steamid32(update.account_id.unwrap()) {
Some(eid) => eid,
None => continue,
};

fields.push(self.create_player_name_field(entity_id, "user"));
fields.push(self.create_player_steamid_field(entity_id, "user"));
fields.extend(self.find_extra_props_events(entity_id, "user"));

fields.push(EventField {
data: Some(Variant::I32(update.num_wins())),
name: "num_wins".to_string(),
});
fields.push(EventField {
data: Some(Variant::I32(update.rank_old())),
name: "rank_old".to_string(),
});
fields.push(EventField {
data: Some(Variant::I32(update.rank_new())),
name: "rank_new".to_string(),
});
fields.push(EventField {
data: Some(Variant::F32(update.rank_change())),
name: "rank_change".to_string(),
});
fields.push(EventField {
data: Some(Variant::I32(update.rank_type_id())),
name: "rank_type_id".to_string(),
});
let ge = GameEvent {
name: "rank_update".to_string(),
fields: fields,
tick: self.tick,
};
self.game_events.push(ge);
self.game_events_counter.insert("rank_update".to_string());
}

Ok(())
}
}
// what is this shit
fn parse_key(key: &Key_t) -> Option<Variant> {
Expand Down
2 changes: 1 addition & 1 deletion src/parser/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn main() {
let mut ds = Parser::new(settings);
let d = ds.parse_demo().unwrap();
println!("TOTAL {:?}", before.elapsed());
println!("{:?}", d.game_events_counter);
println!("{:?}", d.game_events);
}
println!("TOTAL {:?}", before.elapsed());
}
1 change: 1 addition & 0 deletions src/parser/src/parser_threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl ParserThread {
UM_SayText2 => self.parse_chat_messages(&msg_bytes),
net_SetConVar => self.parse_convars(&msg_bytes),
CS_UM_PlayerStatsUpdate => self.parse_player_stats_update(&msg_bytes),
CS_UM_ServerRankUpdate => self.create_custom_event_rank_update(&msg_bytes),
_ => Ok(()),
};
ok?;
Expand Down
2 changes: 1 addition & 1 deletion src/python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "demoparser2"
version = "0.5.1"
version = "0.6.0"
edition = "2021"


Expand Down
6 changes: 6 additions & 0 deletions src/python/tests/e2e_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,11 @@ def test_parse_grenades(self):
df = convert_same_dtypes(parser.parse_grenades(), df_correct)
assert_frame_equal(df, df_correct)

def test_custom_even_rank_update(self):
parser = DemoParser("tests/data/test.dem")
df = parser.parse_event("rank_update")
df_correct = convert_same_dtypes(df, pd.read_csv("tests/data/python/rank_update.csv"))
assert_frame_equal(df, df_correct)

if __name__ == '__main__':
unittest.main()