· 5 years ago · Feb 01, 2020, 08:34 PM
1#pragma semicolon 1
2#pragma newdecls required
3
4#include <sourcemod>
5#include <sdktools>
6#include <cstrike>
7
8public Plugin myinfo =
9{
10 name = "Player Stats",
11 author = "Ilusion9",
12 description = "Stats tracking.",
13 version = "1.0",
14 url = "https://github.com/Ilusion9/"
15};
16
17Database hDatabase;
18int g_Headshots[MAXPLAYERS + 1];
19int g_Kills[MAXPLAYERS + 1];
20int g_Deaths[MAXPLAYERS + 1];
21int g_Score[MAXPLAYERS + 1];
22
23public void OnPluginStart()
24{
25 Database.Connect(Handle_ConnectDatabase, "rank");
26
27 HookEvent("player_team", Event_PlayerTeam);
28 HookEvent("player_death", Event_PlayerDeath);
29 HookEvent("bomb_exploded", Event_BombExploded);
30 HookEvent("bomb_defused", Event_BombDefused);
31 HookEvent("bomb_planted", Event_BombPlanted);
32 HookEvent("hostage_rescued", Event_HostageRescued);
33 HookEvent("hostage_killed", Event_HostageKilled);
34 HookEvent("round_mvp", Event_RoundMvp);
35
36 RegConsoleCmd("sm_rank", Command_Rank);
37 RegConsoleCmd("sm_top", Command_Top);
38 RegAdminCmd("sm_rankpurge", Command_RankPurge, ADMFLAG_RCON);
39
40 for (int i = 1; i <= MaxClients; i++)
41 {
42 OnClientConnected(i);
43 }
44}
45
46public void OnPluginEnd()
47{
48 for (int i = 1; i <= MaxClients; i++)
49 {
50 if (IsClientInGame(i))
51 {
52 OnClientDisconnect(i);
53 }
54 }
55}
56
57public void OnMapEnd()
58{
59 hDatabase.Query(Handle_FastQuery, "DELETE FROM rank_table WHERE date < CURRENT_DATE - INTERVAL 1 MONTH;");
60 hDatabase.Query(Handle_FastQuery, "DELETE a.* FROM name_table a LEFT JOIN rank_table b ON b.steamid = a.steamid WHERE b.steamid IS NULL;");
61}
62
63public void Handle_ConnectDatabase(Database db, const char[] error, any data)
64{
65 if (db)
66 {
67 hDatabase = db;
68 db.SetCharset("utf8mb4");
69
70 db.Query(Handle_FastQuery, "CREATE TABLE IF NOT EXISTS rank_table (steamid INT UNSIGNED, date DATE, score INT, kills INT UNSIGNED, deaths INT UNSIGNED, hs INT UNSIGNED, PRIMARY KEY (steamid, date));");
71 db.Query(Handle_FastQuery, "CREATE TABLE IF NOT EXISTS name_table (steamid INT UNSIGNED PRIMARY KEY, name VARCHAR(65) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci);");
72 }
73 else
74 {
75 SetFailState("Could not connect to the database: %s", error);
76 }
77}
78
79public void OnClientConnected(int client)
80{
81 g_Headshots[client] = 0;
82 g_Kills[client] = 0;
83 g_Deaths[client] = 0;
84 g_Score[client] = 0;
85}
86
87public void Event_PlayerTeam(Event event, const char[] name, bool dontBroadcast)
88{
89 if (event.GetInt("oldteam") == CS_TEAM_NONE)
90 {
91 int userId = event.GetInt("userid"), client = GetClientOfUserId(userId);
92
93 if (client)
94 {
95 int steam = GetSteamAccountID(client);
96
97 if (steam)
98 {
99 char query[512];
100 Format(query, sizeof(query), "SELECT r.rank, (SELECT count(steamid) from name_table) total FROM (SELECT @rank := @rank + 1 rank, s.steamid FROM (SELECT steamid, sum(score) score FROM rank_table GROUP BY steamid ORDER BY score DESC, steamid ASC) s, (SELECT @rank := 0) init) r WHERE steamid = %d;", steam);
101 hDatabase.Query(Handle_GetRankConnect, query, userId);
102 }
103 }
104 }
105}
106
107public void Handle_GetRankConnect(Database db, DBResultSet rs, const char[] error, any data)
108{
109 if (rs)
110 {
111 int client = GetClientOfUserId(view_as<int>(data));
112
113 if (client)
114 {
115 PrintToChat(client, " \x04--------------------------------");
116 PrintToChat(client, "Welcome to \x07CSGO.LALEAGANE.RO");
117
118 if (rs.FetchRow())
119 {
120 PrintToChat(client, "You are ranked \x04%d\x01 of \x04%d", rs.FetchInt(0), rs.FetchInt(1));
121 }
122 PrintToChat(client, " \x04--------------------------------");
123 }
124 }
125 else
126 {
127 LogError("Failed to query database: %s", error);
128 }
129}
130
131public void OnClientDisconnect(int client)
132{
133 int steam = GetSteamAccountID(client);
134
135 if (steam)
136 {
137 char query[512];
138
139 hDatabase.Format(query, sizeof(query), "INSERT INTO name_table (steamid, name) VALUES (%d, '%N') ON DUPLICATE KEY UPDATE name = VALUES(name);", steam, client);
140 hDatabase.Query(Handle_FastQuery, query);
141
142 Format(query, sizeof(query), "INSERT INTO rank_table (steamid, date, score, kills, deaths, hs) VALUES (%d, CURRENT_DATE, %d, %d, %d, %d) ON DUPLICATE KEY UPDATE score = score + VALUES(score), kills = kills + VALUES(kills), deaths = deaths + VALUES(deaths), hs = hs + VALUES(hs);", steam, g_Score[client], g_Kills[client], g_Deaths[client], g_Headshots[client]);
143 hDatabase.Query(Handle_FastQuery, query);
144 }
145}
146
147public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)
148{
149 if (GameRules_GetProp("m_bWarmupPeriod"))
150 {
151 return;
152 }
153
154 int client = GetClientOfUserId(event.GetInt("userid"));
155 int attacker = GetClientOfUserId(event.GetInt("attacker"));
156 int assister = GetClientOfUserId(event.GetInt("assister"));
157
158 if (attacker)
159 {
160 if (attacker != client)
161 {
162 if (event.GetBool("headshot"))
163 {
164 g_Headshots[attacker]++;
165 g_Score[attacker] += 2;
166 }
167
168 g_Kills[attacker]++;
169 g_Score[attacker] += 2;
170 }
171 }
172
173 if (assister)
174 {
175 if (assister != client)
176 {
177 g_Score[assister] += 1;
178 }
179 }
180
181 g_Score[client] -= 2;
182 g_Deaths[client]++;
183}
184
185public void Event_BombExploded(Event event, const char[] name, bool dontBroadcast)
186{
187 if (GetTeamClientCount(CS_TEAM_CT))
188 {
189 int client = GetClientOfUserId(event.GetInt("userid"));
190
191 if (client)
192 {
193 g_Score[client] += 2;
194 }
195 }
196}
197
198public void Event_BombDefused(Event event, const char[] name, bool dontBroadcast)
199{
200 int client = GetClientOfUserId(event.GetInt("userid"));
201
202 if (client)
203 {
204 g_Score[client] += 2;
205 }
206}
207
208public void Event_BombPlanted(Event event, const char[] name, bool dontBroadcast)
209{
210 if (GetTeamClientCount(CS_TEAM_CT))
211 {
212 int client = GetClientOfUserId(event.GetInt("userid"));
213
214 if (client)
215 {
216 g_Score[client] += 1;
217 }
218 }
219}
220
221public void Event_HostageRescued(Event event, const char[] name, bool dontBroadcast)
222{
223 if (GetTeamClientCount(CS_TEAM_T))
224 {
225 int client = GetClientOfUserId(event.GetInt("userid"));
226
227 if (client)
228 {
229 g_Score[client] += 2;
230 }
231 }
232}
233
234public void Event_HostageKilled(Event event, const char[] name, bool dontBroadcast)
235{
236 int client = GetClientOfUserId(event.GetInt("userid"));
237
238 if (client)
239 {
240 g_Score[client] -= 2;
241 }
242}
243
244public void Event_RoundMvp(Event event, const char[] name, bool dontBroadcast)
245{
246 if (GetTeamClientCount(CS_TEAM_T) && GetTeamClientCount(CS_TEAM_CT))
247 {
248 int client = GetClientOfUserId(event.GetInt("userid"));
249
250 if (client)
251 {
252 g_Score[client] += 2;
253 }
254 }
255}
256
257public Action Command_Rank(int client, int args)
258{
259 if (client)
260 {
261 int steam = GetSteamAccountID(client);
262
263 if (steam)
264 {
265 char query[512];
266 Format(query, sizeof(query), "SELECT r.rank, (SELECT count(steamid) from name_table) total, r.score, r.kills, r.deaths, r.hs FROM (SELECT @rank := @rank + 1 rank, s.* FROM (SELECT steamid, sum(score) score, sum(kills) kills, sum(deaths) deaths, sum(hs) hs FROM rank_table GROUP BY steamid ORDER BY score DESC, steamid ASC) s, (SELECT @rank := 0) init) r WHERE steamid = %d;", steam);
267 hDatabase.Query(Handle_GetRankCommand, query, GetClientUserId(client));
268 }
269 }
270
271 return Plugin_Handled;
272}
273
274public void Handle_GetRankCommand(Database db, DBResultSet rs, const char[] error, any data)
275{
276 if (rs)
277 {
278 int client = GetClientOfUserId(view_as<int>(data));
279
280 if (client)
281 {
282 if (rs.FetchRow())
283 {
284 int kills = rs.FetchInt(3);
285 int deaths = rs.FetchInt(4);
286 int headshots = rs.FetchInt(5);
287 float KPD = deaths ? 1.0 * kills / deaths : 1.0;
288 int HPK = kills ? 100 * headshots / kills : 0;
289
290 Panel panel = new Panel();
291 panel.DrawText("Rank");
292 panel.DrawText(" ");
293
294 char row[256];
295
296 Format(row, sizeof(row), "Ranked %d of %d", rs.FetchInt(0), rs.FetchInt(1));
297 panel.DrawText(row);
298
299 Format(row, sizeof(row), "%d points", rs.FetchInt(2));
300 panel.DrawText(row);
301
302 Format(row, sizeof(row), "%d:%d frags (%0.2f)", kills, deaths, KPD);
303 panel.DrawText(row);
304
305 Format(row, sizeof(row), "%d headshots (%d%c)", headshots, HPK, '%');
306 panel.DrawText(row);
307
308 panel.DrawText(" ");
309
310 panel.DrawItem("Close");
311 panel.Send(client, Panel_DoNothing, MENU_TIME_FOREVER);
312
313 delete panel;
314 }
315 }
316 }
317 else
318 {
319 LogError("Failed to query database: %s", error);
320 }
321}
322
323public Action Command_Top(int client, int args)
324{
325 if (client)
326 {
327 hDatabase.Query(Handle_GetTop, "SELECT r.rank, r.score, r.name FROM (SELECT @rank := @rank + 1 rank, s.* FROM (SELECT b.name, sum(a.score) score FROM rank_table a JOIN name_table b ON a.steamid = b.steamid GROUP BY a.steamid ORDER BY score DESC, a.steamid ASC LIMIT 10) s, (SELECT @rank := 0) init) r;", GetClientUserId(client));
328 }
329
330 return Plugin_Handled;
331}
332
333public void Handle_GetTop(Database db, DBResultSet rs, const char[] error, any data)
334{
335 if (rs)
336 {
337 int client = GetClientOfUserId(view_as<int>(data));
338
339 if (client)
340 {
341 if (rs.HasResults)
342 {
343 Panel panel = new Panel();
344
345 panel.DrawText("Top");
346 panel.DrawText(" ");
347
348 for(int i = 0; i < rs.RowCount; i++)
349 {
350 if (rs.FetchRow())
351 {
352 char name[65], row[256];
353 rs.FetchString(2, name, sizeof(name));
354 Format(row, sizeof(row), "%02d. %dp : %s", rs.FetchInt(0), rs.FetchInt(1), name);
355 panel.DrawText(row);
356 }
357 }
358
359 panel.DrawText(" ");
360 panel.DrawItem("Close");
361
362 panel.Send(client, Panel_DoNothing, MENU_TIME_FOREVER);
363 delete panel;
364 }
365 }
366 }
367 else
368 {
369 LogError("Failed to query database: %s", error);
370 }
371}
372
373public Action Command_RankPurge(int client, int args)
374{
375 hDatabase.Query(Handle_FastQuery, "TRUNCATE rank_table;");
376 hDatabase.Query(Handle_FastQuery, "TRUNCATE name_table;");
377
378 ReplyToCommand(client, "All players stats have been purged.");
379 return Plugin_Handled;
380}
381
382public int Panel_DoNothing(Menu menu, MenuAction action, int param1, int param2)
383{
384
385}
386
387public void Handle_FastQuery(Database db, DBResultSet rs, const char[] error, any data)
388{
389 if (!rs)
390 {
391 LogError("Failed to query database: %s", error);
392 }
393}