Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
playerstats.qh File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PlayerStats_GameReport_Event_Player(ent, eventid, val)
#define PlayerStats_GameReport_Event_Team(team, eventid, val)

Functions

void PlayerStats_GameReport (bool finished)
void PlayerStats_GameReport_Accuracy (entity p)
void PlayerStats_GameReport_AddEvent (string event_id)
void PlayerStats_GameReport_AddPlayer (entity e)
void PlayerStats_GameReport_AddTeam (float t)
float PlayerStats_GameReport_Event (string prefix, string event_id, float value)
void PlayerStats_GameReport_FinalizePlayer (entity p)
void PlayerStats_GameReport_Handler (entity fh, entity pass, float status)
void PlayerStats_GameReport_Init ()
void PlayerStats_GameReport_Reset_All ()
void PlayerStats_PlayerBasic (entity joiningplayer, float newrequest)
void PlayerStats_PlayerBasic_CheckUpdate (entity joiningplayer)
void PlayerStats_PlayerBasic_Handler (entity fh, entity p, float status)
void PlayerStats_PlayerDetail ()
void PlayerStats_PlayerDetail_CheckUpdate ()
void PlayerStats_PlayerDetail_Handler (entity fh, entity p, float status)
 REPLICATE_INIT (bool, cvar_cl_allow_uidranking)
 REPLICATE_INIT (int, cvar_cl_allow_uid2name)
 REPLICATE_INIT (int, cvar_cl_allow_uidtracking)

Variables

string autocvar_g_playerstats_gamereport_ladder
string autocvar_g_playerstats_gamereport_uri = "https://stats.xonotic.org/stats/submit"
string autocvar_g_playerstats_playerbasic_uri = "https://stats.xonotic.org"
float autocvar_g_playerstats_playerdetail_autoupdatetime = 1800
string autocvar_g_playerstats_playerdetail_uri = "https://stats.xonotic.org/player/me"
const string PLAYERSTATS_ACHIEVEMENT_BOTLIKE = "achievement-botlike"
const string PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD = "achievement-firstblood"
const string PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM = "achievement-firstvictim"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10 = "achievement-kill-spree-10"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15 = "achievement-kill-spree-15"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20 = "achievement-kill-spree-20"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25 = "achievement-kill-spree-25"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3 = "achievement-kill-spree-3"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30 = "achievement-kill-spree-30"
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5 = "achievement-kill-spree-5"
const string PLAYERSTATS_ALIVETIME = "alivetime"
const string PLAYERSTATS_ANTICHEAT = "anticheat-"
const string PLAYERSTATS_AVGLATENCY = "avglatency"
float playerstats_basicstatus
bool PlayerStats_GameReport_DelayMapVote
const string PLAYERSTATS_HANDICAP_GIVEN = "handicapgiven"
const string PLAYERSTATS_HANDICAP_TAKEN = "handicaptaken"
string playerstats_id
const string PLAYERSTATS_JOINS = "joins"
const string PLAYERSTATS_MATCHES = "matches"
float PlayerStats_PlayerDetail_Status = PS_D_STATUS_IDLE
const string PLAYERSTATS_RANK = "rank"
const string PLAYERSTATS_SCOREBOARD = "scoreboard-"
const string PLAYERSTATS_SCOREBOARD_POS = "scoreboardpos"
const string PLAYERSTATS_SCOREBOARD_VALID = "scoreboardvalid"
const string PLAYERSTATS_TOTAL = "total-"
const string PLAYERSTATS_WINS = "wins"
float PS_B_IN_DB = -1
const float PS_B_STATUS_ERROR = -2
const float PS_B_STATUS_IDLE = -1
const float PS_B_STATUS_RECEIVED = 1
const float PS_B_STATUS_UPDATING = 2
const float PS_B_STATUS_WAITING = 0
int PS_D_IN_DB = -1
string PS_D_IN_EVL
float PS_D_LASTGAMECOUNT
float PS_D_NEXTUPDATETIME
const float PS_D_STATUS_ERROR = -2
const float PS_D_STATUS_IDLE = -1
const float PS_D_STATUS_RECEIVED = 1
const float PS_D_STATUS_WAITING = 0
int PS_GR_OUT_DB = -1
string PS_GR_OUT_EVL
string PS_GR_OUT_PL
string PS_GR_OUT_TL
float scoreboard_pos

Macro Definition Documentation

◆ PlayerStats_GameReport_Event_Player

#define PlayerStats_GameReport_Event_Player ( ent,
eventid,
val )
Value:
PlayerStats_GameReport_Event(ent.playerstats_id, eventid, val)
float PlayerStats_GameReport_Event(string prefix, string event_id, float value)

Definition at line 76 of file playerstats.qh.

Referenced by anticheat_report_to_playerstats(), GiveFrags(), Obituary(), PlayerDamage(), PlayerScore_Add(), PlayerScore_PlayerStats(), PlayerStats_GameReport(), PlayerStats_GameReport_FinalizePlayer(), and PutObserverInServer().

◆ PlayerStats_GameReport_Event_Team

#define PlayerStats_GameReport_Event_Team ( team,
eventid,
val )
Value:
PlayerStats_GameReport_Event(sprintf("team#%d", team), eventid, val)
int team
Definition main.qh:188

Definition at line 77 of file playerstats.qh.

Referenced by PlayerScore_TeamStats().

Function Documentation

◆ PlayerStats_GameReport()

void PlayerStats_GameReport ( bool finished)

Definition at line 229 of file playerstats.qc.

