3 string playerstats_last;
5 .float playerstats_addedglobalinfo;
6 float playerstats_requested;
7 .string playerstats_id;
9 void PlayerStats_Init()
13 playerstats_waitforme = TRUE;
14 uri = autocvar_g_playerstats_uri;
17 playerstats_db = db_create();
18 if(playerstats_db >= 0)
19 playerstats_waitforme = FALSE; // must wait for it at match end
21 PlayerStats_AddEvent(PLAYERSTATS_ALIVETIME);
22 PlayerStats_AddEvent(PLAYERSTATS_WINS);
23 PlayerStats_AddEvent(PLAYERSTATS_MATCHES);
24 PlayerStats_AddEvent(PLAYERSTATS_JOINS);
25 PlayerStats_AddEvent(PLAYERSTATS_SCOREBOARD_VALID);
26 PlayerStats_AddEvent(PLAYERSTATS_RANK);
28 PlayerStats_AddEvent(PLAYERSTATS_ACC_LASER_HIT);
29 PlayerStats_AddEvent(PLAYERSTATS_ACC_LASER_FIRED);
30 PlayerStats_AddEvent(PLAYERSTATS_ACC_SHOTGUN_HIT);
31 PlayerStats_AddEvent(PLAYERSTATS_ACC_SHOTGUN_FIRED);
32 PlayerStats_AddEvent(PLAYERSTATS_ACC_UZI_HIT);
33 PlayerStats_AddEvent(PLAYERSTATS_ACC_UZI_FIRED);
34 PlayerStats_AddEvent(PLAYERSTATS_ACC_GRENADE_LAUNCHER_HIT);
35 PlayerStats_AddEvent(PLAYERSTATS_ACC_GRENADE_LAUNCHER_FIRED);
36 PlayerStats_AddEvent(PLAYERSTATS_ACC_ELECTRO_HIT);
37 PlayerStats_AddEvent(PLAYERSTATS_ACC_ELECTRO_FIRED);
38 PlayerStats_AddEvent(PLAYERSTATS_ACC_CRYLINK_HIT);
39 PlayerStats_AddEvent(PLAYERSTATS_ACC_CRYLINK_FIRED);
40 PlayerStats_AddEvent(PLAYERSTATS_ACC_NEX_HIT);
41 PlayerStats_AddEvent(PLAYERSTATS_ACC_NEX_FIRED);
42 PlayerStats_AddEvent(PLAYERSTATS_ACC_HAGAR_HIT);
43 PlayerStats_AddEvent(PLAYERSTATS_ACC_HAGAR_FIRED);
44 PlayerStats_AddEvent(PLAYERSTATS_ACC_ROCKET_LAUNCHER_HIT);
45 PlayerStats_AddEvent(PLAYERSTATS_ACC_ROCKET_LAUNCHER_FIRED);
46 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINSTANEX_HIT);
47 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINSTANEX_FIRED);
48 PlayerStats_AddEvent(PLAYERSTATS_ACC_SNIPERRIFLE_HIT);
49 PlayerStats_AddEvent(PLAYERSTATS_ACC_SNIPERRIFLE_FIRED);
50 PlayerStats_AddEvent(PLAYERSTATS_ACC_FIREBALL_HIT);
51 PlayerStats_AddEvent(PLAYERSTATS_ACC_FIREBALL_FIRED);
52 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINE_LAYER_HIT);
53 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINE_LAYER_FIRED);
54 PlayerStats_AddEvent(PLAYERSTATS_ACC_SEEKER_HIT);
55 PlayerStats_AddEvent(PLAYERSTATS_ACC_SEEKER_FIRED);
56 PlayerStats_AddEvent(PLAYERSTATS_ACC_TUBA_HIT);
57 PlayerStats_AddEvent(PLAYERSTATS_ACC_TUBA_FIRED);
59 PlayerStats_AddEvent(PLAYERSTATS_ACC_LASER_CNT_HIT);
60 PlayerStats_AddEvent(PLAYERSTATS_ACC_LASER_CNT_FIRED);
61 PlayerStats_AddEvent(PLAYERSTATS_ACC_SHOTGUN_CNT_HIT);
62 PlayerStats_AddEvent(PLAYERSTATS_ACC_SHOTGUN_CNT_FIRED);
63 PlayerStats_AddEvent(PLAYERSTATS_ACC_UZI_CNT_HIT);
64 PlayerStats_AddEvent(PLAYERSTATS_ACC_UZI_CNT_FIRED);
65 PlayerStats_AddEvent(PLAYERSTATS_ACC_GRENADE_LAUNCHER_CNT_HIT);
66 PlayerStats_AddEvent(PLAYERSTATS_ACC_GRENADE_LAUNCHER_CNT_FIRED);
67 PlayerStats_AddEvent(PLAYERSTATS_ACC_ELECTRO_CNT_HIT);
68 PlayerStats_AddEvent(PLAYERSTATS_ACC_ELECTRO_CNT_FIRED);
69 PlayerStats_AddEvent(PLAYERSTATS_ACC_CRYLINK_CNT_HIT);
70 PlayerStats_AddEvent(PLAYERSTATS_ACC_CRYLINK_CNT_FIRED);
71 PlayerStats_AddEvent(PLAYERSTATS_ACC_NEX_CNT_HIT);
72 PlayerStats_AddEvent(PLAYERSTATS_ACC_NEX_CNT_FIRED);
73 PlayerStats_AddEvent(PLAYERSTATS_ACC_HAGAR_CNT_HIT);
74 PlayerStats_AddEvent(PLAYERSTATS_ACC_HAGAR_CNT_FIRED);
75 PlayerStats_AddEvent(PLAYERSTATS_ACC_ROCKET_LAUNCHER_CNT_HIT);
76 PlayerStats_AddEvent(PLAYERSTATS_ACC_ROCKET_LAUNCHER_CNT_FIRED);
77 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINSTANEX_CNT_HIT);
78 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINSTANEX_CNT_FIRED);
79 PlayerStats_AddEvent(PLAYERSTATS_ACC_SNIPERRIFLE_CNT_HIT);
80 PlayerStats_AddEvent(PLAYERSTATS_ACC_SNIPERRIFLE_CNT_FIRED);
81 PlayerStats_AddEvent(PLAYERSTATS_ACC_FIREBALL_CNT_HIT);
82 PlayerStats_AddEvent(PLAYERSTATS_ACC_FIREBALL_CNT_FIRED);
83 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINE_LAYER_CNT_HIT);
84 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINE_LAYER_CNT_FIRED);
85 PlayerStats_AddEvent(PLAYERSTATS_ACC_SEEKER_CNT_HIT);
86 PlayerStats_AddEvent(PLAYERSTATS_ACC_SEEKER_CNT_FIRED);
87 PlayerStats_AddEvent(PLAYERSTATS_ACC_TUBA_CNT_HIT);
88 PlayerStats_AddEvent(PLAYERSTATS_ACC_TUBA_CNT_FIRED);
90 PlayerStats_AddEvent(PLAYERSTATS_ACC_LASER_FRAGS);
91 PlayerStats_AddEvent(PLAYERSTATS_ACC_SHOTGUN_FRAGS);
92 PlayerStats_AddEvent(PLAYERSTATS_ACC_UZI_FRAGS);
93 PlayerStats_AddEvent(PLAYERSTATS_ACC_GRENADE_LAUNCHER_FRAGS);
94 PlayerStats_AddEvent(PLAYERSTATS_ACC_ELECTRO_FRAGS);
95 PlayerStats_AddEvent(PLAYERSTATS_ACC_CRYLINK_FRAGS);
96 PlayerStats_AddEvent(PLAYERSTATS_ACC_NEX_FRAGS);
97 PlayerStats_AddEvent(PLAYERSTATS_ACC_HAGAR_FRAGS);
98 PlayerStats_AddEvent(PLAYERSTATS_ACC_ROCKET_LAUNCHER_FRAGS);
99 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINSTANEX_FRAGS);
100 PlayerStats_AddEvent(PLAYERSTATS_ACC_SNIPERRIFLE_FRAGS);
101 PlayerStats_AddEvent(PLAYERSTATS_ACC_FIREBALL_FRAGS);
102 PlayerStats_AddEvent(PLAYERSTATS_ACC_MINE_LAYER_FRAGS);
103 PlayerStats_AddEvent(PLAYERSTATS_ACC_SEEKER_FRAGS);
104 PlayerStats_AddEvent(PLAYERSTATS_ACC_TUBA_FRAGS);
106 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3);
107 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5);
108 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10);
109 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15);
110 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20);
111 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25);
112 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30);
113 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_BOTLIKE);
114 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD);
115 PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM);
118 void PlayerStats_AddPlayer(entity e)
120 if(playerstats_db < 0)
123 if(e.crypto_idfp != "" && e.cvar_cl_allow_uidtracking == 1)
124 e.playerstats_id = strzone(e.crypto_idfp);
125 else if(clienttype(e) == CLIENTTYPE_BOT)
126 e.playerstats_id = strzone(sprintf("bot#%d", e.playerid));
128 e.playerstats_id = strzone(sprintf("player#%d", e.playerid));
134 key = sprintf("%s:*", e.playerstats_id);
137 p = db_get(playerstats_db, key);
142 db_put(playerstats_db, key, playerstats_last);
143 strunzone(playerstats_last);
146 db_put(playerstats_db, key, "#");
147 playerstats_last = strzone(e.playerstats_id);
151 void PlayerStats_AddTeam(float t)
153 if(playerstats_db < 0)
157 key = sprintf("%d", t);
160 p = db_get(playerstats_db, key);
165 db_put(playerstats_db, key, teamstats_last);
166 strunzone(teamstats_last);
169 db_put(playerstats_db, key, "#");
170 teamstats_last = strzone(key);
174 void PlayerStats_AddEvent(string event_id)
176 if(playerstats_db < 0)
180 key = sprintf("*:%s", event_id);
183 p = db_get(playerstats_db, key);
188 db_put(playerstats_db, key, events_last);
189 strunzone(events_last);
192 db_put(playerstats_db, key, "#");
193 events_last = strzone(event_id);
197 void PlayerStats_Event(entity e, string event_id, float value)
199 if(!e.playerstats_id || playerstats_db < 0)
204 key = sprintf("%s:%s", e.playerstats_id, event_id);
205 val = stof(db_get(playerstats_db, key));
207 db_put(playerstats_db, key, ftos(val));
210 void PlayerStats_TeamScore(float t, string event_id, float value)
214 key = sprintf("team#%d:%s", t, event_id);
215 val = stof(db_get(playerstats_db, key));
217 db_put(playerstats_db, key, ftos(val));
220 void PlayerStats_Sent_URI_Get_Callback(float id, float status, string data)
222 if(playerstats_requested)
223 playerstats_waitforme = TRUE;
229 A collection of lines of the format <key> SPACE <value> NEWLINE, where
230 <key> is always a single character.
232 The following keys are defined:
234 V: format version (always 1) - this MUST be the first line!
235 #: comment (MUST be ignored by any parser)
236 R: release information on the server
237 T: time at which the game ended
240 S: "hostname" of the server
241 C: number of "unpure" cvar changes
243 t: team ID; all following "P" lines will be players on this team
244 P: player ID of an existing player; this also sets the owner for all following "n" and "e" lines (lower case!)
245 n: nickname of the player (optional)
246 e: followed by an event name, a space, and the event count/score
248 alivetime: total playing time of the player
249 wins: number of games won (can only be set if matches is set)
250 matches: number of matches played to the end (not aborted by map switch)
251 joins: number of matches joined (always 1 unless player never played during the match)
252 scoreboardvalid: set to 1 if the player was there at the end of the match
253 total-<scoreboardname>: total score of that scoreboard item
254 scoreboard-<scoreboardname>: end-of-game score of that scoreboard item (can differ in non-team games)
255 achievement-<achievementname>: achievement counters
256 rank <number>: rank of player
259 //#NO AUTOCVARS START
260 void PlayerStats_Shutdown()
270 if(playerstats_db < 0)
273 uri = autocvar_g_playerstats_uri;
279 db_dump(playerstats_db, "foo.db");
281 bufstr_set(b, i++, "V 1");
283 bufstr_set(b, i++, sprintf("R %s", WATERMARK()));
285 bufstr_set(b, i++, sprintf("T %s.%06d", strftime(FALSE, "%s"), floor(random() * 1000000)));
286 bufstr_set(b, i++, sprintf("G %s", GetGametype()));
287 bufstr_set(b, i++, sprintf("M %s", GetMapname()));
288 bufstr_set(b, i++, sprintf("S %s", cvar_string("hostname")));
289 bufstr_set(b, i++, sprintf("C %d", cvar_purechanges_count));
293 winner = PlayerScore_Sort(score_dummyfield);
294 bufstr_set(b, i++, sprintf("W %d", winner.team));
295 for(t = teamstats_last; (tn = db_get(playerstats_db, sprintf("%s", t))) != ""; t = tn)
297 bufstr_set(b, i++, strcat("t ", t));
298 for(p = playerstats_last; (pn = db_get(playerstats_db, sprintf("%s:*", p))) != ""; p = pn)
300 tt = db_get(playerstats_db, sprintf("%s:_team", p));
304 bufstr_set(b, i++, sprintf("P %s", p));
305 nn = db_get(playerstats_db, sprintf("%s:_netname", p));
307 bufstr_set(b, i++, sprintf("n %s", nn));
308 for(e = events_last; (en = db_get(playerstats_db, sprintf("*:%s", e))) != ""; e = en)
311 v = stof(db_get(playerstats_db, sprintf("%s:%s", p, e)));
313 bufstr_set(b, i++, sprintf("e %s %g", e, v));
316 bufstr_set(b, i++, "");
320 for(p = playerstats_last; (pn = db_get(playerstats_db, sprintf("%s:*", p))) != ""; p = pn)
322 bufstr_set(b, i++, sprintf("P %s", p));
323 nn = db_get(playerstats_db, sprintf("%s:_netname", p));
325 bufstr_set(b, i++, sprintf("n %s", nn));
326 for(e = events_last; (en = db_get(playerstats_db, sprintf("*:%s", e))) != ""; e = en)
329 v = stof(db_get(playerstats_db, sprintf("%s:%s", p, e)));
331 bufstr_set(b, i++, sprintf("e %s %g", e, v));
334 bufstr_set(b, i++, "");
337 if(autocvar_g_playerstats_debug)
339 for(i = 0; i < buf_getsize(b); ++i)
340 print(bufstr_get(b, i), "\n");
343 if(crypto_uri_postbuf(uri, URI_GET_PLAYERSTATS_SENT, "text/plain", "\n", b, 0))
344 playerstats_requested = TRUE;
346 playerstats_waitforme = TRUE; // if posting fails, we must continue anyway
351 playerstats_waitforme = TRUE;
353 db_close(playerstats_db);
358 void PlayerStats_AddGlobalInfo(entity p)
360 if(playerstats_db < 0)
362 if(!p.playerstats_id || playerstats_db < 0)
364 p.playerstats_addedglobalinfo = TRUE;
368 PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
371 PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
373 if(p.cvar_cl_allow_uid2name == 1 || clienttype(p) == CLIENTTYPE_BOT)
374 db_put(playerstats_db, sprintf("%s:_netname", p.playerstats_id), p.netname);
377 db_put(playerstats_db, sprintf("%s:_team", p.playerstats_id), ftos(p.team));
380 PlayerStats_Event(p, PLAYERSTATS_JOINS, 1);
382 strunzone(p.playerstats_id);
383 p.playerstats_id = string_null;
386 void PlayerStats_Accuracy(entity p)
391 PlayerStats_Event(p, PLAYERSTATS_ACC_LASER_HIT, a.accuracy_hit[WEP_LASER-1]);
392 PlayerStats_Event(p, PLAYERSTATS_ACC_LASER_FIRED, a.accuracy_fired[WEP_LASER-1]);
393 PlayerStats_Event(p, PLAYERSTATS_ACC_SHOTGUN_HIT, a.accuracy_hit[WEP_SHOTGUN-1]);
394 PlayerStats_Event(p, PLAYERSTATS_ACC_SHOTGUN_FIRED, a.accuracy_fired[WEP_SHOTGUN-1]);
395 PlayerStats_Event(p, PLAYERSTATS_ACC_UZI_HIT, a.accuracy_hit[WEP_UZI-1]);
396 PlayerStats_Event(p, PLAYERSTATS_ACC_UZI_FIRED, a.accuracy_fired[WEP_UZI-1]);
397 PlayerStats_Event(p, PLAYERSTATS_ACC_GRENADE_LAUNCHER_HIT, a.accuracy_hit[WEP_GRENADE_LAUNCHER-1]);
398 PlayerStats_Event(p, PLAYERSTATS_ACC_GRENADE_LAUNCHER_FIRED, a.accuracy_fired[WEP_GRENADE_LAUNCHER-1]);
399 PlayerStats_Event(p, PLAYERSTATS_ACC_ELECTRO_HIT, a.accuracy_hit[WEP_ELECTRO-1]);
400 PlayerStats_Event(p, PLAYERSTATS_ACC_ELECTRO_FIRED, a.accuracy_fired[WEP_ELECTRO-1]);
401 PlayerStats_Event(p, PLAYERSTATS_ACC_CRYLINK_HIT, a.accuracy_hit[WEP_CRYLINK-1]);
402 PlayerStats_Event(p, PLAYERSTATS_ACC_CRYLINK_FIRED, a.accuracy_fired[WEP_CRYLINK-1]);
403 PlayerStats_Event(p, PLAYERSTATS_ACC_NEX_HIT, a.accuracy_hit[WEP_NEX-1]);
404 PlayerStats_Event(p, PLAYERSTATS_ACC_NEX_FIRED, a.accuracy_fired[WEP_NEX-1]);
405 PlayerStats_Event(p, PLAYERSTATS_ACC_HAGAR_HIT, a.accuracy_hit[WEP_HAGAR-1]);
406 PlayerStats_Event(p, PLAYERSTATS_ACC_HAGAR_FIRED, a.accuracy_fired[WEP_HAGAR-1]);
407 PlayerStats_Event(p, PLAYERSTATS_ACC_ROCKET_LAUNCHER_HIT, a.accuracy_hit[WEP_ROCKET_LAUNCHER-1]);
408 PlayerStats_Event(p, PLAYERSTATS_ACC_ROCKET_LAUNCHER_FIRED, a.accuracy_fired[WEP_ROCKET_LAUNCHER-1]);
409 PlayerStats_Event(p, PLAYERSTATS_ACC_MINSTANEX_HIT, a.accuracy_hit[WEP_MINSTANEX-1]);
410 PlayerStats_Event(p, PLAYERSTATS_ACC_MINSTANEX_FIRED, a.accuracy_fired[WEP_MINSTANEX-1]);
411 PlayerStats_Event(p, PLAYERSTATS_ACC_SNIPERRIFLE_HIT, a.accuracy_hit[WEP_SNIPERRIFLE-1]);
412 PlayerStats_Event(p, PLAYERSTATS_ACC_SNIPERRIFLE_FIRED, a.accuracy_fired[WEP_SNIPERRIFLE-1]);
413 PlayerStats_Event(p, PLAYERSTATS_ACC_FIREBALL_HIT, a.accuracy_hit[WEP_FIREBALL-1]);
414 PlayerStats_Event(p, PLAYERSTATS_ACC_FIREBALL_FIRED, a.accuracy_fired[WEP_FIREBALL-1]);
415 PlayerStats_Event(p, PLAYERSTATS_ACC_MINE_LAYER_HIT, a.accuracy_hit[WEP_MINE_LAYER-1]);
416 PlayerStats_Event(p, PLAYERSTATS_ACC_MINE_LAYER_FIRED, a.accuracy_fired[WEP_MINE_LAYER-1]);
417 PlayerStats_Event(p, PLAYERSTATS_ACC_SEEKER_HIT, a.accuracy_hit[WEP_SEEKER-1]);
418 PlayerStats_Event(p, PLAYERSTATS_ACC_SEEKER_FIRED, a.accuracy_fired[WEP_SEEKER-1]);
419 PlayerStats_Event(p, PLAYERSTATS_ACC_TUBA_HIT, a.accuracy_hit[WEP_TUBA-1]);
420 PlayerStats_Event(p, PLAYERSTATS_ACC_TUBA_FIRED, a.accuracy_fired[WEP_TUBA-1]);
422 PlayerStats_Event(p, PLAYERSTATS_ACC_LASER_CNT_HIT, a.accuracy_cnt_hit[WEP_LASER-1]);
423 PlayerStats_Event(p, PLAYERSTATS_ACC_LASER_CNT_FIRED, a.accuracy_cnt_fired[WEP_LASER-1]);
424 PlayerStats_Event(p, PLAYERSTATS_ACC_SHOTGUN_CNT_HIT, a.accuracy_cnt_hit[WEP_SHOTGUN-1]);
425 PlayerStats_Event(p, PLAYERSTATS_ACC_SHOTGUN_CNT_FIRED, a.accuracy_cnt_fired[WEP_SHOTGUN-1]);
426 PlayerStats_Event(p, PLAYERSTATS_ACC_UZI_CNT_HIT, a.accuracy_cnt_hit[WEP_UZI-1]);
427 PlayerStats_Event(p, PLAYERSTATS_ACC_UZI_CNT_FIRED, a.accuracy_cnt_fired[WEP_UZI-1]);
428 PlayerStats_Event(p, PLAYERSTATS_ACC_GRENADE_LAUNCHER_CNT_HIT, a.accuracy_cnt_hit[WEP_GRENADE_LAUNCHER-1]);
429 PlayerStats_Event(p, PLAYERSTATS_ACC_GRENADE_LAUNCHER_CNT_FIRED, a.accuracy_cnt_fired[WEP_GRENADE_LAUNCHER-1]);
430 PlayerStats_Event(p, PLAYERSTATS_ACC_ELECTRO_CNT_HIT, a.accuracy_cnt_hit[WEP_ELECTRO-1]);
431 PlayerStats_Event(p, PLAYERSTATS_ACC_ELECTRO_CNT_FIRED, a.accuracy_cnt_fired[WEP_ELECTRO-1]);
432 PlayerStats_Event(p, PLAYERSTATS_ACC_CRYLINK_CNT_HIT, a.accuracy_cnt_hit[WEP_CRYLINK-1]);
433 PlayerStats_Event(p, PLAYERSTATS_ACC_CRYLINK_CNT_FIRED, a.accuracy_cnt_fired[WEP_CRYLINK-1]);
434 PlayerStats_Event(p, PLAYERSTATS_ACC_NEX_CNT_HIT, a.accuracy_cnt_hit[WEP_NEX-1]);
435 PlayerStats_Event(p, PLAYERSTATS_ACC_NEX_CNT_FIRED, a.accuracy_cnt_fired[WEP_NEX-1]);
436 PlayerStats_Event(p, PLAYERSTATS_ACC_HAGAR_CNT_HIT, a.accuracy_cnt_hit[WEP_HAGAR-1]);
437 PlayerStats_Event(p, PLAYERSTATS_ACC_HAGAR_CNT_FIRED, a.accuracy_cnt_fired[WEP_HAGAR-1]);
438 PlayerStats_Event(p, PLAYERSTATS_ACC_ROCKET_LAUNCHER_CNT_HIT, a.accuracy_cnt_hit[WEP_ROCKET_LAUNCHER-1]);
439 PlayerStats_Event(p, PLAYERSTATS_ACC_ROCKET_LAUNCHER_CNT_FIRED, a.accuracy_cnt_fired[WEP_ROCKET_LAUNCHER-1]);
440 PlayerStats_Event(p, PLAYERSTATS_ACC_MINSTANEX_CNT_HIT, a.accuracy_cnt_hit[WEP_MINSTANEX-1]);
441 PlayerStats_Event(p, PLAYERSTATS_ACC_MINSTANEX_CNT_FIRED, a.accuracy_cnt_fired[WEP_MINSTANEX-1]);
442 PlayerStats_Event(p, PLAYERSTATS_ACC_SNIPERRIFLE_CNT_HIT, a.accuracy_cnt_hit[WEP_SNIPERRIFLE-1]);
443 PlayerStats_Event(p, PLAYERSTATS_ACC_SNIPERRIFLE_CNT_FIRED, a.accuracy_cnt_fired[WEP_SNIPERRIFLE-1]);
444 PlayerStats_Event(p, PLAYERSTATS_ACC_FIREBALL_CNT_HIT, a.accuracy_cnt_hit[WEP_FIREBALL-1]);
445 PlayerStats_Event(p, PLAYERSTATS_ACC_FIREBALL_CNT_FIRED, a.accuracy_cnt_fired[WEP_FIREBALL-1]);
446 PlayerStats_Event(p, PLAYERSTATS_ACC_MINE_LAYER_CNT_HIT, a.accuracy_cnt_hit[WEP_MINE_LAYER-1]);
447 PlayerStats_Event(p, PLAYERSTATS_ACC_MINE_LAYER_CNT_FIRED, a.accuracy_cnt_fired[WEP_MINE_LAYER-1]);
448 PlayerStats_Event(p, PLAYERSTATS_ACC_SEEKER_CNT_HIT, a.accuracy_cnt_hit[WEP_SEEKER-1]);
449 PlayerStats_Event(p, PLAYERSTATS_ACC_SEEKER_CNT_FIRED, a.accuracy_cnt_fired[WEP_SEEKER-1]);
450 PlayerStats_Event(p, PLAYERSTATS_ACC_TUBA_CNT_HIT, a.accuracy_cnt_hit[WEP_TUBA-1]);
451 PlayerStats_Event(p, PLAYERSTATS_ACC_TUBA_CNT_FIRED, a.accuracy_cnt_fired[WEP_TUBA-1]);
453 PlayerStats_Event(p, PLAYERSTATS_ACC_LASER_FRAGS, a.accuracy_frags[WEP_LASER-1]);
454 PlayerStats_Event(p, PLAYERSTATS_ACC_SHOTGUN_FRAGS, a.accuracy_frags[WEP_SHOTGUN-1]);
455 PlayerStats_Event(p, PLAYERSTATS_ACC_UZI_FRAGS, a.accuracy_frags[WEP_UZI-1]);
456 PlayerStats_Event(p, PLAYERSTATS_ACC_GRENADE_LAUNCHER_FRAGS, a.accuracy_frags[WEP_GRENADE_LAUNCHER-1]);
457 PlayerStats_Event(p, PLAYERSTATS_ACC_ELECTRO_FRAGS, a.accuracy_frags[WEP_ELECTRO-1]);
458 PlayerStats_Event(p, PLAYERSTATS_ACC_CRYLINK_FRAGS, a.accuracy_frags[WEP_CRYLINK-1]);
459 PlayerStats_Event(p, PLAYERSTATS_ACC_NEX_FRAGS, a.accuracy_frags[WEP_NEX-1]);
460 PlayerStats_Event(p, PLAYERSTATS_ACC_HAGAR_FRAGS, a.accuracy_frags[WEP_HAGAR-1]);
461 PlayerStats_Event(p, PLAYERSTATS_ACC_ROCKET_LAUNCHER_FRAGS, a.accuracy_frags[WEP_ROCKET_LAUNCHER-1]);
462 PlayerStats_Event(p, PLAYERSTATS_ACC_MINSTANEX_FRAGS, a.accuracy_frags[WEP_MINSTANEX-1]);
463 PlayerStats_Event(p, PLAYERSTATS_ACC_SNIPERRIFLE_FRAGS, a.accuracy_frags[WEP_SNIPERRIFLE-1]);
464 PlayerStats_Event(p, PLAYERSTATS_ACC_FIREBALL_FRAGS, a.accuracy_frags[WEP_FIREBALL-1]);
465 PlayerStats_Event(p, PLAYERSTATS_ACC_MINE_LAYER_FRAGS, a.accuracy_frags[WEP_MINE_LAYER-1]);
466 PlayerStats_Event(p, PLAYERSTATS_ACC_SEEKER_FRAGS, a.accuracy_frags[WEP_SEEKER-1]);
467 PlayerStats_Event(p, PLAYERSTATS_ACC_TUBA_FRAGS, a.accuracy_frags[WEP_TUBA-1]);
470 void PlayerStats_EndMatch(float finished)
473 winner = PlayerScore_Sort(score_dummyfield);
476 PlayerScore_PlayerStats(p);
477 PlayerStats_Accuracy(p);
478 PlayerStats_Event(p, PLAYERSTATS_SCOREBOARD_VALID, 1);
481 PlayerStats_Event(p, PLAYERSTATS_WINS, p.winning);
482 PlayerStats_Event(p, PLAYERSTATS_MATCHES, 1);
483 PlayerStats_Event(p, PLAYERSTATS_RANK, p.score_dummyfield);