]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/playerstats.qc
player stats: send all info from scoreboard
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / playerstats.qc
1 float playerstats_db;
2 string playerstats_last;
3 string events_last;
4 .float playerstats_addedglobalinfo;
5 float playerstats_requested;
6 .string playerstats_id;
7
8 void PlayerStats_Init()
9 {
10         string uri;
11         playerstats_db = -1;
12         playerstats_waitforme = TRUE;
13         uri = autocvar_g_playerstats_uri;
14         if(uri == "")
15                 return;
16         playerstats_db = db_create();
17         if(playerstats_db >= 0)
18                 playerstats_waitforme = FALSE; // must wait for it at match end
19         
20         PlayerStats_AddEvent(PLAYERSTATS_ALIVETIME);
21         PlayerStats_AddEvent(PLAYERSTATS_WINS);
22         PlayerStats_AddEvent(PLAYERSTATS_MATCHES);
23 }
24
25 void PlayerStats_AddPlayer(entity e)
26 {
27         if(playerstats_db < 0)
28                 return;
29
30         if(e.crypto_idfp != "")
31                 e.playerstats_id = strzone(e.crypto_idfp);
32         else if(clienttype(e) == CLIENTTYPE_BOT)
33                 e.playerstats_id = strzone(sprintf("bot#%d", e.playerid));
34         else
35                 e.playerstats_id = strzone(sprintf("player#%d", e.playerid));
36         
37         string key;
38         key = sprintf("%s:*", e.playerstats_id);
39         
40         string p;
41         p = db_get(playerstats_db, key);
42         if(p == "")
43         {
44                 if(playerstats_last)
45                 {
46                         db_put(playerstats_db, key, playerstats_last);
47                         strunzone(playerstats_last);
48                 }
49                 else
50                         db_put(playerstats_db, key, "#");
51                 playerstats_last = strzone(e.playerstats_id);
52         }
53 }
54
55 void PlayerStats_AddEvent(string event_id)
56 {
57         if(playerstats_db < 0)
58                 return;
59         
60         string key;
61         key = sprintf("*:%s", event_id);
62         
63         string p;
64         p = db_get(playerstats_db, key);
65         if(p == "")
66         {
67                 if(events_last)
68                 {
69                         db_put(playerstats_db, key, events_last);
70                         strunzone(events_last);
71                 }
72                 else
73                         db_put(playerstats_db, key, "#");
74                 events_last = strzone(event_id);
75         }
76 }
77
78 void PlayerStats_Event(entity e, string event_id, float value)
79 {
80         if(!e.playerstats_id || playerstats_db < 0)
81                 return;
82         
83         string key;
84         float val;
85         key = sprintf("%s:%s", e.playerstats_id, event_id);
86         val = stof(db_get(playerstats_db, key));
87         val += value;
88         db_put(playerstats_db, key, ftos(val));
89 }
90
91 void PlayerStats_Sent_URI_Get_Callback(float id, float status, string data)
92 {
93         if(playerstats_requested)
94                 playerstats_waitforme = TRUE;
95 }
96
97 //#NO AUTOCVARS START
98 void PlayerStats_Shutdown()
99 {
100         string p, pn;
101         string e, en;
102         string nn;
103         float b;
104         float i;
105         string uri;
106
107         if(playerstats_db < 0)
108                 return;
109
110         uri = autocvar_g_playerstats_uri;
111         if(uri != "")
112         {
113                 b = buf_create();
114                 i = 0;
115
116                 db_dump(playerstats_db, "foo.db");
117
118                 bufstr_set(b, i++, "V 1");
119                 bufstr_set(b, i++, sprintf("T %s.%06d", strftime(FALSE, "%s"), floor(random() * 1000000)));
120                 bufstr_set(b, i++, sprintf("G %s", GetGametype()));
121                 bufstr_set(b, i++, sprintf("M %s", GetMapname()));
122                 bufstr_set(b, i++, sprintf("S %s", cvar_string("hostname")));
123                 bufstr_set(b, i++, sprintf("C %d", cvar_purechanges_count));
124                 for(p = playerstats_last; (pn = db_get(playerstats_db, sprintf("%s:*", p))) != ""; p = pn)
125                 {
126                         bufstr_set(b, i++, sprintf("P %s", p));
127                         nn = db_get(playerstats_db, sprintf("%s:_netname", p));
128                         if(nn != "")
129                                 bufstr_set(b, i++, sprintf("n %s", nn));
130                         for(e = events_last; (en = db_get(playerstats_db, sprintf("*:%s", e))) != ""; e = en)
131                         {
132                                 float v;
133                                 v = stof(db_get(playerstats_db, sprintf("%s:%s", p, e)));
134                                 bufstr_set(b, i++, sprintf("e %s %f", e, v));
135                         }
136                 }
137                 bufstr_set(b, i++, "");
138
139                 if(autocvar_g_playerstats_debug)
140                 {
141                         for(i = 0; i < buf_getsize(b); ++i)
142                                 print(bufstr_get(b, i), "\n");
143                 }
144
145                 if(crypto_uri_postbuf(uri, URI_GET_PLAYERSTATS_SENT, "text/plain", "\n", b, 0))
146                         playerstats_requested = TRUE;
147                 else
148                         playerstats_waitforme = TRUE; // if posting fails, we must continue anyway
149
150                 buf_del(b);
151         }
152         else
153                 playerstats_waitforme = TRUE;
154
155         db_close(playerstats_db);
156         playerstats_db = -1;
157 }
158 //#NO AUTOCVARS END
159
160 void PlayerStats_AddGlobalInfo(entity p)
161 {
162         if(playerstats_db < 0)
163                 return;
164         if(!p.playerstats_id || playerstats_db < 0)
165                 return;
166         p.playerstats_addedglobalinfo = TRUE;
167
168         // add global info!
169         if(p.alivetime)
170                 PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
171
172         if(p.alivetime)
173                 PlayerStats_Event(p, PLAYERSTATS_ALIVETIME, time - p.alivetime);
174         
175         if(p.cvar_cl_allow_uid2name == 1)
176                 db_put(playerstats_db, sprintf("%s:_netname", p.playerstats_id), p.netname);
177
178         strunzone(p.playerstats_id);
179         p.playerstats_id = string_null;
180 }
181
182 void PlayerStats_EndMatch()
183 {
184         entity p;
185         FOR_EACH_PLAYER(p)
186         {
187                 PlayerScore_PlayerStats(p);
188                 PlayerStats_Event(p, PLAYERSTATS_WINS, p.winning);
189                 PlayerStats_Event(p, PLAYERSTATS_MATCHES, 1);
190         }
191 }