230{
231 if(PS_GR_OUT_DB < 0) { return; }
232
233 PlayerScore_Sort(score_dummyfield, 0, false, false);
234 PlayerScore_Sort(scoreboard_pos, 1, true, true);
236
237 FOREACH_CLIENT(true, {
238 // add personal score rank
240
241 // scoreboard data
242 if(it.scoreboard_pos)
243 {
244 // scoreboard is valid!
246
247 // add scoreboard position
249
250 // add scoreboard data
252
253 // if the match ended normally, add winning info
254 if(finished)
255 {
258 }
259 }
260
261 // handicap
262 const float given = GameRules_scoring_add(it, DMG, 0);
263 const float taken = GameRules_scoring_add(it, DMGTAKEN, 0);
264 PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_HANDICAP_GIVEN, given <= 0 ? 1 : it.handicap_avg_given_sum / given);
265 PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_HANDICAP_TAKEN, taken <= 0 ? 1 : it.handicap_avg_taken_sum / taken);
266
267 // collect final player information
269 });
270
272 {
275 PS_GR_OUT_DB = -1;
276 return;
277 }
278
284 NULL
285 );
286}
bool warmup_stage
Definition main.qh:120
const float FILE_APPEND
ERASEABLE void db_close(int db)
Definition map.qh:84
void PlayerStats_GameReport_FinalizePlayer(entity p)
void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
float scoreboard_pos
const string PLAYERSTATS_MATCHES
const string PLAYERSTATS_HANDICAP_TAKEN
const string PLAYERSTATS_WINS
string autocvar_g_playerstats_gamereport_uri
const string PLAYERSTATS_SCOREBOARD_VALID
const string PLAYERSTATS_HANDICAP_GIVEN
const string PLAYERSTATS_RANK
const string PLAYERSTATS_SCOREBOARD_POS
#define PlayerStats_GameReport_Event_Player(ent, eventid, val)
bool PlayerStats_GameReport_DelayMapVote
int PS_GR_OUT_DB
Definition playerstats.qh:5
#define NULL
Definition post.qh:14
float score_dummyfield
Definition scores.qc:916
void PlayerScore_PlayerStats(entity p)
Definition scores.qc:950
entity PlayerScore_Sort(.float field, int teams, bool strict, bool nospectators)
Sorts the players and stores their place in the given field, starting with.
Definition scores.qc:748
void PlayerScore_TeamStats()
Definition scores.qc:960
#define GameRules_scoring_add(client, fld, value)
Definition sv_rules.qh:85
bool teamplay
Definition teams.qh:59
ERASEABLE void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass)
Definition urllib.qc:364
#define FOREACH_CLIENT(cond, body)
Definition utils.qh:50

References autocvar_g_playerstats_gamereport_uri, db_close(), FILE_APPEND, FOREACH_CLIENT, GameRules_scoring_add, NULL, PlayerScore_PlayerStats(), PlayerScore_Sort(), PlayerScore_TeamStats(), PlayerStats_GameReport_DelayMapVote, PlayerStats_GameReport_Event_Player, PlayerStats_GameReport_FinalizePlayer(), PlayerStats_GameReport_Handler(), PLAYERSTATS_HANDICAP_GIVEN, PLAYERSTATS_HANDICAP_TAKEN, PLAYERSTATS_MATCHES, PLAYERSTATS_RANK, PLAYERSTATS_SCOREBOARD_POS, PLAYERSTATS_SCOREBOARD_VALID, PLAYERSTATS_WINS, PS_GR_OUT_DB, score_dummyfield, scoreboard_pos, teamplay, url_multi_fopen(), and warmup_stage.

Referenced by NextLevel(), and Shutdown().

◆ PlayerStats_GameReport_Accuracy()

void PlayerStats_GameReport_Accuracy ( entity p)

Definition at line 167 of file playerstats.qc.

