]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/playerstats.qc
Clean up accuracy function a bit
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / playerstats.qc
index b7dac05cbe84a51734499254f150e31509726fd8..dc6ddd758dc7ecefdc32d0aa76fc8a7f11de4981 100644 (file)
@@ -1,29 +1,29 @@
 #ifdef SVQC
-float PS_PM_IN_DB;   // playerstats_prematch_in_db      // db for info COLLECTED at the beginning of a match
+//float PS_PM_IN_DB;   // playerstats_prematch_in_db      // db for info COLLECTED at the beginning of a match
 float PS_GR_OUT_DB;  // playerstats_gamereport_out_db   // db of info SENT at the end of a match
-float PS_GR_IN_DB;   // playerstats_gamereport_in_db    // db for info COLLECTED at the end of a match
-float PS_B_IN_DB;    // playerstats_playerbasic_in_db   // db for info COLLECTED for basic player info (ELO)
+//float PS_GR_IN_DB;   // playerstats_gamereport_in_db    // db for info COLLECTED at the end of a match
+//float PS_B_IN_DB;    // playerstats_playerbasic_in_db   // db for info COLLECTED for basic player info (ELO)
 // http://stats.xonotic.org/player/GgXRw6piDtFIbMArMuiAi8JG4tiin8VLjZgsKB60Uds=/elo.txt
 #endif
 
 #ifdef MENUQC
-float PS_D_IN_DB; // playerstats_playerdetail_in_db  // db for info COLLECTED for detailed player profile display
+//float PS_D_IN_DB; // playerstats_playerdetail_in_db  // db for info COLLECTED for detailed player profile display
 // http://stats.xonotic.org/player/me
 #endif
 
 #ifdef SVQC
-string PS_PM_IN_EVL;   // playerstats_prematch_in_events_last
+//string PS_PM_IN_EVL;   // playerstats_prematch_in_events_last
 string PS_GR_OUT_TL;   // playerstats_gamereport_out_teams_last
 string PS_GR_OUT_PL;   // playerstats_gamereport_out_players_las
 string PS_GR_OUT_EVL;  // playerstats_gamereport_out_events_last
-string PS_GR_IN_PL;    // playerstats_gamereport_in_players_last
-string PS_GR_IN_EVL;   // playerstats_gamereport_in_events_last
-string PS_B_IN_PL;     // playerstats_playerbasic_in_players_las
-string PS_B_IN_EVL;    // playerstats_playerbasic_in_events_last
+//string PS_GR_IN_PL;    // playerstats_gamereport_in_players_last
+//string PS_GR_IN_EVL;   // playerstats_gamereport_in_events_last
+//string PS_B_IN_PL;     // playerstats_playerbasic_in_players_las
+//string PS_B_IN_EVL;    // playerstats_playerbasic_in_events_last
 #endif
 
 #ifdef MENUQC
-string PS_D_IN_EVL; // playerstats_playerdetail_in_events_last
+//string PS_D_IN_EVL; // playerstats_playerdetail_in_events_last
 #endif
 
 #ifdef SVQC
@@ -32,21 +32,18 @@ void PlayerStats_Prematch(void)
        //foobar
 }
 
-.string playerstats_id;
-
 void PlayerStats_GameReport_AddPlayer(entity e)
 {
-       string s;
+       if((PS_GR_OUT_DB < 0) || (e.playerstats_id)) { return; }
 
-       if(PS_GR_OUT_DB < 0) { return; }
-       if(e.playerstats_id) { return; }
+       // set up player identification
+       string s = string_null;
 
-       s = string_null;
-       if(e.crypto_idfp != "" && e.cvar_cl_allow_uidtracking == 1)
+       if((e.crypto_idfp != "") && (e.cvar_cl_allow_uidtracking == 1))
                { s = e.crypto_idfp; }
        else if(IS_BOT_CLIENT(e))
                { s = sprintf("bot#%g#%s", skill, e.cleanname); }
-
+               
        if((s == "") || find(world, playerstats_id, s)) // already have one of the ID - next one can't be tracked then!
        {
                if(IS_BOT_CLIENT(e))
@@ -54,9 +51,10 @@ void PlayerStats_GameReport_AddPlayer(entity e)
                else
                        { s = sprintf("player#%d", e.playerid); }
        }
-
+       
        e.playerstats_id = strzone(s);
 
+       // now add the player to the database
        string key = sprintf("%s:*", e.playerstats_id);
        string p = db_get(PS_GR_OUT_DB, key);
        
@@ -109,8 +107,7 @@ void PlayerStats_GameReport_AddEvent(string event_id)
                PS_GR_OUT_EVL = strzone(event_id);
        }
 }
