@@ -7,6 +7,7 @@ use crate::stringtables::UserInfo;
7
7
use crate :: variants:: * ;
8
8
use ahash:: AHashMap ;
9
9
use ahash:: RandomState ;
10
+ use csgoproto:: cstrike15_usermessages:: CCSUsrMsg_ServerRankUpdate ;
10
11
use csgoproto:: netmessages:: csvcmsg_game_event_list:: Descriptor_t ;
11
12
use csgoproto:: netmessages:: CSVCMsg_GameEventList ;
12
13
use csgoproto:: networkbasetypes:: csvcmsg_game_event:: Key_t ;
@@ -24,6 +25,8 @@ static INTERNALEVENTFIELDS: &'static [&str] = &[
24
25
"assister_pawn" ,
25
26
] ;
26
27
const ENTITYIDNONE : i32 = 2047 ;
28
+ // https://developer.valvesoftware.com/wiki/SteamID
29
+ const STEAMID64INDIVIDUALIDENTIFIER : u64 = 0x0110000100000000 ;
27
30
28
31
impl Parser {
29
32
// Message that should come before first game event
@@ -81,15 +84,15 @@ impl ParserThread {
81
84
} ) ;
82
85
Ok ( ( ) )
83
86
}
84
- fn find_user_by_userid ( & self , userid : i32 ) -> Option < & UserInfo > {
87
+ pub fn find_user_by_userid ( & self , userid : i32 ) -> Option < & UserInfo > {
85
88
for player in self . stringtable_players . values ( ) {
86
89
if player. userid == userid {
87
90
return Some ( player) ;
88
91
}
89
92
}
90
93
return None ;
91
94
}
92
- fn entity_id_from_userid ( & self , userid : i32 ) -> Option < i32 > {
95
+ pub fn entity_id_from_userid ( & self , userid : i32 ) -> Option < i32 > {
93
96
if let Some ( userinfo) = self . find_user_by_userid ( userid) {
94
97
for player in self . players . values ( ) {
95
98
if player. steamid == Some ( userinfo. steamid ) {
@@ -99,7 +102,7 @@ impl ParserThread {
99
102
}
100
103
return None ;
101
104
}
102
- fn find_extra ( & self , fields : & Vec < EventField > ) -> Result < Vec < EventField > , DemoParserError > {
105
+ pub fn find_extra ( & self , fields : & Vec < EventField > ) -> Result < Vec < EventField > , DemoParserError > {
103
106
let mut extra_fields = vec ! [ ] ;
104
107
// Always add tick to event
105
108
extra_fields. push ( EventField {
@@ -132,7 +135,7 @@ impl ParserThread {
132
135
extra_fields. extend ( self . find_non_player_props ( ) ) ;
133
136
Ok ( extra_fields)
134
137
}
135
- fn generate_empty_fields ( & self , prefix : & str ) -> Vec < EventField > {
138
+ pub fn generate_empty_fields ( & self , prefix : & str ) -> Vec < EventField > {
136
139
let mut extra_fields = vec ! [ ] ;
137
140
// when pointer fails for some reason we need to add None to output
138
141
for prop_info in & self . prop_controller . prop_infos {
@@ -159,7 +162,7 @@ impl ParserThread {
159
162
extra_fields
160
163
}
161
164
162
- fn find_non_player_props ( & self ) -> Vec < EventField > {
165
+ pub fn find_non_player_props ( & self ) -> Vec < EventField > {
163
166
let mut extra_fields = vec ! [ ] ;
164
167
for prop_info in & self . prop_controller . prop_infos {
165
168
let fields = match prop_info. prop_type {
@@ -172,7 +175,7 @@ impl ParserThread {
172
175
extra_fields
173
176
}
174
177
175
- fn find_other_rules_props ( & self , prop_info : & PropInfo ) -> Vec < EventField > {
178
+ pub fn find_other_rules_props ( & self , prop_info : & PropInfo ) -> Vec < EventField > {
176
179
let mut extra_fields = vec ! [ ] ;
177
180
let prop = match self . rules_entity_id {
178
181
Some ( entid) => match self . get_prop_from_ent ( & prop_info. id , & entid) {
@@ -187,7 +190,7 @@ impl ParserThread {
187
190
} ) ;
188
191
extra_fields
189
192
}
190
- fn find_other_team_props ( & self , prop_info : & PropInfo ) -> Vec < EventField > {
193
+ pub fn find_other_team_props ( & self , prop_info : & PropInfo ) -> Vec < EventField > {
191
194
let mut extra_fields = vec ! [ ] ;
192
195
let t = self . teams . team2_entid ;
193
196
let ct = self . teams . team3_entid ;
@@ -259,7 +262,7 @@ impl ParserThread {
259
262
}
260
263
extra_pairs
261
264
}
262
- fn create_player_name_field ( & self , entity_id : i32 , prefix : & str ) -> EventField {
265
+ pub fn create_player_name_field ( & self , entity_id : i32 , prefix : & str ) -> EventField {
263
266
if entity_id == ENTITYIDNONE {
264
267
return EventField {
265
268
name : prefix. to_owned ( ) + "_name" ,
@@ -278,7 +281,7 @@ impl ParserThread {
278
281
data : data,
279
282
}
280
283
}
281
- fn create_player_steamid_field ( & self , entity_id : i32 , prefix : & str ) -> EventField {
284
+ pub fn create_player_steamid_field ( & self , entity_id : i32 , prefix : & str ) -> EventField {
282
285
if entity_id == ENTITYIDNONE {
283
286
return EventField {
284
287
name : prefix. to_owned ( ) + "_steamid" ,
@@ -297,6 +300,68 @@ impl ParserThread {
297
300
data : data,
298
301
}
299
302
}
303
+ pub fn player_from_steamid32 ( & self , steamid32 : i32 ) -> Option < i32 > {
304
+ for ( _entid, player) in & self . players {
305
+ if let Some ( steamid) = player. steamid {
306
+ if steamid - STEAMID64INDIVIDUALIDENTIFIER == steamid32 as u64 {
307
+ return Some ( player. player_entity_id . unwrap ( ) ) ;
308
+ }
309
+ }
310
+ }
311
+ None
312
+ }
313
+ pub fn create_custom_event_rank_update ( & mut self , msg_bytes : & [ u8 ] ) -> Result < ( ) , DemoParserError > {
314
+ if !self . wanted_events . contains ( & "rank_update" . to_string ( ) ) {
315
+ return Ok ( ( ) ) ;
316
+ }
317
+ let update_msg: CCSUsrMsg_ServerRankUpdate = match Message :: parse_from_bytes ( & msg_bytes) {
318
+ Ok ( m) => m,
319
+ Err ( _e) => return Err ( DemoParserError :: MalformedMessage ) ,
320
+ } ;
321
+
322
+ for update in update_msg. rank_update {
323
+ let mut fields = vec ! [ ] ;
324
+
325
+ let entity_id = match self . player_from_steamid32 ( update. account_id . unwrap ( ) ) {
326
+ Some ( eid) => eid,
327
+ None => continue ,
328
+ } ;
329
+
330
+ fields. push ( self . create_player_name_field ( entity_id, "user" ) ) ;
331
+ fields. push ( self . create_player_steamid_field ( entity_id, "user" ) ) ;
332
+ fields. extend ( self . find_extra_props_events ( entity_id, "user" ) ) ;
333
+
334
+ fields. push ( EventField {
335
+ data : Some ( Variant :: I32 ( update. num_wins ( ) ) ) ,
336
+ name : "num_wins" . to_string ( ) ,
337
+ } ) ;
338
+ fields. push ( EventField {
339
+ data : Some ( Variant :: I32 ( update. rank_old ( ) ) ) ,
340
+ name : "rank_old" . to_string ( ) ,
341
+ } ) ;
342
+ fields. push ( EventField {
343
+ data : Some ( Variant :: I32 ( update. rank_new ( ) ) ) ,
344
+ name : "rank_new" . to_string ( ) ,
345
+ } ) ;
346
+ fields. push ( EventField {
347
+ data : Some ( Variant :: F32 ( update. rank_change ( ) ) ) ,
348
+ name : "rank_change" . to_string ( ) ,
349
+ } ) ;
350
+ fields. push ( EventField {
351
+ data : Some ( Variant :: I32 ( update. rank_type_id ( ) ) ) ,
352
+ name : "rank_type_id" . to_string ( ) ,
353
+ } ) ;
354
+ let ge = GameEvent {
355
+ name : "rank_update" . to_string ( ) ,
356
+ fields : fields,
357
+ tick : self . tick ,
358
+ } ;
359
+ self . game_events . push ( ge) ;
360
+ self . game_events_counter . insert ( "rank_update" . to_string ( ) ) ;
361
+ }
362
+
363
+ Ok ( ( ) )
364
+ }
300
365
}
301
366
// what is this shit
302
367
fn parse_key ( key : & Key_t ) -> Option < Variant > {
0 commit comments