168{
169 #define ACCMAC(suffix, field) \
170 PlayerStats_GameReport_Event_Player(p, \
171 sprintf("acc-%s-%s", it.netname, suffix), CS(p).accuracy.(field[i-1]));
172 FOREACH(Weapons, it != WEP_Null, {
173 ACCMAC("real", accuracy_real)
174 ACCMAC("hit", accuracy_hit)
175 ACCMAC("fired", accuracy_fired)
176 ACCMAC("cnt-hit", accuracy_cnt_hit)
177 ACCMAC("cnt-fired", accuracy_cnt_fired)
178 ACCMAC("frags", accuracy_frags)
179 });
180 #undef ACCMAC
181}
float accuracy_fired[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:31
float accuracy_frags[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:27
float accuracy_cnt_hit[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:32
float accuracy_hit[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:30
float accuracy_cnt_fired[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:33
float accuracy_real[REGISTRY_MAX(Weapons)]
Definition accuracy.qh:29
Weapons
Definition guide.qh:113
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define ACCMAC(suffix, field)

References ACCMAC, accuracy_cnt_fired, accuracy_cnt_hit, accuracy_fired, accuracy_frags, accuracy_hit, accuracy_real, entity(), FOREACH, and Weapons.

Referenced by PlayerStats_GameReport_FinalizePlayer().

◆ PlayerStats_GameReport_AddEvent()

void PlayerStats_GameReport_AddEvent ( string event_id)

Definition at line 136 of file playerstats.qc.

137{
138 if(PS_GR_OUT_DB < 0) { return; }
139
140 string key = sprintf("*:%s", event_id);
141 string p = db_get(PS_GR_OUT_DB, key);
142
143 if(p == "")
144 {
145 if(PS_GR_OUT_EVL)
146 {
149 }
150 else { db_put(PS_GR_OUT_DB, key, "#"); }
151 PS_GR_OUT_EVL = strzone(event_id);
152 }
153}
ERASEABLE string db_get(int db, string key)
Definition map.qh:91
ERASEABLE void db_put(int db, string key, string value)
Definition map.qh:101
void strunzone(string s)
string strzone(string s)
string PS_GR_OUT_EVL

References db_get(), db_put(), PS_GR_OUT_DB, PS_GR_OUT_EVL, strunzone(), and strzone().

Referenced by anticheat_register_to_playerstats(), ClientConnect(), PlayerStats_GameReport_Init(), PlayerStats_GameReport_Reset_All(), ScoreInfo_SetLabel_PlayerScore(), and ScoreInfo_SetLabel_TeamScore().

◆ PlayerStats_GameReport_AddPlayer()

void PlayerStats_GameReport_AddPlayer ( entity e)

Definition at line 79 of file playerstats.qc.

80{
81 if((PS_GR_OUT_DB < 0) || (e.playerstats_id)) { return; }
82
83 // set up player identification
84 string s = "";
85
86 if((e.crypto_idfp != "") && (CS_CVAR(e).cvar_cl_allow_uidtracking == 1))
87 { s = e.crypto_idfp; }
88 else if(IS_BOT_CLIENT(e))
89 { s = sprintf("bot#%g#%s", skill, e.cleanname); }
90
91 if((s == "") || find(NULL, playerstats_id, s)) // already have one of the ID - next one can't be tracked then!
92 {
93 if(IS_BOT_CLIENT(e))
94 { s = sprintf("bot#%d", e.playerid); }
95 else
96 { s = sprintf("player#%d", e.playerid); }
97 }
98
99 e.playerstats_id = strzone(s);
100
101 // now add the player to the database
102 string key = sprintf("%s:*", e.playerstats_id);
103 string p = db_get(PS_GR_OUT_DB, key);
104
105 if(p == "")
106 {
107 if(PS_GR_OUT_PL)
108 {
111 }
112 else { db_put(PS_GR_OUT_DB, key, "#"); }
113 PS_GR_OUT_PL = strzone(e.playerstats_id);
114 }
115}
float skill
Definition api.qh:35
entity find(entity start,.string field, string match)
string playerstats_id
string PS_GR_OUT_PL
#define CS_CVAR(this)
Definition state.qh:51
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15

References CS_CVAR, db_get(), db_put(), entity(), find(), IS_BOT_CLIENT, NULL, playerstats_id, PS_GR_OUT_DB, PS_GR_OUT_PL, skill, strunzone(), and strzone().

Referenced by ClientConnect(), PlayerStats_GameReport_Reset_All(), and REPLICATE_APPLYCHANGE().

◆ PlayerStats_GameReport_AddTeam()

void PlayerStats_GameReport_AddTeam ( float t)

◆ PlayerStats_GameReport_Event()

float PlayerStats_GameReport_Event ( string prefix,
string event_id,
float value )

Definition at line 155 of file playerstats.qc.

156{
157 if((prefix == "") || PS_GR_OUT_DB < 0) { return 0; }
158
159 // use a cheaper strcat here since this function is called often in game
160 string key = strcat(prefix, ":", event_id);
161 float val = stof(db_get(PS_GR_OUT_DB, key));
162 val += value;
163 db_put(PS_GR_OUT_DB, key, ftos(val));
164 return val;
165}
float stof(string val,...)
string ftos(float f)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))

References db_get(), db_put(), ftos(), PS_GR_OUT_DB, stof(), and strcat().

◆ PlayerStats_GameReport_FinalizePlayer()

void PlayerStats_GameReport_FinalizePlayer ( entity p)

Definition at line 183 of file playerstats.qc.

184{
185 if((p.playerstats_id == "") || PS_GR_OUT_DB < 0) { return; }
186
187 // add global info!
188 if(p.alivetime_start)
189 {
191 p.alivetime_start = 0;
192 }
193
194 db_put(PS_GR_OUT_DB, sprintf("%s:_playerid", p.playerstats_id), ftos(p.playerid));
195
196 if(CS_CVAR(p).cvar_cl_allow_uid2name == 1 || IS_BOT_CLIENT(p))
197 db_put(PS_GR_OUT_DB, sprintf("%s:_netname", p.playerstats_id), playername(p.netname, p.team, false));
198
199 if(teamplay)
200 db_put(PS_GR_OUT_DB, sprintf("%s:_team", p.playerstats_id), ftos(p.team));
201
202 if(stof(db_get(PS_GR_OUT_DB, sprintf("%s:%s", p.playerstats_id, PLAYERSTATS_ALIVETIME))) > 0)
204
207
208 if(IS_REAL_CLIENT(p))
209 {
210 if(CS(p).latency_cnt)
211 {
212 float latency = max(0, CS(p).latency_sum / CS(p).latency_cnt);
213 if(latency)
214 {
215 // if previous average latency exists (player disconnected and reconnected)
216 // make the average of previous and current average latency
218 float new_latency = !prev_latency ? latency : (prev_latency + latency) / 2;
219 PlayerStats_GameReport_Event_Player(p, PLAYERSTATS_AVGLATENCY, -prev_latency + new_latency);
220 }
221 }
222
223 db_put(PS_GR_OUT_DB, sprintf("%s:_ranked", p.playerstats_id), ftos(CS_CVAR(p).cvar_cl_allow_uidranking));
224 }
225
226 strfree(p.playerstats_id);
227}
void anticheat_report_to_playerstats(entity this)
Definition anticheat.qc:221
string playername(string thename, int teamid, bool team_colorize)
Definition util.qc:2082
float time
float max(float f,...)
void PlayerStats_GameReport_Accuracy(entity p)
const string PLAYERSTATS_JOINS
const string PLAYERSTATS_AVGLATENCY
const string PLAYERSTATS_ALIVETIME
ClientState CS(Client this)
Definition state.qh:47
#define strfree(this)
Definition string.qh:59
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
float latency_cnt
Definition world.qc:55
float latency_sum
Definition world.qc:54

References anticheat_report_to_playerstats(), CS(), CS_CVAR, db_get(), db_put(), entity(), ftos(), IS_BOT_CLIENT, IS_REAL_CLIENT, latency_cnt, latency_sum, max(), playername(), PLAYERSTATS_ALIVETIME, PLAYERSTATS_AVGLATENCY, PlayerStats_GameReport_Accuracy(), PlayerStats_GameReport_Event_Player, PLAYERSTATS_JOINS, PS_GR_OUT_DB, stof(), strfree, teamplay, and time.

Referenced by ClientDisconnect(), and PlayerStats_GameReport().

◆ PlayerStats_GameReport_Handler()

void PlayerStats_GameReport_Handler ( entity fh,
entity pass,
float status )

Definition at line 359 of file playerstats.qc.

360{
361 string t, tn;
362 string p, pn;
363 string e, en;
364 string nn, tt;
365 string s;
366
367 switch(status)
368 {
369 // ======================================
370 // -- OUTGOING GAME REPORT INFORMATION --
371 // ======================================
372 /* SPECIFICATIONS:
373 * V: format version (always a fixed number) - this MUST be the first line!
374 * #: comment (MUST be ignored by any parser)
375 * R: release information on the server
376 * G: gametype
377 * O: mod name (icon request) as in server browser
378 * M: map name
379 * I: match ID (see "matchid" in world.qc)
380 * S: "hostname" of the server
381 * C: number of "unpure" cvar changes
382 * U: UDP port number of the server
383 * D: duration of the match
384 * RP: number of rounds played
385 * L: "ladder" in which the server is participating in
386 * P: player ID of an existing player; this also sets the owner for all following "n", "e" and "t" lines (lower case!)
387 * Q: team number of an existing team (format: team#NN); this also sets the owner for all following "e" lines (lower case!)
388 * i: player index
389 * n: nickname of the player (optional)
390 * t: team ID
391 * r: player ranking enabled / disabled
392 * e: followed by an event name, a space, and the event count/score
393 * event names can be:
394 * alivetime: total playing time of the player
395 * avglatency: average network latency compounded throughout the match
396 * wins: number of games won (can only be set if matches is set)
397 * matches: number of matches played to the end (not aborted by map switch)
398 * joins: number of matches joined (always 1 unless player never played during the match)
399 * scoreboardvalid: set to 1 if the player was there at the end of the match
400 * total-<scoreboardname>: total score of that scoreboard item
401 * scoreboard-<scoreboardname>: end-of-game score of that scoreboard item (can differ in non-team games)
402 * achievement-<achievementname>: achievement counters (their "count" is usually 1 if nonzero at all)
403 * kills-<index>: number of kills against the indexed player
404 * rank <number>: rank of player
405 * handicapgiven: average handicap on given (dealt) damage throughout the match
406 * handicaptaken: average handicap on taken (received) damage throughout the match
407 * acc-<weapon netname>-real: total damage dealt excluding excess after death
408 * acc-<weapon netname>-hit: total damage dealt including excess after death
409 * acc-<weapon netname>-fired: total damage that all fired shots could have dealt
410 * acc-<weapon netname>-cnt-hit: amount of shots that actually hit
411 * acc-<weapon netname>-cnt-fired: amount of fired shots
412 * acc-<weapon netname>-frags: amount of frags dealt by weapon
413 */
415 {
416 url_fputs(fh, "V 9\n");
417 #ifdef WATERMARK
418 url_fputs(fh, sprintf("R %s\n", WATERMARK));
419 #endif
420 url_fputs(fh, sprintf("G %s\n", PlayerStats_GetGametype()));
421 url_fputs(fh, sprintf("O %s\n", modname));
422 url_fputs(fh, sprintf("M %s\n", GetMapname()));
423 url_fputs(fh, sprintf("I %s\n", matchid));
424 url_fputs(fh, sprintf("S %s\n", cvar_string("hostname")));
425 url_fputs(fh, sprintf("C %d\n", cvar_purechanges_count));
426 url_fputs(fh, sprintf("U %d\n", cvar("port")));
427 url_fputs(fh, sprintf("D %f\n", max(0, time - game_starttime)));
428 if (rounds_played > 0)
429 url_fputs(fh, sprintf("RP %d\n", rounds_played));
432
433 // TEAMS
434 if(teamplay)
435 {
436 for(t = PS_GR_OUT_TL; (tn = db_get(PS_GR_OUT_DB, sprintf("%d", stof(t)))) != ""; t = tn)
437 {
438 // start team section
439 url_fputs(fh, sprintf("Q team#%s\n", t));
440
441 // output team events // todo: does this do unnecessary loops? perhaps we should do a separate "team_events_last" tracker..."
442 for(e = PS_GR_OUT_EVL; (en = db_get(PS_GR_OUT_DB, sprintf("*:%s", e))) != ""; e = en)
443 {
444 float v = stof(db_get(PS_GR_OUT_DB, sprintf("team#%d:%s", stof(t), e)));
445 if(v != 0) { url_fputs(fh, sprintf("e %s %g\n", e, v)); }
446 }
447 }
448 }
449
450 // PLAYERS
451 for(p = PS_GR_OUT_PL; (pn = db_get(PS_GR_OUT_DB, sprintf("%s:*", p))) != ""; p = pn)
452 {
453 // start player section
454 url_fputs(fh, sprintf("P %s\n", p));
455
456 // playerid/index (entity number for this server)
457 nn = db_get(PS_GR_OUT_DB, sprintf("%s:_playerid", p));
458 if(nn != "") { url_fputs(fh, sprintf("i %s\n", nn)); }
459
460 // player name
461 nn = db_get(PS_GR_OUT_DB, sprintf("%s:_netname", p));
462 if(nn != "") { url_fputs(fh, sprintf("n %s\n", nn)); }
463
464 // team identification number
465 if(teamplay)
466 {
467 tt = db_get(PS_GR_OUT_DB, sprintf("%s:_team", p));
468 url_fputs(fh, sprintf("t %s\n", tt));
469 }
470
471 // skill ranking enabled
472 nn = db_get(PS_GR_OUT_DB, sprintf("%s:_ranked", p));
473 if(nn != "") { url_fputs(fh, sprintf("r %s\n", nn)); }
474
475 // output player events
476 for(e = PS_GR_OUT_EVL; (en = db_get(PS_GR_OUT_DB, sprintf("*:%s", e))) != ""; e = en)
477 {
478 float v = stof(db_get(PS_GR_OUT_DB, sprintf("%s:%s", p, e)));
479 if(v != 0) { url_fputs(fh, sprintf("e %s %g\n", e, v)); }
480 }
481 }
482 url_fputs(fh, "\n");
483 url_fclose(fh);
484 break;
485 }
486
487 // ======================================
488 // -- INCOMING GAME REPORT INFORMATION --
489 // ======================================
490 /* SPECIFICATIONS:
491 * stuff
492 */
494 {
495 // url_fclose is processing, we got a response for writing the data
496 // this must come from HTTP
497 LOG_DEBUG("Got response from player stats server:");
498 while((s = url_fgets(fh))) { LOG_DEBUG(" ", s); }
499 LOG_DEBUG("End of response.");
500 url_fclose(fh);
501 break;
502 }
503
504 case URL_READY_CLOSED:
505 {
506 // url_fclose has finished
507 LOG_DEBUG("Player stats written");
509 if(PS_GR_OUT_DB >= 0)
510 {
512 PS_GR_OUT_DB = -1;
513 }
514 break;
515 }
516
517 case URL_READY_ERROR:
518 default:
519 {
520 LOG_INFO("Player stats writing failed: ", ftos(status));
522 if(PS_GR_OUT_DB >= 0)
523 {
525 PS_GR_OUT_DB = -1;
526 }
527 break;
528 }
529 }
530}
float game_starttime
Definition stats.qh:82
int rounds_played
Definition stats.qh:377
string GetMapname()
#define LOG_INFO(...)
Definition log.qh:65
#define LOG_DEBUG(...)
Definition log.qh:80
float cvar(string name)
const string cvar_string(string name)
string PlayerStats_GetGametype()
string autocvar_g_playerstats_gamereport_ladder
string PS_GR_OUT_TL
ERASEABLE string url_fgets(entity e)
Definition urllib.qc:287
ERASEABLE void url_fputs(entity e, string s)
Definition urllib.qc:312
ERASEABLE void url_fclose(entity e)
Definition urllib.qc:207
const float URL_READY_CLOSED
Definition urllib.qh:15
const float URL_READY_ERROR
Definition urllib.qh:14
const float URL_READY_CANREAD
Definition urllib.qh:17
const float URL_READY_CANWRITE
Definition urllib.qh:16
string matchid
Definition world.qh:63
float cvar_purechanges_count
Definition world.qh:47
string modname
Definition world.qh:49

References autocvar_g_playerstats_gamereport_ladder, cvar(), cvar_purechanges_count, cvar_string(), db_close(), db_get(), entity(), ftos(), game_starttime, GetMapname(), LOG_DEBUG, LOG_INFO, matchid, max(), modname, pass, PlayerStats_GameReport_DelayMapVote, PlayerStats_GetGametype(), PS_GR_OUT_DB, PS_GR_OUT_EVL, PS_GR_OUT_PL, PS_GR_OUT_TL, rounds_played, stof(), teamplay, time, url_fclose(), url_fgets(), url_fputs(), URL_READY_CANREAD, URL_READY_CANWRITE, URL_READY_CLOSED, and URL_READY_ERROR.

Referenced by PlayerStats_GameReport().

◆ PlayerStats_GameReport_Init()

void PlayerStats_GameReport_Init ( )

Definition at line 288 of file playerstats.qc.

289{
292
293 if(autocvar_g_playerstats_gamereport_uri == "") { return; }
294
296
297 if(PS_GR_OUT_DB >= 0)
298 {
300
301 if(autocvar_g_playerstats_gamereport_uri != cvar_defstring("g_playerstats_gamereport_uri"))
303 else if(checkextension("DP_CRYPTO") && checkextension("DP_QC_URI_POST"))
304 // XonStat submission requires player and server IDs, and HTTPS POST
306
317
318 // accuracy stats
319 FOREACH(Weapons, it != WEP_Null, {
320 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-real"));
321 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-hit"));
322 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-fired"));
323 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-cnt-hit"));
324 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-cnt-fired"));
325 PlayerStats_GameReport_AddEvent(strcat("acc-", it.netname, "-frags"));
326 });
327
338
340 }
342}
void anticheat_register_to_playerstats()
Definition anticheat.qc:230
int serverflags
Definition main.qh:211
const int SERVERFLAG_PLAYERSTATS
Definition constants.qh:18
const int SERVERFLAG_PLAYERSTATS_CUSTOM
Definition constants.qh:19
ERASEABLE int db_create()
Definition map.qh:25
float checkextension(string ext)
const string cvar_defstring(string name)
void PlayerStats_GameReport_AddEvent(string event_id)
const string PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD
const string PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25
const string PLAYERSTATS_ACHIEVEMENT_BOTLIKE
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15
const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5

References anticheat_register_to_playerstats(), autocvar_g_playerstats_gamereport_uri, checkextension(), cvar_defstring(), db_create(), FOREACH, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5, PLAYERSTATS_ALIVETIME, PLAYERSTATS_AVGLATENCY, PlayerStats_GameReport_AddEvent(), PlayerStats_GameReport_DelayMapVote, PLAYERSTATS_HANDICAP_GIVEN, PLAYERSTATS_HANDICAP_TAKEN, PLAYERSTATS_JOINS, PLAYERSTATS_MATCHES, PLAYERSTATS_RANK, PLAYERSTATS_SCOREBOARD_POS, PLAYERSTATS_SCOREBOARD_VALID, PLAYERSTATS_WINS, PS_GR_OUT_DB, SERVERFLAG_PLAYERSTATS, SERVERFLAG_PLAYERSTATS_CUSTOM, serverflags, strcat(), and Weapons.

Referenced by PlayerStats_GameReport_Reset_All(), and spawnfunc().

◆ PlayerStats_GameReport_Reset_All()

void PlayerStats_GameReport_Reset_All ( )

Definition at line 36 of file playerstats.qc.

37{
41
42 if (PS_GR_OUT_DB >= 0)
43 {
46 }
47 if(PS_GR_OUT_DB < 0)
48 return;
49
50 for (int i = 0; i < 16; ++i)
51 if (teamscorekeepers[i])
53 FOREACH_CLIENT(true, {
54 // NOTE Adding back a player we are applying any cl_allow_uidtracking change
55 // usually only possible by reconnecting to the server
56 strfree(it.playerstats_id);
57 PlayerStats_GameReport_AddEvent(sprintf("kills-%d", it.playerid));
59 it.handicap_avg_given_sum = 0;
60 it.handicap_avg_taken_sum = 0;
61 });
62 FOREACH(Scores, true, {
63 string label = scores_label(it);
64 if (label == "")
65 continue;
68 });
69 for(int i = 0; i < MAX_TEAMSCORE; ++i)
70 {
71 string label = teamscores_label(i);
72 if (label == "")
73 continue;
76 }
77}
#define scores_label(this)
Definition scores.qh:146
#define MAX_TEAMSCORE
Definition scores.qh:149
#define teamscores_label(i)
Definition scores.qh:154
void PlayerStats_GameReport_AddPlayer(entity e)
void PlayerStats_GameReport_AddTeam(int t)
void PlayerStats_GameReport_Init()
const string PLAYERSTATS_SCOREBOARD
const string PLAYERSTATS_TOTAL
entity teamscorekeepers[16]
Definition scores.qc:20

References db_close(), FOREACH, FOREACH_CLIENT, MAX_TEAMSCORE, PlayerStats_GameReport_AddEvent(), PlayerStats_GameReport_AddPlayer(), PlayerStats_GameReport_AddTeam(), PlayerStats_GameReport_Init(), PLAYERSTATS_SCOREBOARD, PLAYERSTATS_TOTAL, PS_GR_OUT_DB, PS_GR_OUT_EVL, PS_GR_OUT_PL, PS_GR_OUT_TL, scores_label, strcat(), strfree, teamscorekeepers, and teamscores_label.

Referenced by reset_map().

◆ PlayerStats_PlayerBasic()

void PlayerStats_PlayerBasic ( entity joiningplayer,
float newrequest )

Definition at line 532 of file playerstats.qc.

533{
534 GameRules_scoring_add(joiningplayer, SKILL, -1);
535 // http://stats.xonotic.org/skill?hashkey=Cm5mzXa1Vn9VX0%2FySV4Pp8ca9CTZvklERDqrrNOUFZU%3D
537 {
539 if (joiningplayer.crypto_idfp == "") {
540 GameRules_scoring_add(joiningplayer, SKILL, -1);
541 } else {
542 // create the database if it doesn't already exist
543 if(PS_B_IN_DB < 0)
545
546 // now request the information
547 uri = strcat(uri, "/skill?game_type_cd=", uri_escape(PlayerStats_GetGametype()));
548 uri = strcat(uri, "&hashkey=", uri_escape(joiningplayer.crypto_idfp));
549 LOG_DEBUG("Retrieving playerstats from URL: ", uri);
551 uri,
552 FILE_READ,
554 joiningplayer
555 );
556
557 // set status appropriately // todo: check whether the player info exists in the database previously
558 if(newrequest)
559 {
560 // database still contains useful information, so don't clear it of a useful status
561 joiningplayer.playerstats_basicstatus = PS_B_STATUS_WAITING;
562 }
563 else
564 {
565 // database was previously empty or never hit received status for some reason
566 joiningplayer.playerstats_basicstatus = PS_B_STATUS_UPDATING;
567 }
568 }
569 }
570 else
571 {
572 // server has this disabled, kill the DB and set status to idle
573 GameRules_scoring_add(joiningplayer, SKILL, -1);
574 if(PS_B_IN_DB >= 0)
575 {
577 PS_B_IN_DB = -1;
578
579 FOREACH_CLIENT(IS_REAL_CLIENT(it), it.playerstats_basicstatus = PS_B_STATUS_IDLE);
580 }
581 }
582}
const float FILE_READ
void PlayerStats_PlayerBasic_Handler(entity fh, entity p, float status)
float PS_B_IN_DB
Definition playerstats.qh:7
const float PS_B_STATUS_UPDATING
const float PS_B_STATUS_WAITING
string autocvar_g_playerstats_playerbasic_uri
const float PS_B_STATUS_IDLE
ERASEABLE void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
Definition urllib.qc:87

References autocvar_g_playerstats_playerbasic_uri, db_close(), db_create(), entity(), FILE_READ, FOREACH_CLIENT, GameRules_scoring_add, IS_REAL_CLIENT, LOG_DEBUG, PlayerStats_GetGametype(), PlayerStats_PlayerBasic_Handler(), PS_B_IN_DB, PS_B_STATUS_IDLE, PS_B_STATUS_UPDATING, PS_B_STATUS_WAITING, strcat(), and url_single_fopen().

Referenced by PlayerStats_PlayerBasic_CheckUpdate().

◆ PlayerStats_PlayerBasic_CheckUpdate()

void PlayerStats_PlayerBasic_CheckUpdate ( entity joiningplayer)

Definition at line 599 of file playerstats.qc.

600{
601 // determine whether we should retrieve playerbasic information again
602
603 LOG_DEBUGF("PlayerStats_PlayerBasic_CheckUpdate('%s'): %f",
604 joiningplayer.netname,
605 time
606 );
607
608 // TODO: check to see if this playerid is inside the database already somehow...
609 // for now we'll just check the field, but this won't work for players who disconnect and reconnect properly
610 // although maybe we should just submit another request ANYWAY?
611 if(!joiningplayer.playerstats_basicstatus)
612 {
614 joiningplayer,
615 (joiningplayer.playerstats_basicstatus == PS_B_STATUS_RECEIVED)
616 );
617 }
618}
#define LOG_DEBUGF(...)
Definition log.qh:81
void PlayerStats_PlayerBasic(entity joiningplayer, float newrequest)
const float PS_B_STATUS_RECEIVED

References entity(), LOG_DEBUGF, PlayerStats_PlayerBasic(), PS_B_STATUS_RECEIVED, and time.

Referenced by ClientState_attach().

◆ PlayerStats_PlayerBasic_Handler()

void PlayerStats_PlayerBasic_Handler ( entity fh,
entity p,
float status )

Definition at line 620 of file playerstats.qc.

621{
622 switch(status)
623 {
625 {
626 // THIS should be never called
627 LOG_DEBUG("-- Sending data to player stats server");
628 url_fputs(fh, "\n");
629 url_fclose(fh);
630 return;
631 }
632
634 {
635 string temp = "";
636 for (string s; (s = url_fgets(fh)); )
637 {
638 if (temp != "")
639 temp = strcat(temp, "\n", s);
640 else
641 temp = s;
642 }
643 url_fclose(fh);
644 int buf = json_parse(temp, _json_parse_array);
645 EXPECT_NE(-1, buf);
647 if (json_get(buf, "0.game_type_cd") == gametype && gametype != "")
648 {
649 float mu = stof(json_get(buf, "0.mu"));
650 //float sigma = stof(json_get(buf, "0.sigma"));
651 float skill = max(0, mu);
652 /* we display just the mean skill, since this most accurately represents how players will play on an average match.
653 * displaying mu - 3 * sigma would display worst-case performance, but when applied to every player this becomes meaningless.
654 * also we're not interested in the skill that we're confident players can operate above, rather where we expect them to operate.
655 */
656 GameRules_scoring_add(p, SKILL, skill + 1);
657 return;
658
659 }
660 break;
661 }
662 case URL_READY_CLOSED:
663 {
664 // url_fclose has finished
665 LOG_INFO("Player stats synchronized with server");
666 return;
667 }
668
669 case URL_READY_ERROR:
670 default:
671 {
672 LOG_INFO("Receiving player stats failed: ", ftos(status));
673 break;
674 }
675 }
676 GameRules_scoring_add(p, SKILL, -1);
677}
entity gametype
Definition main.qh:43
ERASEABLE int json_parse(string in, bool() func)
Definition json.qc:230
bool _json_parse_array()
Definition json.qc:73
ERASEABLE string json_get(int buf, string key)
Definition json.qc:276
#define EXPECT_NE(val1, val2)
Definition test.qh:52

References _json_parse_array(), entity(), EXPECT_NE, ftos(), GameRules_scoring_add, gametype, json_get(), json_parse(), LOG_DEBUG, LOG_INFO, max(), PlayerStats_GetGametype(), skill, stof(), strcat(), url_fclose(), url_fgets(), url_fputs(), URL_READY_CANREAD, URL_READY_CANWRITE, URL_READY_CLOSED, and URL_READY_ERROR.

Referenced by PlayerStats_PlayerBasic().

◆ PlayerStats_PlayerDetail()

void PlayerStats_PlayerDetail ( )

Definition at line 715 of file playerstats.qc.

716{
717 // http://stats.xonotic.org/player/me
718 if((autocvar_g_playerstats_playerdetail_uri != "") && (crypto_getmyidstatus(0) > 0))
719 {
720 // create the database if it doesn't already exist
721 if(PS_D_IN_DB < 0)
723
724 //uri = strcat(uri, "/player/", uri_escape(crypto_getmyidfp(0)));
725 LOG_DEBUG("Retrieving playerstats from URL: ", autocvar_g_playerstats_playerdetail_uri);
730 NULL
731 );
732
734 }
735 else
736 {
737 // player has this disabled, kill the DB and set status to idle
738 if(PS_D_IN_DB >= 0)
739 {
741 PS_D_IN_DB = -1;
742 }
743
745 }
746}
void PlayerStats_PlayerDetail_Handler(entity fh, entity unused, float status)
float PlayerStats_PlayerDetail_Status
const float PS_D_STATUS_WAITING
string autocvar_g_playerstats_playerdetail_uri
int PS_D_IN_DB
const float PS_D_STATUS_IDLE

