· 6 years ago · Aug 15, 2019, 10:08 PM
1#pragma semicolon 1
2
3// ===================
4// >>> DEFINE
5// ===================
6
7#define PLUGIN_AUTHOR "Bioly"
8#define PLUGIN_VERSION "1.0"
9#define LoopValidClients(%1) for(int %1 = 1; %1 < MaxClients; %1++) if(IsValidClient(%1))
10
11// ====================
12// >>> INCLUDE
13// ====================
14
15#include <sourcemod>
16#include <sdktools>
17#include <cstrike>
18#include <sdkhooks>
19#include <colors>
20#include <dbi>
21#undef REQUIRE_PLUGIN
22#tryinclude <store>
23#tryinclude <smrpg>
24#define REQUIRE_PLUGIN
25
26// ====================
27// >>> ZMIENNE
28// ====================
29
30ConVar g_cvPrefix, g_cvNetwork;
31Database DatabaseHandle;
32int g_iWords;
33int g_iTime[MAXPLAYERS];
34int g_iConnTime[MAXPLAYERS];
35int g_iHours[MAXPLAYERS];
36int g_iRank[MAXPLAYERS];
37char g_cConfigFile[PLATFORM_MAX_PATH];
38char g_cError[128];
39char g_cPrefix[64];
40char g_cNetwork[64];
41char g_cRanksName[256][PLATFORM_MAX_PATH];
42char g_cHours[256][PLATFORM_MAX_PATH];
43char g_cZeph[256][PLATFORM_MAX_PATH];
44char g_cRPG[256][PLATFORM_MAX_PATH];
45char g_cVip[256][PLATFORM_MAX_PATH];
46char g_cVipFlags[256][PLATFORM_MAX_PATH];
47char PluginName[64];
48
49#pragma newdecls required
50
51EngineVersion g_Game;
52
53// ===========================
54// >>> PLUGIN INFO
55// ===========================
56
57public Plugin myinfo =
58{
59 name = "[Bioly] Ranks",
60 author = PLUGIN_AUTHOR,
61 description = "N/A",
62 version = PLUGIN_VERSION,
63 url = "id/ToTenBioly"
64};
65
66// ====================
67// >>> OnPluginStart
68// ====================
69
70public void OnPluginStart()
71{
72 Errors.SetPluginName("[Bioly] Ranks");
73 g_Game = GetEngineVersion();
74 if (g_Game != Engine_CSGO && g_Game != Engine_CSS)
75 {
76 Errors.ThrowCriticalError(0, "Ten plugin jest tylko do CSGO/CSS.");
77 }
78 DB_Connect();
79 BuildPath(Path_SM, g_cConfigFile, sizeof(g_cConfigFile), "configs/bioly_ranks.cfg");
80 g_cvPrefix = CreateConVar("ranks_prefix", "[{lightred}Rangi{default}]", "Tag przed wiadomością.");
81 g_cvNetwork = CreateConVar("ranks_network", "PluginySM.pl", "Nazwa sieci (wyświetlana w menu).");
82 AutoExecConfig(true, "Bioly_Ranks");
83 HookEvent("player_spawn", playerSpawn);
84 RegConsoleCmd("sm_staty", RanksCallback);
85}
86public void OnConfigsExecuted()
87{
88 g_cvPrefix.GetString(g_cPrefix, sizeof(g_cPrefix));
89 g_cvNetwork.GetString(g_cNetwork, sizeof(g_cNetwork));
90}
91public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
92{
93 MarkNativeAsOptional("Store_SetClientCredits");
94 MarkNativeAsOptional("Store_GetClientCredits");
95 MarkNativeAsOptional("SMRPG_SetClientCredits");
96 MarkNativeAsOptional("SMRPG_GetClientCredits");
97 return APLRes_Success;
98}
99public void OnMapStart()
100{
101 DB_Connect();
102 LoadInfo();
103}
104public Action playerSpawn(Handle event, char[] name, bool dontBroadcast)
105{
106 int client = GetClientOfUserId(GetEventInt(event, "userid"));
107
108 if (IsValidClient(client))
109 {
110 int iTIME = g_iConnTime[client] > 0 ? g_iConnTime[client]:GetTime();
111 g_iTime[client] += (GetTime() - iTIME);
112 if (GameRules_GetProp("m_bWarmupPeriod") != 1)
113 {
114 char buffer[64];
115 g_iHours[client] = (g_iTime[client] / 60) / 60;
116 GetRank(g_iHours[client], g_iRank[client], buffer, 64);
117 if (!StrEqual(buffer, g_cRanksName[g_iRank[client]], false))
118 {
119 g_iRank[client] += 1;
120 if (StringToInt(g_cRPG[g_iRank[client]]) != 0)SMRPG_SetClientCredits(client, SMRPG_GetClientCredits(client) + StringToInt(g_cRPG[g_iRank[client]]));
121 if (StringToInt(g_cZeph[g_iRank[client]]) != 0)Store_SetClientCredits(client, Store_GetClientCredits(client) + StringToInt(g_cZeph[g_iRank[client]]));
122 strcopy(g_cRanksName[g_iRank[client]], 64, buffer);
123 CPrintToChat(client, " ");
124 CPrintToChat(client, "===================== \x04» RANGI « \x01=====================");
125 CPrintToChat(client, "%s \x04Gratulacje! \x01Awansowałeś na rangę: \x0B%s", g_cPrefix, g_cRanksName[g_iRank[client]]);
126 CPrintToChat(client, "===================== \x04» RANGI « \x01=====================");
127 CPrintToChat(client, " ");
128 }
129 }
130 if (StringToInt(g_cVip[g_iRank[client]]) == 1)
131 {
132 SetUserFlagBits(client, GetUserFlagBits(client) | ReadFlagString(g_cVipFlags[g_iRank[client]]));
133 }
134 }
135}
136public Action RanksCallback(int client, int args)
137{
138 g_iHours[client] = (g_iTime[client] / 60) / 60;
139 Menu RanksMenu = new Menu(RanksMenuCallback);
140 RanksMenu.SetTitle("%s :: Spis rang\n» Twoja aktualna ranga: %s\n» Godziny na serwerze: %iH\n \n", g_cNetwork, g_cRanksName[g_iRank[client]], g_iHours[client]);
141 if (GetUserFlagBits(client) & ADMFLAG_ROOT)RanksMenu.AddItem("root", "Menu admina");
142 char item[64], buffer[64];
143 for (int i = 0; i < g_iWords; i++)
144 {
145 Format(item, sizeof(item), "%s", g_cRanksName[i]);
146 IntToString(i, buffer, sizeof(buffer));
147 RanksMenu.AddItem(buffer, item);
148 }
149 RanksMenu.ExitButton = true;
150 RanksMenu.Display(client, MENU_TIME_FOREVER);
151 return Plugin_Handled;
152}
153public int RanksMenuCallback(Menu RanksMenu, MenuAction action, int param1, int param2)
154{
155 switch (action)
156 {
157 case MenuAction_Select:
158 {
159 char item[64];
160 RanksMenu.GetItem(param2, item, sizeof(item));
161 if (StrEqual(item, "root"))
162 {
163 OpenRootMenu(param1);
164 return;
165 }
166 int id = StringToInt(item);
167 CPrintToChat(param1, " ");
168 CPrintToChat(param1, "===================== \x10» RANGI « \x01=====================");
169 CPrintToChat(param1, "%s Nazwa rangi: \x0B%s", g_cPrefix, g_cRanksName[id]);
170 CPrintToChat(param1, "%s Potrzebne godziny: \x0B%i", g_cPrefix, StringToInt(g_cHours[id]));
171 if (StringToInt(g_cZeph[id]) != 0)CPrintToChat(param1, "%s Bonusowe kredyty: \x0B%i", g_cPrefix, StringToInt(g_cZeph[id]));
172 if (StringToInt(g_cRPG[id]) != 0)CPrintToChat(param1, "%s Bonusowe RPG: \x0B%i", g_cPrefix, StringToInt(g_cRPG[id]));
173 CPrintToChat(param1, "%s Bonusowy VIP: %s", g_cPrefix, StringToInt(g_cVip[id]) == 1 ? "\x04Tak":"\x02Nie");
174 CPrintToChat(param1, "===================== \x10» RANGI « \x01=====================");
175 CPrintToChat(param1, " ");
176 }
177 case MenuAction_End:
178 {
179 delete RanksMenu;
180 }
181 }
182}
183public void GetRank(int time, int rank, char[] buffer, int maxlen)
184{
185 int iWords = g_iWords - 1;
186 if (rank != iWords)
187 {
188 if (time >= StringToInt(g_cHours[rank + 1]))
189 {
190 strcopy(buffer, maxlen, g_cRanksName[rank + 1]);
191 }
192 else strcopy(buffer, 64, g_cRanksName[rank]);
193 }
194 else strcopy(buffer, 64, g_cRanksName[rank]);
195}
196public void OpenRootMenu(int client)
197{
198 Menu AdminMenu = new Menu(AdminMenuCallback);
199 AdminMenu.SetTitle("%s :: Menu admina\n \n", g_cNetwork);
200 AdminMenu.AddItem("resetplayer", "Zresetuj rangę pojedynczemu graczowi");
201 AdminMenu.AddItem("resetall", "Zresetuj rangi wszystkim");
202 AdminMenu.AddItem("setrank", "Ustaw rangę graczowwi");
203 AdminMenu.ExitBackButton = true;
204 AdminMenu.ExitButton = true;
205 AdminMenu.Display(client, MENU_TIME_FOREVER);
206}
207public int AdminMenuCallback(Menu AdminMenu, MenuAction action, int param1, int param2)
208{
209 switch (action)
210 {
211 case MenuAction_Select:
212 {
213 char item[64];
214 char sQuery[300];
215 AdminMenu.GetItem(param2, item, sizeof(item));
216 if (StrEqual(item, "resetplayer"))
217 {
218 Format(sQuery, sizeof(sQuery), "SELECT * FROM `ranksbase`");
219 DatabaseHandle.Query(DB_ResetRanksCallback, sQuery, param1);
220 }
221 else if (StrEqual(item, "resetall"))
222 {
223 CPrintToChatAll("%s Administrator \x07%N \x01zresetował wszystkim rangi.", g_cPrefix, param1);
224 LoopValidClients(i)
225 {
226 ResetAllVariables(i);
227 Format(sQuery, sizeof(sQuery), "UPDATE `ranksbase` SET `time`='0', `rank`='0'");
228 DatabaseHandle.Query(SQLCallback_Void, sQuery);
229 }
230 }
231 else if (StrEqual(item, "setrank"))
232 {
233 SetRank(param1);
234 }
235 }
236 case MenuAction_Cancel:
237 {
238 ClientCommand(param1, "sm_rangi");
239 }
240 case MenuAction_End:
241 {
242 delete AdminMenu;
243 }
244 }
245}
246public void SetRank(int client)
247{
248 Menu menu = CreateMenu(InvitationMenu_Callback, MenuAction_Select | MenuAction_End | MenuAction_DisplayItem);
249 char sInfoString[64];
250 char sDisplayString[64];
251 menu.SetTitle("%s :: Wybierz gracza\n \n", g_cNetwork);
252 for (int i = 1; i <= MaxClients; i++)
253 {
254 if (IsValidClient(i))
255 {
256 Format(sInfoString, sizeof(sInfoString), "%i", GetClientUserId(i));
257 Format(sDisplayString, sizeof(sDisplayString), "[%s] %N", g_cRanksName[g_iRank[i]], i);
258 menu.AddItem(sInfoString, sDisplayString);
259 }
260 }
261 menu.ExitBackButton = true;
262 menu.Display(client, MENU_TIME_FOREVER);
263}
264public int InvitationMenu_Callback(Menu menu, MenuAction action, int param1, int param2)
265{
266 switch (action)
267 {
268 case MenuAction_Select:
269 {
270 char sInfo[64];
271 menu.GetItem(param2, sInfo, sizeof(sInfo));
272 int iUserID = StringToInt(sInfo);
273 int iTargetID = GetClientOfUserId(iUserID);
274 SetRank_Rank(param1, iTargetID);
275 }
276 case MenuAction_Cancel:
277 {
278 OpenRootMenu(param1);
279 }
280 case MenuAction_End:
281 {
282 delete menu;
283 }
284 }
285 return;
286}
287public void SetRank_Rank(int client, int target)
288{
289 Menu SetRankMenu = CreateMenu(SetRankMenu_Callback, MenuAction_Select | MenuAction_End | MenuAction_DisplayItem);
290 char sInfoString[64];
291 char sDisplayString[64];
292 //char sTempArray[2][128];
293 SetRankMenu.SetTitle("%s :: Wybierz rangę dla gracza %N\n \n", g_cNetwork, target);
294 for (int i = 0; i < g_iWords; i++)
295 {
296 Format(sDisplayString, sizeof(sDisplayString), "%s", g_cRanksName[i]);
297 Format(sInfoString, sizeof(sInfoString), "%i;%i", target, i);
298 SetRankMenu.AddItem(sInfoString, sDisplayString);
299 }
300 SetRankMenu.ExitBackButton = true;
301 SetRankMenu.Display(client, MENU_TIME_FOREVER);
302}
303public int SetRankMenu_Callback(Menu SetRankMenu, MenuAction action, int param1, int param2)
304{
305 switch (action)
306 {
307 case MenuAction_Select:
308 {
309 char sInfo[64];
310 char sTempArray[2][128];
311 SetRankMenu.GetItem(param2, sInfo, sizeof(sInfo));
312 ExplodeString(sInfo, ";", sTempArray, 2, sizeof(sTempArray[])); // sTempArray[0] - target | sTempArray[1] - iRank
313 int iTarget = StringToInt(sTempArray[0]);
314 int iRank = StringToInt(sTempArray[1]);
315 g_iRank[iTarget] = iRank;
316 CPrintToChat(iTarget, "===================== \x10» RANGI « \x01=====================");
317 CPrintToChat(iTarget, "%s Administrator \x07%N \x01ustawił Ci nową rangę.", g_cPrefix, param1);
318 CPrintToChat(iTarget, "%s Nowa ranga: \x06%s\x01.", g_cPrefix, g_cRanksName[iRank]);
319 CPrintToChat(iTarget, "===================== \x10» RANGI « \x01=====================");
320 CPrintToChat(param1, "===================== \x10» RANGI « \x01=====================");
321 CPrintToChat(param1, "%s Poprawnie ustawiłeś rangę graczowi \x07%N\x01.", g_cPrefix, iTarget);
322 CPrintToChat(param1, "%s Nowa ranga: \x06%s\x01.", g_cPrefix, g_cRanksName[iRank]);
323 CPrintToChat(param1, "===================== \x10» RANGI « \x01=====================");
324 }
325 case MenuAction_Cancel:
326 {
327 OpenRootMenu(param1);
328 }
329 case MenuAction_End:
330 {
331 delete SetRankMenu;
332 }
333 }
334 return;
335}
336public void DB_ResetRanksCallback(Database db, DBResultSet results, const char[] error, int data)
337{
338 int i;
339 int client = data;
340
341 if (!IsValidClient(client))
342 return;
343
344 Menu menu = new Menu(ResetStats_Handler, MENU_ACTIONS_ALL);
345 menu.SetTitle("%s :: Zresetuj statystyki gracza\n \n", g_cNetwork);
346
347 char item[64];
348
349 while (results.FetchRow())
350 {
351 char nick[128];
352 char steamid[128];
353 i++;
354 results.FetchString(0, steamid, sizeof(steamid)); // steamid
355 results.FetchString(3, nick, sizeof(nick)); // Player Name
356 Format(item, sizeof(item), "%s", nick);
357 menu.AddItem(steamid, item);
358 }
359
360 if (i == 0)
361 menu.AddItem("nothing", "Brak danych.");
362
363 menu.ExitBackButton = true;
364 menu.ExitButton = true;
365 menu.Display(client, 0);
366}
367public int ResetStats_Handler(Menu menu, MenuAction action, int param1, int param2)
368{
369 switch (action)
370 {
371 case MenuAction_Select:
372 {
373 char info[128];
374 char sQuery[300];
375 char sSteamID[64];
376 menu.GetItem(param2, info, sizeof(info));
377 LoopValidClients(i)
378 {
379 GetClientAuthId(i, AuthId_SteamID64, sSteamID, sizeof(sSteamID));
380 if (StrEqual(sSteamID, info))
381 {
382 char nick[64];
383 GetClientName(i, nick, sizeof(nick));
384 CPrintToChatAll("%s Administrator \x07%N \x01zresetował statystyki graczowi o nicku \x10%s\x01 .", g_cPrefix, param1, nick);
385 }
386 else
387 {
388 CPrintToChatAll("%s Administrator \x07%N \x01zresetował statystyki graczowi ze SteamID: \x10%s\x01.", g_cPrefix, param1, info);
389 }
390 }
391 Format(sQuery, sizeof(sQuery), "UPDATE `ranksbase` SET `time`='0', `rank`='0' WHERE `steamid`='%s'", info);
392 DatabaseHandle.Query(SQLCallback_Void, sQuery);
393 LoopValidClients(i)
394 {
395 GetClientAuthId(i, AuthId_SteamID64, sSteamID, sizeof(sSteamID));
396 if (StrEqual(sSteamID, info))
397 {
398 ResetAllVariables(i);
399 }
400 }
401 }
402 case MenuAction_Cancel:
403 {
404 OpenRootMenu(param1);
405 }
406 case MenuAction_End:
407 {
408 CloseHandle(menu);
409 }
410 }
411}
412public void OnClientAuthorized(int client, const char[] auth)
413{
414 DataPack dp = new DataPack();
415 dp.WriteCell(client);
416 dp.WriteString(auth);
417 CreateTimer(1.0, RanksGen, dp);
418}
419public Action RanksGen(Handle timer, DataPack dp)
420{
421 dp.Reset();
422 int client = dp.ReadCell();
423 if (!IsFakeClient(client))
424 {
425 char auth[64];
426 dp.ReadString(auth, sizeof(auth));
427 g_iConnTime[client] = GetTime();
428 DB_LoadRanks(client, auth);
429 }
430}
431public void OnClientDisconnect(int client)
432{
433 int iTIME = g_iConnTime[client] > 0 ? g_iConnTime[client]:GetTime();
434 g_iTime[client] += (GetTime() - iTIME);
435 DB_UpdateAccount(client);
436 ResetAllVariables(client);
437}
438public void LoadInfo()
439{
440 g_iWords = 0;
441 KeyValues kvConfig = CreateKeyValues("Rangi");
442
443 if (!kvConfig.ImportFromFile(g_cConfigFile))
444 {
445 Format(g_cError, sizeof(g_cError), "[- Bioly_Ranks -] Nie można odczytać poprawnie configu %s", g_cConfigFile);
446 Errors.ThrowCriticalError(2, g_cError);
447 delete kvConfig;
448 return;
449 }
450
451 if (!kvConfig.GotoFirstSubKey())
452 {
453 Format(g_cError, sizeof(g_cError), "[- Bioly_Ranks -] Nie można odczytać poprawnie configu %s", g_cConfigFile);
454 Errors.ThrowCriticalError(3, g_cError);
455 delete kvConfig;
456 return;
457 }
458
459 do
460 {
461 kvConfig.GetString("nazwa", g_cRanksName[g_iWords], sizeof(g_cRanksName[]));
462 kvConfig.GetString("godziny", g_cHours[g_iWords], sizeof(g_cHours[]));
463 kvConfig.GetString("kredyty", g_cZeph[g_iWords], sizeof(g_cZeph[]));
464 kvConfig.GetString("rpg", g_cRPG[g_iWords], sizeof(g_cRPG[]));
465 kvConfig.GetString("vip", g_cVip[g_iWords], sizeof(g_cVip[]));
466 kvConfig.GetString("flags", g_cVipFlags[g_iWords], sizeof(g_cVipFlags[]));
467 g_iWords += 1;
468 }
469 while (kvConfig.GotoNextKey());
470
471 delete kvConfig;
472}
473public void DB_Connect()
474{
475 if (SQL_CheckConfig("bRanks"))
476 Database.Connect(DB_ConnectCallback, "bRanks");
477 else
478 {
479 Format(g_cError, sizeof(g_cError), "[- Bioly_Ranks -] Brak wpisu 'bRanks' w configu database.cfg.");
480 Errors.ThrowCriticalError(4, g_cError);
481 }
482 return;
483}
484public void DB_ConnectCallback(Database db, const char[] error, any data)
485{
486 if (db == null || error[0])
487 {
488 Format(g_cError, sizeof(g_cError), "[- Bioly_Ranks -] Error: %s", error);
489 Errors.ThrowCriticalError(5, g_cError);
490 }
491 DatabaseHandle = db;
492 char sQuery[300];
493 Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `ranksbase` ( `steamid` VARCHAR(28) NOT NULL , `time` INT(20) NOT NULL , `rank` SMALLINT(4) NOT NULL , `nick` VARCHAR(64) NOT NULL , PRIMARY KEY (`steamid`)) ENGINE = InnoDB;");
494 DatabaseHandle.Query(SQLCallback_Void, sQuery);
495}
496public void DB_LoadRanks(int client, const char[] auth)
497{
498 char sQuery[256];
499 Format(sQuery, sizeof(sQuery), "SELECT * FROM `ranksbase` WHERE `steamid`='%s'", auth);
500 DatabaseHandle.Query(DB_LoadRanksCallback, sQuery, client);
501}
502public void DB_LoadRanksCallback(Database db, DBResultSet results, const char[] error, any data)
503{
504 int client = data;
505 if (results == null)
506 {
507 KickClient(client, "[- Bioly_Ranks -] Twoje konto nie zostało zautoryzowane.");
508 LogError("[- Bioly_Ranks -] Wystąpił błąd w funkcji `DB_LoadRanks_Callback`. Error: %s", error);
509 return;
510 }
511 if (results.RowCount > 0)
512 {
513 if (results.FetchRow())
514 {
515 g_iTime[client] = results.FetchInt(1);
516 g_iRank[client] = results.FetchInt(2);
517 }
518 }
519 else
520 {
521 DB_CreateAccount(client);
522 }
523}
524public void DB_CreateAccount(int client)
525{
526 char sQuery[256];
527 char auth[35];
528 char name[128];
529 char checkedname[128];
530 GetClientAuthId(client, AuthId_Steam2, auth, sizeof(auth));
531 GetClientName(client, name, sizeof(name));
532 SQL_EscapeString(DatabaseHandle, name, checkedname, sizeof(checkedname));
533 Format(sQuery, sizeof(sQuery), "INSERT INTO `ranksbase` VALUES ('%s', '0', '0', '%s')", auth, checkedname);
534 g_iTime[client] = 0;
535 g_iRank[client] = 0;
536 DatabaseHandle.Query(SQLCallback_Void, sQuery);
537}
538public void DB_UpdateAccount(int client)
539{
540 char sQuery[256];
541 char auth[35];
542 char name[128];
543 char checkedname[128];
544 GetClientAuthId(client, AuthId_Steam2, auth, sizeof(auth));
545 GetClientName(client, name, sizeof(name));
546 SQL_EscapeString(DatabaseHandle, name, checkedname, sizeof(checkedname));
547 Format(sQuery, sizeof(sQuery), "UPDATE `ranksbase` SET `time`='%i', `rank`='%i', `nick`='%s' WHERE `steamid`='%s'", g_iTime[client], g_iRank[client], checkedname, auth);
548 DatabaseHandle.Query(SQLCallback_Void, sQuery);
549}
550public void SQLCallback_Void(Database db, DBResultSet results, const char[] error, int data)
551{
552 if (db == null)
553 {
554 LogError("[- Bioly_Ranks -] Error (%i): %s", data, error);
555 }
556}
557public void ResetAllVariables(int client)
558{
559 g_iTime[client] = 0;
560 g_iConnTime[client] = 0;
561 g_iHours[client] = 0;
562 g_iRank[client] = 0;
563}
564methodmap Errors {
565 public static void SetPluginName(char[] name) {
566 strcopy(PluginName, sizeof(PluginName), name);
567 }
568 public static void ThrowCriticalError(int errorCode, char[] error) {
569 LogError("[Error] Wystąpił błąd w pluginie %s [#%i]. Kod błędu: %s.", PluginName, errorCode, error);
570 SetFailState("Wystąpił błąd w pluginie [#%i]. Szczegóły znajdziesz w logach błędów.", errorCode);
571 }
572}
573stock bool IsValidClient(int client)
574{
575 if (client <= 0 || client > MaxClients || !IsClientConnected(client) || IsFakeClient(client))
576 {
577 return false;
578 }
579 return IsClientInGame(client);
580}