diff --git a/src/parser/src/collect_data.rs b/src/parser/src/collect_data.rs index 242edf00..50a3d597 100644 --- a/src/parser/src/collect_data.rs +++ b/src/parser/src/collect_data.rs @@ -2,6 +2,7 @@ use itertools::Itertools; use super::entities::PlayerMetaData; use super::variants::Variant; +use crate::maps::AGENTSMAP; use crate::maps::BUTTONMAP; use crate::maps::GRENADE_FRIENDLY_NAMES; use crate::maps::PAINTKITS; @@ -97,6 +98,10 @@ pub enum PropCollectionError { OriginalOwnerXuidHighIncorrectVariant, SpottedIncorrectVariant, VelocityNotFound, + AgentIdNotFound, + AgentIncorrectVariant, + AgentPropNotFound, + AgentSpecialIdNotSet, } // DONT KNOW IF THESE ARE CORRECT. SEEMS TO GIVE CORRECT VALUES const CELL_BITS: i32 = 9; @@ -177,7 +182,7 @@ impl ParserThread { PropType::Custom => self.create_custom_prop(prop_info.prop_name.as_str(), entity_id, prop_info, player), PropType::Weapon => return self.find_weapon_prop(&prop_info.id, &entity_id), PropType::Button => return self.get_button_prop(&prop_info, &entity_id), - PropType::Controller => return self.get_controller_prop(prop_info, player), + PropType::Controller => return self.get_controller_prop(&prop_info.id, player), PropType::Rules => return self.get_rules_prop(prop_info), PropType::GameTime => return Ok(Variant::F32(self.net_tick as f32 / 64.0)), } @@ -227,9 +232,9 @@ impl ParserThread { None => return Err(PropCollectionError::RulesEntityIdNotSet), } } - pub fn get_controller_prop(&self, prop_info: &PropInfo, player: &PlayerMetaData) -> Result { + pub fn get_controller_prop(&self, prop_id: &u32, player: &PlayerMetaData) -> Result { match player.controller_entid { - Some(entid) => return self.get_prop_from_ent(&prop_info.id, &entid), + Some(entid) => return self.get_prop_from_ent(prop_id, &entid), None => return Err(PropCollectionError::ControllerEntityIdNotSet), } } @@ -473,9 +478,24 @@ impl ParserThread { "CCSPlayerPawn.m_bSpottedByMask" => self.find_spotted(entity_id, prop_info), "entity_id" => return Ok(Variant::I32(*entity_id)), "is_alive" => return self.find_is_alive(entity_id), + "agent_skin" => return self.find_agent_skin(player), _ => Err(PropCollectionError::UnknownCustomPropName), } } + pub fn find_agent_skin(&self, player: &PlayerMetaData) -> Result { + let id = match self.prop_controller.special_ids.agent_skin_idx { + Some(i) => i, + None => return Err(PropCollectionError::AgentSpecialIdNotSet), + }; + match self.get_controller_prop(&id, player) { + Ok(Variant::U32(agent_id)) => match AGENTSMAP.get(&agent_id) { + Some(agent) => return Ok(Variant::String(agent.to_string())), + None => return Err(PropCollectionError::AgentIdNotFound), + }, + Ok(_) => return Err(PropCollectionError::AgentIncorrectVariant), + Err(_) => return Err(PropCollectionError::AgentPropNotFound), + } + } pub fn collect_velocity(&self, player: &PlayerMetaData) -> Result { if let Some(s) = player.steamid { let steamids = self.output.get(&STEAMID_ID); diff --git a/src/parser/src/maps.rs b/src/parser/src/maps.rs index 296f9b9f..76c6cf48 100644 --- a/src/parser/src/maps.rs +++ b/src/parser/src/maps.rs @@ -16,6 +16,149 @@ pub static BUTTONMAP: phf::Map<&'static str, u64> = phf_map! { "ZOOM" => 1 << 24, "WALK" => 1 << 18, }; +pub static AGENTSMAP: phf::Map = phf_map! { + 5036_u32 => "customplayer_t_map_based", + 5037_u32 => "customplayer_ct_map_based", + 5038_u32 => "customplayer_tm_anarchist", + 5039_u32 => "customplayer_tm_anarchist_varianta", + 5040_u32 => "customplayer_tm_anarchist_variantb", + 5041_u32 => "customplayer_tm_anarchist_variantc", + 5042_u32 => "customplayer_tm_anarchist_variantd", + 5043_u32 => "customplayer_tm_pirate", + 5044_u32 => "customplayer_tm_pirate_varianta", + 5045_u32 => "customplayer_tm_pirate_variantb", + 5046_u32 => "customplayer_tm_pirate_variantc", + 5047_u32 => "customplayer_tm_pirate_variantd", + 5048_u32 => "customplayer_tm_professional", + 5049_u32 => "customplayer_tm_professional_var1", + 5050_u32 => "customplayer_tm_professional_var2", + 5051_u32 => "customplayer_tm_professional_var3", + 5052_u32 => "customplayer_tm_professional_var4", + 5053_u32 => "customplayer_tm_separatist", + 5054_u32 => "customplayer_tm_separatist_varianta", + 5055_u32 => "customplayer_tm_separatist_variantb", + 5056_u32 => "customplayer_tm_separatist_variantc", + 5057_u32 => "customplayer_tm_separatist_variantd", + 5058_u32 => "customplayer_ctm_gign", + 5059_u32 => "customplayer_ctm_gign_varianta", + 5060_u32 => "customplayer_ctm_gign_variantb", + 5061_u32 => "customplayer_ctm_gign_variantc", + 5062_u32 => "customplayer_ctm_gign_variantd", + 5063_u32 => "customplayer_ctm_gsg9", + 5064_u32 => "customplayer_ctm_gsg9_varianta", + 5065_u32 => "customplayer_ctm_gsg9_variantb", + 5066_u32 => "customplayer_ctm_gsg9_variantc", + 5067_u32 => "customplayer_ctm_gsg9_variantd", + 5068_u32 => "customplayer_ctm_idf", + 5069_u32 => "customplayer_ctm_idf_variantb", + 5070_u32 => "customplayer_ctm_idf_variantc", + 5071_u32 => "customplayer_ctm_idf_variantd", + 5072_u32 => "customplayer_ctm_idf_variante", + 5073_u32 => "customplayer_ctm_idf_variantf", + 5074_u32 => "customplayer_ctm_swat", + 5075_u32 => "customplayer_ctm_swat_varianta", + 5076_u32 => "customplayer_ctm_swat_variantb", + 5077_u32 => "customplayer_ctm_swat_variantc", + 5078_u32 => "customplayer_ctm_swat_variantd", + 5079_u32 => "customplayer_ctm_sas_varianta", + 5080_u32 => "customplayer_ctm_sas_variantb", + 5081_u32 => "customplayer_ctm_sas_variantc", + 5082_u32 => "customplayer_ctm_sas_variantd", + 5083_u32 => "customplayer_ctm_st6", + 5084_u32 => "customplayer_ctm_st6_varianta", + 5085_u32 => "customplayer_ctm_st6_variantb", + 5086_u32 => "customplayer_ctm_st6_variantc", + 5087_u32 => "customplayer_ctm_st6_variantd", + 5088_u32 => "customplayer_tm_balkan_variante", + 5089_u32 => "customplayer_tm_balkan_varianta", + 5090_u32 => "customplayer_tm_balkan_variantb", + 5091_u32 => "customplayer_tm_balkan_variantc", + 5092_u32 => "customplayer_tm_balkan_variantd", + 5093_u32 => "customplayer_tm_jumpsuit_varianta", + 5094_u32 => "customplayer_tm_jumpsuit_variantb", + 5095_u32 => "customplayer_tm_jumpsuit_variantc", + 5096_u32 => "customplayer_tm_phoenix_heavy", + 5097_u32 => "customplayer_ctm_heavy", + 5100_u32 => "customplayer_tm_leet_varianta", + 5101_u32 => "customplayer_tm_leet_variantb", + 5102_u32 => "customplayer_tm_leet_variantc", + 5103_u32 => "customplayer_tm_leet_variantd", + 5104_u32 => "customplayer_tm_leet_variante", + 5105_u32 => "customplayer_tm_leet_variantg", + 5106_u32 => "customplayer_tm_leet_varianth", + 5107_u32 => "customplayer_tm_leet_varianti", + 5108_u32 => "customplayer_tm_leet_variantf", + 5109_u32 => "customplayer_tm_leet_variantj", + 5200_u32 => "customplayer_tm_phoenix", + 5201_u32 => "customplayer_tm_phoenix_varianta", + 5202_u32 => "customplayer_tm_phoenix_variantb", + 5203_u32 => "customplayer_tm_phoenix_variantc", + 5204_u32 => "customplayer_tm_phoenix_variantd", + 5205_u32 => "customplayer_tm_phoenix_varianth", + 5206_u32 => "customplayer_tm_phoenix_variantf", + 5207_u32 => "customplayer_tm_phoenix_variantg", + 5208_u32 => "customplayer_tm_phoenix_varianti", + 5300_u32 => "customplayer_ctm_fbi", + 5301_u32 => "customplayer_ctm_fbi_varianta", + 5302_u32 => "customplayer_ctm_fbi_variantc", + 5303_u32 => "customplayer_ctm_fbi_variantd", + 5304_u32 => "customplayer_ctm_fbi_variante", + 5305_u32 => "customplayer_ctm_fbi_variantf", + 5306_u32 => "customplayer_ctm_fbi_variantg", + 5307_u32 => "customplayer_ctm_fbi_varianth", + 5308_u32 => "customplayer_ctm_fbi_variantb", + 5400_u32 => "customplayer_ctm_st6_variantk", + 5401_u32 => "customplayer_ctm_st6_variante", + 5402_u32 => "customplayer_ctm_st6_variantg", + 5403_u32 => "customplayer_ctm_st6_variantm", + 5404_u32 => "customplayer_ctm_st6_varianti", + 4619_u32 => "customplayer_ctm_st6_variantj", + 4680_u32 => "customplayer_ctm_st6_variantl", + 5405_u32 => "customplayer_ctm_st6_variantn", + 5500_u32 => "customplayer_tm_balkan_variantf", + 5501_u32 => "customplayer_tm_balkan_varianti", + 5502_u32 => "customplayer_tm_balkan_variantg", + 5503_u32 => "customplayer_tm_balkan_variantj", + 5504_u32 => "customplayer_tm_balkan_varianth", + 4718_u32 => "customplayer_tm_balkan_variantk", + 5505_u32 => "customplayer_tm_balkan_variantl", + 5600_u32 => "customplayer_ctm_sas", + 5601_u32 => "customplayer_ctm_sas_variantf", + 5602_u32 => "customplayer_ctm_sas_variantg", + 4711_u32 => "customplayer_ctm_swat_variante", + 4712_u32 => "customplayer_ctm_swat_variantf", + 4713_u32 => "customplayer_ctm_swat_variantg", + 4714_u32 => "customplayer_ctm_swat_varianth", + 4715_u32 => "customplayer_ctm_swat_varianti", + 4716_u32 => "customplayer_ctm_swat_variantj", + 4756_u32 => "customplayer_ctm_swat_variantk", + 4726_u32 => "customplayer_tm_professional_varf", + 4733_u32 => "customplayer_tm_professional_varf1", + 4734_u32 => "customplayer_tm_professional_varf2", + 4735_u32 => "customplayer_tm_professional_varf3", + 4736_u32 => "customplayer_tm_professional_varf4", + 4727_u32 => "customplayer_tm_professional_varg", + 4728_u32 => "customplayer_tm_professional_varh", + 4732_u32 => "customplayer_tm_professional_vari", + 4730_u32 => "customplayer_tm_professional_varj", + 4613_u32 => "customplayer_tm_professional_varf5", + 4749_u32 => "customplayer_ctm_gendarmerie_varianta", + 4750_u32 => "customplayer_ctm_gendarmerie_variantb", + 4751_u32 => "customplayer_ctm_gendarmerie_variantc", + 4752_u32 => "customplayer_ctm_gendarmerie_variantd", + 4753_u32 => "customplayer_ctm_gendarmerie_variante", + 4757_u32 => "customplayer_ctm_diver_varianta", + 4771_u32 => "customplayer_ctm_diver_variantb", + 4772_u32 => "customplayer_ctm_diver_variantc", + 4773_u32 => "customplayer_tm_jungle_raider_varianta", + 4774_u32 => "customplayer_tm_jungle_raider_variantb", + 4775_u32 => "customplayer_tm_jungle_raider_variantc", + 4776_u32 => "customplayer_tm_jungle_raider_variantd", + 4777_u32 => "customplayer_tm_jungle_raider_variante", + 4778_u32 => "customplayer_tm_jungle_raider_variantf", + 4780_u32 => "customplayer_tm_jungle_raider_variantb2", + 4781_u32 => "customplayer_tm_jungle_raider_variantf2", +}; // Found in scripts/items/items_game.txt pub static WEAPINDICIES: phf::Map = phf_map! { @@ -1394,7 +1537,6 @@ pub static TYPEHM: phf::Map<&'static str, PropType> = phf_map! { "CCSPlayerController.m_iPawnArmor" => PropType::Controller, "CCSPlayerController.m_bPawnHasDefuser" => PropType::Controller, "CCSPlayerController.m_bPawnHasHelmet" => PropType::Controller, - "CCSPlayerController.m_nPawnCharacterDefIndex" => PropType::Controller, "CCSPlayerController.m_iPawnLifetimeStart" => PropType::Controller, "CCSPlayerController.m_iPawnLifetimeEnd" => PropType::Controller, "CCSPlayerController.m_iPawnGunGameLevel" => PropType::Controller, @@ -1564,6 +1706,7 @@ pub static TYPEHM: phf::Map<&'static str, PropType> = phf_map! { "game_time" => PropType::GameTime, "inventory" => PropType::Custom, "CCSPlayerPawn.m_bSpottedByMask" => PropType::Custom, + "agent_skin" => PropType::Custom, "is_alive" => PropType::Custom, @@ -1775,7 +1918,7 @@ pub static FRIENDLY_NAMES_MAPPING: phf::Map<&'static str, &'static str> = phf_ma "inventory" => "inventory", "entity_id" => "entity_id", "is_alive"=>"is_alive", - + "agent_skin" => "agent_skin", "rank" => "CCSPlayerController.m_iCompetitiveRanking", "rank_if_win" => "CCSPlayerController.m_iCompetitiveRankingPredicted_Win", diff --git a/src/parser/src/parser_thread_settings.rs b/src/parser/src/parser_thread_settings.rs index caec4aab..400ea34e 100644 --- a/src/parser/src/parser_thread_settings.rs +++ b/src/parser/src/parser_thread_settings.rs @@ -270,6 +270,7 @@ pub struct SpecialIDs { pub life_state: Option, pub h_owner_entity: Option, + pub agent_skin_idx: Option, } impl SpecialIDs { pub fn new() -> Self { @@ -302,6 +303,7 @@ impl SpecialIDs { orig_own_high: None, orig_own_low: None, life_state: None, + agent_skin_idx: None, } } } diff --git a/src/parser/src/prop_controller.rs b/src/parser/src/prop_controller.rs index 6d92f86e..0e15eb9f 100644 --- a/src/parser/src/prop_controller.rs +++ b/src/parser/src/prop_controller.rs @@ -31,6 +31,8 @@ pub const VELOCITY_Y_ID: u32 = 100000005; pub const VELOCITY_Z_ID: u32 = 100000006; pub const VELOCITY_ID: u32 = 100000007; +pub const AGENT_SKIN_ID: u32 = 100000009; + #[derive(Clone, Debug)] pub struct PropController { pub id: u32, @@ -226,6 +228,15 @@ impl PropController { is_player_prop: true, }); } + if self.wanted_player_props.contains(&("agent_skin".to_string())) { + self.prop_infos.push(PropInfo { + id: AGENT_SKIN_ID, + prop_type: PropType::Custom, + prop_name: "agent_skin".to_string(), + prop_friendly_name: "agent_skin".to_string(), + is_player_prop: true, + }); + } if self.wanted_player_props.contains(&("X".to_string())) { self.prop_infos.push(PropInfo { id: PLAYER_X_ID, @@ -405,11 +416,7 @@ impl PropController { }; if name.contains("CCSTeam.m_iTeamNum") || name.contains("CCSPlayerPawn.m_iTeamNum") - || name.contains("CCSPlayerController.m_iTeamNum") - || name.contains("CCSPlayerController.m_iszPlayerName") - || name.contains("CCSPlayerController.m_steamID") - || name.contains("CCSPlayerController.m_hPlayerPawn") - || name.contains("CCSPlayerController.m_bPawnIsAlive") + || name.contains("CCSPlayerController") || name.contains("m_hActiveWeapon") || name.contains("Weapons") || name.contains("OriginalOwnerXuid") @@ -458,6 +465,7 @@ impl PropController { "CCSPlayerPawn.CBodyComponentBaseAnimGraph.m_vecZ" => self.special_ids.cell_z_offset_player = Some(id), "CCSPlayerPawn.CCSPlayer_WeaponServices.m_hActiveWeapon" => self.special_ids.active_weapon = Some(id), "CCSPlayerPawn.m_lifeState" => self.special_ids.life_state = Some(id), + "CCSPlayerController.m_nPawnCharacterDefIndex" => self.special_ids.agent_skin_idx = Some(id), _ => {} }; }