References autocvar_g_playerstats_playerdetail_uri, db_close(), db_create(), FILE_APPEND, LOG_DEBUG, NULL, PlayerStats_PlayerDetail_Handler(), PlayerStats_PlayerDetail_Status, PS_D_IN_DB, PS_D_STATUS_IDLE, PS_D_STATUS_WAITING, and url_single_fopen().

Referenced by PlayerStats_PlayerDetail_CheckUpdate().

◆ PlayerStats_PlayerDetail_CheckUpdate()

void PlayerStats_PlayerDetail_CheckUpdate ( )

Definition at line 748 of file playerstats.qc.

749{
750 // determine whether we should retrieve playerdetail information again
751 float gamecount = cvar("cl_matchcount");
752
753 #if 0
754 LOG_INFOF("PlayerStats_PlayerDetail_CheckUpdate(): %f >= %f, %d > %d",
755 time,
758 gamecount
759 );
760 #endif
761
762 if(
764 ||
765 (gamecount > PS_D_LASTGAMECOUNT)
766 )
767 {
770 PS_D_LASTGAMECOUNT = gamecount;
771 }
772}
#define LOG_INFOF(...)
Definition log.qh:66
void PlayerStats_PlayerDetail()
float PS_D_LASTGAMECOUNT
float PS_D_NEXTUPDATETIME
float autocvar_g_playerstats_playerdetail_autoupdatetime