-#define PS_GR_P_ADDVAL(ent,eventid,val) PlayerStats_GameReport_Event(ent.playerstats_id, eventid, val)
-#define PS_GR_T_ADDVAL(team,eventid,val) PlayerStats_GameReport_Event(sprintf("team#%d", team), eventid, val)
+
 // referred to by PS_GR_P_ADDVAL and PS_GR_T_ADDVAL
 float PlayerStats_GameReport_Event(string prefix, string event_id, float value)
 {
@@ -128,20 +125,24 @@ void PlayerStats_GameReport_Accuracy(entity p)
     entity w;
     float i;
 
-       #define PAC p.accuracy
     for(i = WEP_FIRST; i <= WEP_LAST; ++i)
     {
         w = get_weaponinfo(i);
-        PS_GR_P_ADDVAL(p, strcat("acc-", w.netname, "-hit"), PAC.(accuracy_hit[i-1]));
-        PS_GR_P_ADDVAL(p, strcat("acc-", w.netname, "-fired"), PAC.(accuracy_fired[i-1]));
-        PS_GR_P_ADDVAL(p, strcat("acc-", w.netname, "-cnt-hit"), PAC.(accuracy_cnt_hit[i-1]));
-        PS_GR_P_ADDVAL(p, strcat("acc-", w.netname, "-cnt-fired"), PAC.(accuracy_cnt_fired[i-1]));
-        PS_GR_P_ADDVAL(p, strcat("acc-", w.netname, "-frags"), PAC.(accuracy_frags[i-1]));
+        
+        #define ACCMAC(suffix,field) \
+                       PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", w.netname, suffix), p.accuracy.(field[i-1]));
+                       
+        ACCMAC("hit", accuracy_hit)
+        ACCMAC("fired", accuracy_fired)
+        ACCMAC("cnt-hit", accuracy_cnt_hit)
+        ACCMAC("cnt-fired", accuracy_cnt_fired)
+        ACCMAC("frags", accuracy_frags)
+
+        #undef ACCMAC
     }
-    #undef PAC
 }
 
-void PlayerStats_GameReport_AddGlobalInfo(entity p)
+void PlayerStats_GameReport_FinalizePlayer(entity p)
 {
        if((p.playerstats_id == "") || PS_GR_OUT_DB < 0) { return; }
 
@@ -163,7 +164,7 @@ void PlayerStats_GameReport_AddGlobalInfo(entity p)
        if(stof(db_get(PS_GR_OUT_DB, sprintf("%s:%s", p.playerstats_id, PLAYERSTATS_ALIVETIME))) > 0)
                PS_GR_P_ADDVAL(p, PLAYERSTATS_JOINS, 1);
 
-       PlayerStats_Accuracy(p);
+       PlayerStats_GameReport_Accuracy(p);
 
        if(IS_REAL_CLIENT(p))
        {
@@ -178,104 +179,109 @@ void PlayerStats_GameReport_AddGlobalInfo(entity p)
        p.playerstats_id = string_null;
 }
 
-.float scoreboard_pos;
 void PlayerStats_GameReport_EndMatch(float finished)
 {
-       entity p;
+       if(PS_GR_OUT_DB < 0) { return; }
+       
        PlayerScore_Sort(score_dummyfield, 0, 0, 0);
        PlayerScore_Sort(scoreboard_pos, 1, 1, 1);
        if(teamplay) { PlayerScore_TeamStats(); }
+
+       entity p;
        FOR_EACH_CLIENT(p)
        {
                // add personal score rank
                PS_GR_P_ADDVAL(p, PLAYERSTATS_RANK, p.score_dummyfield);
 
-               if(!p.scoreboard_pos) { continue; }
-
-               // scoreboard is valid!
-               PS_GR_P_ADDVAL(p, PLAYERSTATS_SCOREBOARD_VALID, 1);
+               // scoreboard data
+               if(p.scoreboard_pos)
+               {
+                       // scoreboard is valid!
+                       PS_GR_P_ADDVAL(p, PLAYERSTATS_SCOREBOARD_VALID, 1);
 
-               // add scoreboard position
-               PS_GR_P_ADDVAL(p, PLAYERSTATS_SCOREBOARD_POS, p.scoreboard_pos);
+                       // add scoreboard position
+                       PS_GR_P_ADDVAL(p, PLAYERSTATS_SCOREBOARD_POS, p.scoreboard_pos);
 
-               // add scoreboard data
-               PlayerScore_PlayerStats(p);
+                       // add scoreboard data
+                       PlayerScore_PlayerStats(p);
 
-               // if the match ended normally, add winning info
-               if(finished)
-               {
-                       PS_GR_P_ADDVAL(p, PLAYERSTATS_WINS, p.winning);
-                       PS_GR_P_ADDVAL(p, PLAYERSTATS_MATCHES, 1);
+                       // if the match ended normally, add winning info
+                       if(finished)
+                       {
+                               PS_GR_P_ADDVAL(p, PLAYERSTATS_WINS, p.winning);
+                               PS_GR_P_ADDVAL(p, PLAYERSTATS_MATCHES, 1);
+                       }
                }
+
+               // collect final player information
+               PlayerStats_GameReport_FinalizePlayer(p);
+       }
+
+       if(autocvar_g_playerstats_gamereport_uri != "")
+       {
+               PlayerStats_GameReport_DelayMapVote = TRUE;
+               url_multi_fopen(
+                       autocvar_g_playerstats_gamereport_uri,
+                       FILE_APPEND,
+                       PlayerStats_GameReport_Handler,
+                       world
+               );
+       }
+       else
+       {
+               PlayerStats_GameReport_DelayMapVote = FALSE;
+               db_close(PS_GR_OUT_DB);
+               PS_GR_OUT_DB = -1;
        }
 }
 
 void PlayerStats_GameReport_Init() // initiated before InitGameplayMode so that scores are added properly
 {
-       string uri;
+       if(autocvar_g_playerstats_gamereport_uri == "") { return; }
+
        PS_GR_OUT_DB = -1;
-       playerstats_waitforme = TRUE;
-       uri = autocvar_g_playerstats_uri;
-       if(uri == "")
-               return;
        PS_GR_OUT_DB = db_create();
-       if(PS_GR_OUT_DB >= 0)
-               playerstats_waitforme = FALSE; // must wait for it at match end
-
-       serverflags |= SERVERFLAG_PLAYERSTATS;
-
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ALIVETIME);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_AVGLATENCY);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_WINS);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_MATCHES);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_JOINS);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_VALID);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_POS);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_RANK);
-
-    // accuracy stats
-    entity w;
-    float i;
-    for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-    {
-        w = get_weaponinfo(i);
-        PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-hit"));
-        PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-fired"));
-        PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-cnt-hit"));
-        PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-cnt-fired"));
-        PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-frags"));
-    }
-
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_BOTLIKE);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD);
-       PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM);
-}
 
