X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fserver%2Fplayerstats.qc;h=2bb5540d6b26680cd4027bcf3739a12c90812dae;hb=88e4782bf4efb1f8e7e6e722194f257c0daf8a01;hp=7da57f2c23102dc26ca4e73af96cce7387940e21;hpb=26c8963b7747f4c53fc541df0dd71b7024d1d496;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/playerstats.qc b/qcsrc/server/playerstats.qc index 7da57f2c2..2bb5540d6 100644 --- a/qcsrc/server/playerstats.qc +++ b/qcsrc/server/playerstats.qc @@ -3,29 +3,75 @@ string playerstats_last; string events_last; .float playerstats_addedglobalinfo; float playerstats_requested; +.string playerstats_id; void PlayerStats_Init() { string uri; - playerstats_sent = TRUE; - uri = cvar_string("g_playerstats_uri"); + playerstats_db = -1; + playerstats_waitforme = TRUE; + uri = autocvar_g_playerstats_uri; if(uri == "") return; playerstats_db = db_create(); if(playerstats_db >= 0) - playerstats_sent = FALSE; // must wait for it at match end + playerstats_waitforme = FALSE; // must wait for it at match end PlayerStats_AddEvent(PLAYERSTATS_ALIVETIME); - PlayerStats_AddEvent(PLAYERSTATS_KILLS); + PlayerStats_AddEvent(PLAYERSTATS_WINS); + PlayerStats_AddEvent(PLAYERSTATS_MATCHES); + PlayerStats_AddEvent(PLAYERSTATS_JOINS); + PlayerStats_AddEvent(PLAYERSTATS_SCOREBOARD_VALID); + + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_BOTLIKE); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD); + PlayerStats_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM); } void PlayerStats_AddPlayer(entity e) { - if(!e.crypto_idfp || playerstats_db < 0) + if(playerstats_db < 0) return; + + if(e.crypto_idfp != "" && e.cvar_cl_allow_uidtracking == 1) + e.playerstats_id = strzone(e.crypto_idfp); + else if(clienttype(e) == CLIENTTYPE_BOT) + e.playerstats_id = strzone(sprintf("bot#%d", e.playerid)); + else + e.playerstats_id = strzone(sprintf("player#%d", e.playerid)); + + string key; + key = sprintf("%s:*", e.playerstats_id); + string p; + p = db_get(playerstats_db, key); + if(p == "") + { + if(playerstats_last) + { + db_put(playerstats_db, key, playerstats_last); + strunzone(playerstats_last); + } + else + db_put(playerstats_db, key, "#"); + playerstats_last = strzone(e.playerstats_id); + } +} + +void PlayerStats_AddTeam(float t) +{ + if(playerstats_db < 0) + return; + string key; - key = sprintf("%s:*", e.crypto_idfp); + key = sprintf("team#%d:*", t); string p; p = db_get(playerstats_db, key); @@ -38,7 +84,7 @@ void PlayerStats_AddPlayer(entity e) } else db_put(playerstats_db, key, "#"); - playerstats_last = strzone(e.crypto_idfp); + playerstats_last = strzone(sprintf("team%d", t)); } } @@ -67,12 +113,22 @@ void PlayerStats_AddEvent(string event_id) void PlayerStats_Event(entity e, string event_id, float value) { - if(!e.crypto_idfp || playerstats_db < 0) + if(!e.playerstats_id || playerstats_db < 0) return; string key; float val; - key = sprintf("%s:%s", e.crypto_idfp, event_id); + key = sprintf("%s:%s", e.playerstats_id, event_id); + val = stof(db_get(playerstats_db, key)); + val += value; + db_put(playerstats_db, key, ftos(val)); +} + +void PlayerStats_TeamScore(float t, string event_id, float value) +{ + string key; + float val; + key = sprintf("team#%d:%s", t, event_id); val = stof(db_get(playerstats_db, key)); val += value; db_put(playerstats_db, key, ftos(val)); @@ -81,9 +137,40 @@ void PlayerStats_Event(entity e, string event_id, float value) void PlayerStats_Sent_URI_Get_Callback(float id, float status, string data) { if(playerstats_requested) - playerstats_sent = TRUE; + playerstats_waitforme = TRUE; } +/* + format spec: + + A collection of lines of the format SPACE NEWLINE, where + is always a single character. + + The following keys are defined: + + V: format version (always 1) - this MUST be the first line! + #: comment (MUST be ignored by any parser) + R: release information on the server + T: time at which the game ended + G: game type + M: map name + S: "hostname" of the server + C: number of "unpure" cvar changes + P: player ID of an existing player; this also sets the owner for all following "n" and "e" lines (lower case!) + n: nickname of the player (optional) + e: followed by an event name, a space, and the event count/score + event names can be: + alivetime: total playing time of the player + wins: number of games won (can only be set if matches is set) + matches: number of matches played to the end (not aborted by map switch) + joins: number of matches joined (always 1 unless player never played during the match) + scoreboardvalid: set to 1 if the player was there at the end of the match + total-: total score of that scoreboard item + scoreboard-: end-of-game score of that scoreboard item (can differ in non-team games) + achievement-: achievement counters +*/ + +//#NO AUTOCVARS START void PlayerStats_Shutdown() { string p, pn; @@ -96,7 +183,7 @@ void PlayerStats_Shutdown() if(playerstats_db < 0) return; - uri = cvar_string("g_playerstats_uri"); + uri = autocvar_g_playerstats_uri; if(uri != "") { b = buf_create(); @@ -105,9 +192,14 @@ void PlayerStats_Shutdown() db_dump(playerstats_db, "foo.db"); bufstr_set(b, i++, "V 1"); +#ifdef WATERMARK + bufstr_set(b, i++, sprintf("R %s", WATERMARK())); +#endif bufstr_set(b, i++, sprintf("T %s.%06d", strftime(FALSE, "%s"), floor(random() * 1000000))); bufstr_set(b, i++, sprintf("G %s", GetGametype())); bufstr_set(b, i++, sprintf("M %s", GetMapname())); + bufstr_set(b, i++, sprintf("S %s", cvar_string("hostname"))); + bufstr_set(b, i++, sprintf("C %d", cvar_purechanges_count)); for(p = playerstats_last; (pn = db_get(playerstats_db, sprintf("%s:*", p))) != ""; p = pn) { bufstr_set(b, i++, sprintf("P %s", p)); @@ -118,37 +210,69 @@ void PlayerStats_Shutdown() { float v; v = stof(db_get(playerstats_db, sprintf("%s:%s", p, e))); - bufstr_set(b, i++, sprintf("e %s %f", e, v)); + if(v != 0) + bufstr_set(b, i++, sprintf("e %s %g", e, v)); } } bufstr_set(b, i++, ""); + if(autocvar_g_playerstats_debug) + { + for(i = 0; i < buf_getsize(b); ++i) + print(bufstr_get(b, i), "\n"); + } + if(crypto_uri_postbuf(uri, URI_GET_PLAYERSTATS_SENT, "text/plain", "\n", b, 0)) playerstats_requested = TRUE; else - playerstats_sent = TRUE; // if posting fails, we must continue anyway + playerstats_waitforme = TRUE; // if posting fails, we must continue anyway buf_del(b); } else - playerstats_sent = TRUE; + playerstats_waitforme = TRUE; db_close(playerstats_db); playerstats_db = -1; } +//#NO AUTOCVARS END void PlayerStats_AddGlobalInfo(entity p) { if(playerstats_db < 0) return; - if(!p.crypto_idfp || playerstats_db < 0) + if(!p.playerstats_id || playerstats_db < 0) return; p.playerstats_addedglobalinfo = TRUE; // add global info! if(p.alivetime) PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime); + + if(p.alivetime) + PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime); - if(p.cvar_cl_allow_uid2name) - db_put(playerstats_db, sprintf("%s:_netname", p.crypto_idfp), p.netname); + if(p.cvar_cl_allow_uid2name == 1 || clienttype(p) == CLIENTTYPE_BOT) + db_put(playerstats_db, sprintf("%s:_netname", p.playerstats_id), p.netname); + + if(p.alivetime > 0) + PlayerStats_Event(p, PLAYERSTATS_JOINS, 1); + + strunzone(p.playerstats_id); + p.playerstats_id = string_null; +} + +void PlayerStats_EndMatch(float finished) +{ + entity p; + FOR_EACH_PLAYER(p) + { + PlayerScore_PlayerStats(p); + PlayerStats_Event(p, PLAYERSTATS_SCOREBOARD_VALID, 1); + if(finished) + { + PlayerStats_Event(p, PLAYERSTATS_WINS, p.winning); + PlayerStats_Event(p, PLAYERSTATS_MATCHES, 1); + } + } }