References autocvar_g_playerstats_playerdetail_autoupdatetime, cvar(), LOG_INFOF, PlayerStats_PlayerDetail(), PS_D_LASTGAMECOUNT, PS_D_NEXTUPDATETIME, and time.

Referenced by XonoticStatsList_showNotify().

◆ PlayerStats_PlayerDetail_Handler()

void PlayerStats_PlayerDetail_Handler ( entity fh,
entity p,
float status )

Definition at line 774 of file playerstats.qc.

775{
776 switch(status)
777 {
779 {
780 LOG_DEBUG("PlayerStats_PlayerDetail_Handler(): Sending data to player stats server...");
781 url_fputs(fh, "V 1\n");
782 #ifdef WATERMARK
783 url_fputs(fh, sprintf("R %s\n", WATERMARK));
784 #endif
785 url_fputs(fh, sprintf("l %s\n", cvar_string("_menu_prvm_language"))); // language
786 //url_fputs(fh, sprintf("c %s\n", cvar_string("_cl_country"))); // country
787 url_fputs(fh, sprintf("n %s\n", cvar_string("_cl_name"))); // name
788 url_fputs(fh, sprintf("m %s %s\n", cvar_string("_cl_playermodel"), cvar_string("_cl_playerskin"))); // model/skin
789 url_fputs(fh, "\n");
790 url_fclose(fh);
791 break;
792 }
793
795 {
796 //print("PlayerStats_PlayerDetail_Handler(): Got response from player stats server:\n");
797 string input = "";
798 string gametype = "overall";
799 while((input = url_fgets(fh)))
800 {
801 float count = tokenizebyseparator(input, " ");
802 string key = "", event = "", data = "";
803
804 if(argv(0) == "#") { continue; }
805
806 if(count == 2)
807 {
808 key = argv(0);
809 data = substring(input, argv_start_index(1), strlen(input) - argv_start_index(1));
810 }
811 else if(count >= 3)
812 {
813 key = argv(0);
814 event = argv(1);
815 data = substring(input, argv_start_index(2), strlen(input) - argv_start_index(2));
816 }
817 else { continue; }
818
819 switch(key)
820 {
821 // general info
822 case "V": PlayerStats_PlayerDetail_AddItem("version", data); break;
823 case "R": PlayerStats_PlayerDetail_AddItem("release", data); break;
824 case "T": PlayerStats_PlayerDetail_AddItem("time", data); break;
825
826 // player info
827 case "S": PlayerStats_PlayerDetail_AddItem("statsurl", data); break;
828 case "P": PlayerStats_PlayerDetail_AddItem("hashkey", data); break;
829 case "n": PlayerStats_PlayerDetail_AddItem("playernick", data); break;
830 case "i": PlayerStats_PlayerDetail_AddItem("playerid", data); break;
831
832 // other/event info
833 case "G": gametype = data; break;
834 case "e":
835 {
836 if(event != "" && data != "")
837 {
839 sprintf(
840 "%s/%s",
841 gametype,
842 event
843 ),
844 data
845 );
846 }
847 break;
848 }
849
850 default:
851 {
852 LOG_INFOF(
853 "PlayerStats_PlayerDetail_Handler(): ERROR: "
854 "Key went unhandled? Is our version outdated?\n"
855 "PlayerStats_PlayerDetail_Handler(): "
856 "Key '%s', Event '%s', Data '%s'",
857 key,
858 event,
859 data
860 );
861 break;
862 }
863 }
864
865 #if 0
866 LOG_INFOF(
867 "PlayerStats_PlayerDetail_Handler(): "
868 "Key '%s', Event '%s', Data '%s'",
869 key,
870 event,
871 data
872 );
873 #endif
874 }
875 //print("PlayerStats_PlayerDetail_Handler(): End of response.\n");
876 url_fclose(fh);
878 statslist.getStats(statslist);
879 break;
880 }
881
882 case URL_READY_CLOSED:
883 {
884 // url_fclose has finished
885 LOG_INFO("PlayerStats_PlayerDetail_Handler(): Player stats synchronized with server.");
886 break;
887 }
888
889 case URL_READY_ERROR:
890 default:
891 {
892 LOG_INFO("PlayerStats_PlayerDetail_Handler(): Receiving player stats failed: ", ftos(status));
894 if(PS_D_IN_DB >= 0)
895 {
897 PS_D_IN_DB = -1;
898 }
899 break;
900 }
901 }
902}
float count
Definition powerups.qc:22
#define strlen
#define tokenizebyseparator
#define argv_start_index
string substring(string s, float start, float length)
string argv(float n)
void PlayerStats_PlayerDetail_AddItem(string event, string data)
const float PS_D_STATUS_RECEIVED
const float PS_D_STATUS_ERROR
entity statslist
Definition statslist.qh:23