-void PlayerStats_GameReport_Shutdown()
-{
-       string uri;
-
-       if(PS_GR_OUT_DB < 0) { return; }
-
-       uri = autocvar_g_playerstats_uri;
-       if(uri != "")
-       {
-               playerstats_waitforme = FALSE;
-               url_multi_fopen(uri, FILE_APPEND, PlayerStats_GameReport_Handler, world);
-       }
-       else
+       if(PS_GR_OUT_DB >= 0)
        {
-               playerstats_waitforme = TRUE;
-               db_close(PS_GR_OUT_DB);
-               PS_GR_OUT_DB = -1;
+               PlayerStats_GameReport_DelayMapVote = TRUE;
+
+               serverflags |= SERVERFLAG_PLAYERSTATS;
+
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ALIVETIME);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_AVGLATENCY);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_WINS);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_MATCHES);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_JOINS);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_VALID);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_SCOREBOARD_POS);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_RANK);
+
+               // accuracy stats
+               entity w;
+               float i;
+               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+               {
+                       w = get_weaponinfo(i);
+                       PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-hit"));
+                       PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-fired"));
+                       PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-cnt-hit"));
+                       PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-cnt-fired"));
+                       PlayerStats_GameReport_AddEvent(strcat("acc-", w.netname, "-frags"));
+               }
+
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_BOTLIKE);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD);
+               PlayerStats_GameReport_AddEvent(PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM);
        }
+       else { PlayerStats_GameReport_DelayMapVote = FALSE; }
 }
 
 void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
@@ -342,7 +348,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                        url_fputs(fh, sprintf("C %d\n", cvar_purechanges_count));
                        url_fputs(fh, sprintf("U %d\n", cvar("port")));
                        url_fputs(fh, sprintf("D %f\n", max(0, time - game_starttime)));
-                       url_fputs(fh, sprintf("L %s\n", autocvar_g_playerstats_ladder));
+                       url_fputs(fh, sprintf("L %s\n", autocvar_g_playerstats_gamereport_ladder));
 
                        // TEAMS
                        if(teamplay)
@@ -415,7 +421,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                {
                        // url_fclose has finished
                        print("Player stats written\n");
-                       playerstats_waitforme = TRUE;
+                       PlayerStats_GameReport_DelayMapVote = FALSE;
                        db_close(PS_GR_OUT_DB);
                        PS_GR_OUT_DB = -1;
                        break;
@@ -425,7 +431,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                default:
                {
                        print("Player stats writing failed: ", ftos(status), "\n");
-                       playerstats_waitforme = TRUE;
+                       PlayerStats_GameReport_DelayMapVote = FALSE;
                        if(PS_GR_OUT_DB >= 0)
                        {
                                db_close(PS_GR_OUT_DB);
@@ -436,6 +442,128 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
        }
 }
 #endif // SVQC
+
+#ifdef MENUQC
+void PlayerStats_PlayerDetail_Handler(entity fh, entity p, float status)
+{
+       switch(status)
+       {
+               case URL_READY_CANWRITE:
+               {
+                       print("-- Sending data to player stats server\n");
+                       /*url_fputs(fh, "V 1\n");
+                       #ifdef WATERMARK
+                       url_fputs(fh, sprintf("R %s\n", WATERMARK));
+                       #endif
+                       url_fputs(fh, sprintf("l %s\n", cvar_string("_menu_prvm_language"))); // language
+                       url_fputs(fh, sprintf("c %s\n", cvar_string("_menu_prvm_country"))); // country
+                       url_fputs(fh, sprintf("g %s\n", cvar_string("_menu_prvm_gender"))); // gender
+                       url_fputs(fh, sprintf("n %s\n", cvar_string("_cl_name"))); // name
+                       url_fputs(fh, sprintf("m %s %s\n", cvar_string("_cl_playermodel"), cvar_string("_cl_playerskin"))); // model/skin
+                       */url_fputs(fh, "\n");
+                       url_fclose(fh);
+                       break;
+               }
+               
+               case URL_READY_CANREAD:
+               {
+                       string s = "";
+                       print("-- Got response from player stats server:\n");
+                       //string gametype = string_null;
+                       while((s = url_fgets(fh)))
+                       {
+                               print("  ", s, "\n");
+                               /*
+                               string key = "", value = "", data = "";
+
+                               n = tokenizebyseparator(s, " "); // key (value) data
+                               if (n == 1)
+                                       continue;
+                               else if (n == 2)
+                               {
+                               key = argv(0);
+                               data = argv(1);
+                               }
+                               else if (n >= 3)
+                               {
+                                                               key = argv(0);
+                                                               value = argv(1);
+                                                               data = argv(2);
+                               }
+
+                               if (data == "")
+                               continue;
+
+                               if (key == "#")
+                               continue;
+                               else if (key == "V")
+                               PlayerInfo_AddItem(p, "_version", data);
+                               else if (key == "R")
+                               PlayerInfo_AddItem(p, "_release", data);
+                               else if (key == "T")
+                               PlayerInfo_AddItem(p, "_time", data);
+                               else if (key == "S")
+                               PlayerInfo_AddItem(p, "_statsurl", data);
+                               else if (key == "P")
+                               PlayerInfo_AddItem(p, "_hashkey", data);
+                               else if (key == "n")
+                               PlayerInfo_AddItem(p, "_playernick", data);
+                               else if (key == "i")
+                               PlayerInfo_AddItem(p, "_playerid", data);
+                               else if (key == "G")
+                               gametype = data;
+                               else if (key == "e" && value != "")
+                               {
+                               if (gametype == "")
+                               PlayerInfo_AddItem(p, value, data);
+                               else
+                               PlayerInfo_AddItem(p, sprintf("%s/%s", gametype, value), data);
+                               }
+                               else
+                               continue;
+                               */
+                       }
+                       print("-- End of response.\n");
+                       url_fclose(fh);
+                       break;
+               }
+               case URL_READY_CLOSED:
+               {
+                       // url_fclose has finished
+                       print("Player stats synchronized with server\n");
+                       break;
+               }
+               
+               case URL_READY_ERROR:
+               default:
+               {
+                       print("Receiving player stats failed: ", ftos(status), "\n");
+                       break;
+               }
+       }
+}
+
+void PlayerStats_PlayerDetail()
+{
+       //PS_D_IN_DB = -1;
+       //PS_D_IN_DB = db_create();
+
+       //if(PS_D_IN_DB < 0) { return; }
+
+       if((autocvar_g_playerstats_playerdetail_uri != "") && (crypto_getmyidstatus(0) > 0))
+       {
+               //uri = strcat(uri, "/player/", uri_escape(crypto_getmyidfp(0)));
+               print("Retrieving playerstats from URL: ", autocvar_g_playerstats_playerdetail_uri, "\n");
+               url_single_fopen(
+                       autocvar_g_playerstats_playerdetail_uri,
+                       FILE_APPEND,
+                       PlayerStats_PlayerDetail_Handler,
+                       world
+               );
+       }
+}
+#endif
+
 /*
 void PlayerInfo_AddPlayer(entity e)
 {