References argv(), argv_start_index, count, cvar_string(), db_close(), entity(), ftos(), gametype, LOG_DEBUG, LOG_INFO, LOG_INFOF, PlayerStats_PlayerDetail_AddItem(), PlayerStats_PlayerDetail_Status, PS_D_IN_DB, PS_D_STATUS_ERROR, PS_D_STATUS_RECEIVED, statslist, strlen, substring(), tokenizebyseparator, url_fclose(), url_fgets(), url_fputs(), URL_READY_CANREAD, URL_READY_CANWRITE, URL_READY_CLOSED, and URL_READY_ERROR.

Referenced by PlayerStats_PlayerDetail().

◆ REPLICATE_INIT() [1/3]

REPLICATE_INIT ( bool ,
cvar_cl_allow_uidranking  )

◆ REPLICATE_INIT() [2/3]

REPLICATE_INIT ( int ,
cvar_cl_allow_uid2name  )

◆ REPLICATE_INIT() [3/3]

REPLICATE_INIT ( int ,
cvar_cl_allow_uidtracking  )

Variable Documentation

◆ autocvar_g_playerstats_gamereport_ladder

string autocvar_g_playerstats_gamereport_ladder

Definition at line 95 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Handler().

◆ autocvar_g_playerstats_gamereport_uri

string autocvar_g_playerstats_gamereport_uri = "https://stats.xonotic.org/stats/submit"

Definition at line 96 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ autocvar_g_playerstats_playerbasic_uri

string autocvar_g_playerstats_playerbasic_uri = "https://stats.xonotic.org"

Definition at line 104 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic().

◆ autocvar_g_playerstats_playerdetail_autoupdatetime

float autocvar_g_playerstats_playerdetail_autoupdatetime = 1800

Definition at line 119 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_CheckUpdate().

◆ autocvar_g_playerstats_playerdetail_uri

string autocvar_g_playerstats_playerdetail_uri = "https://stats.xonotic.org/player/me"

Definition at line 118 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail().

◆ PLAYERSTATS_ACHIEVEMENT_BOTLIKE

const string PLAYERSTATS_ACHIEVEMENT_BOTLIKE = "achievement-botlike"

Definition at line 54 of file playerstats.qh.

Referenced by Obituary(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD

const string PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD = "achievement-firstblood"

Definition at line 55 of file playerstats.qh.

Referenced by Obituary(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM

const string PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM = "achievement-firstvictim"

Definition at line 56 of file playerstats.qh.

Referenced by Obituary(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10 = "achievement-kill-spree-10"

Definition at line 49 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15 = "achievement-kill-spree-15"

Definition at line 50 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20 = "achievement-kill-spree-20"

Definition at line 51 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25 = "achievement-kill-spree-25"

Definition at line 52 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3 = "achievement-kill-spree-3"

Definition at line 47 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30 = "achievement-kill-spree-30"

Definition at line 53 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5

const string PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5 = "achievement-kill-spree-5"

Definition at line 48 of file playerstats.qh.

Referenced by PlayerStats_GameReport_Init().

◆ PLAYERSTATS_ALIVETIME

const string PLAYERSTATS_ALIVETIME = "alivetime"

◆ PLAYERSTATS_ANTICHEAT

const string PLAYERSTATS_ANTICHEAT = "anticheat-"

◆ PLAYERSTATS_AVGLATENCY

const string PLAYERSTATS_AVGLATENCY = "avglatency"

◆ playerstats_basicstatus

float playerstats_basicstatus

Definition at line 103 of file playerstats.qh.

◆ PlayerStats_GameReport_DelayMapVote

bool PlayerStats_GameReport_DelayMapVote

◆ PLAYERSTATS_HANDICAP_GIVEN

const string PLAYERSTATS_HANDICAP_GIVEN = "handicapgiven"

Definition at line 40 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_HANDICAP_TAKEN

const string PLAYERSTATS_HANDICAP_TAKEN = "handicaptaken"

Definition at line 41 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ playerstats_id

string playerstats_id

Definition at line 90 of file playerstats.qh.

Referenced by PlayerStats_GameReport_AddPlayer().

◆ PLAYERSTATS_JOINS

const string PLAYERSTATS_JOINS = "joins"

◆ PLAYERSTATS_MATCHES

const string PLAYERSTATS_MATCHES = "matches"

Definition at line 35 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PlayerStats_PlayerDetail_Status

float PlayerStats_PlayerDetail_Status = PS_D_STATUS_IDLE

Definition at line 117 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail(), and PlayerStats_PlayerDetail_Handler().

◆ PLAYERSTATS_RANK

const string PLAYERSTATS_RANK = "rank"

Definition at line 38 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_SCOREBOARD

◆ PLAYERSTATS_SCOREBOARD_POS

const string PLAYERSTATS_SCOREBOARD_POS = "scoreboardpos"

Definition at line 39 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_SCOREBOARD_VALID

const string PLAYERSTATS_SCOREBOARD_VALID = "scoreboardvalid"

Definition at line 37 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PLAYERSTATS_TOTAL

const string PLAYERSTATS_TOTAL = "total-"

◆ PLAYERSTATS_WINS

const string PLAYERSTATS_WINS = "wins"

Definition at line 34 of file playerstats.qh.

Referenced by PlayerStats_GameReport(), and PlayerStats_GameReport_Init().

◆ PS_B_IN_DB

float PS_B_IN_DB = -1

Definition at line 7 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic(), and SHUTDOWN().

◆ PS_B_STATUS_ERROR

const float PS_B_STATUS_ERROR = -2

Definition at line 98 of file playerstats.qh.

◆ PS_B_STATUS_IDLE

const float PS_B_STATUS_IDLE = -1

Definition at line 99 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic().

◆ PS_B_STATUS_RECEIVED

const float PS_B_STATUS_RECEIVED = 1

Definition at line 101 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic_CheckUpdate().

◆ PS_B_STATUS_UPDATING

const float PS_B_STATUS_UPDATING = 2

Definition at line 102 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic().

◆ PS_B_STATUS_WAITING

const float PS_B_STATUS_WAITING = 0

Definition at line 100 of file playerstats.qh.

Referenced by PlayerStats_PlayerBasic().

◆ PS_D_IN_DB

◆ PS_D_IN_EVL

string PS_D_IN_EVL

Definition at line 26 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_AddItem(), and XonoticStatsList_getStats().

◆ PS_D_LASTGAMECOUNT

float PS_D_LASTGAMECOUNT

Definition at line 112 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_CheckUpdate().

◆ PS_D_NEXTUPDATETIME

float PS_D_NEXTUPDATETIME

Definition at line 111 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_CheckUpdate().

◆ PS_D_STATUS_ERROR

const float PS_D_STATUS_ERROR = -2

Definition at line 113 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_Handler().

◆ PS_D_STATUS_IDLE

const float PS_D_STATUS_IDLE = -1

Definition at line 114 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail().

◆ PS_D_STATUS_RECEIVED

const float PS_D_STATUS_RECEIVED = 1

Definition at line 116 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail_Handler().

◆ PS_D_STATUS_WAITING

const float PS_D_STATUS_WAITING = 0

Definition at line 115 of file playerstats.qh.

Referenced by PlayerStats_PlayerDetail().

◆ PS_GR_OUT_DB

◆ PS_GR_OUT_EVL

◆ PS_GR_OUT_PL

◆ PS_GR_OUT_TL

◆ scoreboard_pos

float scoreboard_pos

Definition at line 91 of file playerstats.qh.

Referenced by PlayerStats_GameReport().