· 9 years ago · Dec 29, 2016, 03:52 AM
1public PlVers:__version =
2{
3 version = 5,
4 filevers = "1.5.4-dev+4047",
5 date = "07/02/2014",
6 time = "15:08:13"
7};
8new Float:NULL_VECTOR[3];
9new String:NULL_STRING[4];
10public Extension:__ext_core =
11{
12 name = "Core",
13 file = "core",
14 autoload = 0,
15 required = 0,
16};
17new MaxClients;
18public Plugin:myinfo =
19{
20 name = "[bTimes] Core",
21 description = "The root of bTimes",
22 author = "blacky",
23 version = "1.8.3",
24 url = "http://steamcommunity.com/id/blaackyy/"
25};
26public Extension:__ext_sdktools =
27{
28 name = "SDKTools",
29 file = "sdktools.ext",
30 autoload = 1,
31 required = 1,
32};
33new _pl_scp = 1792;
34new localIPRanges[4] =
35{
36 -1, 0, 0, 0
37};
38new String:chatColorNames[12][0];
39new String:chatColorTags[12][16] =
40{
41 "normal",
42 "orange",
43 "red",
44 "redblue",
45 "blue",
46 "bluered",
47 "team",
48 "lightgreen",
49 "gray",
50 "green",
51 "olivegreen",
52 "black"
53};
54new chatColorInfo[12][4] =
55{
56 {
57 1, -1, 1, -3
58 },
59 {
60 1, 0, 1, -3
61 },
62 {
63 3, 9, 1, 2
64 },
65 {
66 3, 4, 1, 2
67 },
68 {
69 3, 9, 1, 3
70 },
71 {
72 3, 2, 1, 3
73 },
74 {
75 3, 9, 1, -2
76 },
77 {
78 3, 9, 1, 0
79 },
80 {
81 3, 9, 1, -1
82 },
83 {
84 4, 0, 1, -3
85 },
86 {
87 5, 9, 1, -3
88 },
89 {
90 6, 9, 1, -3
91 }
92};
93new bool:checkTeamPlay;
94new Handle:mp_teamplay;
95new bool:isSayText2_supported = 1;
96new chatSubject = -2;
97new g_GameType;
98new printToChat_excludeclient;
99new Handle:g_hCommandList;
100new bool:g_bCommandListLoaded;
101new Handle:g_DB;
102new String:g_sMapName[64];
103new g_PlayerID[66];
104new Handle:g_MapList;
105new Handle:g_hDbMapNameList;
106new Handle:g_hDbMapIdList;
107new bool:g_bDbMapsLoaded;
108new Float:g_fMapStart;
109new Float:g_fSpamTime[66];
110new Float:g_fJoinTime[66];
111new String:g_msg_start[128];
112new String:g_msg_varcol[128] = "\x07B4D398";
113new String:g_msg_textcol[128] = "\x01";
114new Handle:g_fwdMapIDPostCheck;
115new Handle:g_fwdMapListLoaded;
116new Handle:g_fwdPlayerIDLoaded;
117new Handle:g_hPlayerID;
118new Handle:g_hUser;
119new bool:g_bPlayerListLoaded;
120new Handle:g_hChangeLogURL;
121public __ext_core_SetNTVOptional()
122{
123 MarkNativeAsOptional("GetFeatureStatus");
124 MarkNativeAsOptional("RequireFeature");
125 MarkNativeAsOptional("AddCommandListener");
126 MarkNativeAsOptional("RemoveCommandListener");
127 MarkNativeAsOptional("BfWriteBool");
128 MarkNativeAsOptional("BfWriteByte");
129 MarkNativeAsOptional("BfWriteChar");
130 MarkNativeAsOptional("BfWriteShort");
131 MarkNativeAsOptional("BfWriteWord");
132 MarkNativeAsOptional("BfWriteNum");
133 MarkNativeAsOptional("BfWriteFloat");
134 MarkNativeAsOptional("BfWriteString");
135 MarkNativeAsOptional("BfWriteEntity");
136 MarkNativeAsOptional("BfWriteAngle");
137 MarkNativeAsOptional("BfWriteCoord");
138 MarkNativeAsOptional("BfWriteVecCoord");
139 MarkNativeAsOptional("BfWriteVecNormal");
140 MarkNativeAsOptional("BfWriteAngles");
141 MarkNativeAsOptional("BfReadBool");
142 MarkNativeAsOptional("BfReadByte");
143 MarkNativeAsOptional("BfReadChar");
144 MarkNativeAsOptional("BfReadShort");
145 MarkNativeAsOptional("BfReadWord");
146 MarkNativeAsOptional("BfReadNum");
147 MarkNativeAsOptional("BfReadFloat");
148 MarkNativeAsOptional("BfReadString");
149 MarkNativeAsOptional("BfReadEntity");
150 MarkNativeAsOptional("BfReadAngle");
151 MarkNativeAsOptional("BfReadCoord");
152 MarkNativeAsOptional("BfReadVecCoord");
153 MarkNativeAsOptional("BfReadVecNormal");
154 MarkNativeAsOptional("BfReadAngles");
155 MarkNativeAsOptional("BfGetNumBytesLeft");
156 MarkNativeAsOptional("PbReadInt");
157 MarkNativeAsOptional("PbReadFloat");
158 MarkNativeAsOptional("PbReadBool");
159 MarkNativeAsOptional("PbReadString");
160 MarkNativeAsOptional("PbReadColor");
161 MarkNativeAsOptional("PbReadAngle");
162 MarkNativeAsOptional("PbReadVector");
163 MarkNativeAsOptional("PbReadVector2D");
164 MarkNativeAsOptional("PbGetRepeatedFieldCount");
165 MarkNativeAsOptional("PbReadRepeatedInt");
166 MarkNativeAsOptional("PbReadRepeatedFloat");
167 MarkNativeAsOptional("PbReadRepeatedBool");
168 MarkNativeAsOptional("PbReadRepeatedString");
169 MarkNativeAsOptional("PbReadRepeatedColor");
170 MarkNativeAsOptional("PbReadRepeatedAngle");
171 MarkNativeAsOptional("PbReadRepeatedVector");
172 MarkNativeAsOptional("PbReadRepeatedVector2D");
173 MarkNativeAsOptional("PbSetInt");
174 MarkNativeAsOptional("PbSetFloat");
175 MarkNativeAsOptional("PbSetBool");
176 MarkNativeAsOptional("PbSetString");
177 MarkNativeAsOptional("PbSetColor");
178 MarkNativeAsOptional("PbSetAngle");
179 MarkNativeAsOptional("PbSetVector");
180 MarkNativeAsOptional("PbSetVector2D");
181 MarkNativeAsOptional("PbAddInt");
182 MarkNativeAsOptional("PbAddFloat");
183 MarkNativeAsOptional("PbAddBool");
184 MarkNativeAsOptional("PbAddString");
185 MarkNativeAsOptional("PbAddColor");
186 MarkNativeAsOptional("PbAddAngle");
187 MarkNativeAsOptional("PbAddVector");
188 MarkNativeAsOptional("PbAddVector2D");
189 MarkNativeAsOptional("PbReadMessage");
190 MarkNativeAsOptional("PbReadRepeatedMessage");
191 MarkNativeAsOptional("PbAddMessage");
192 VerifyCoreVersion();
193 return 0;
194}
195
196Float:operator/(Float:,_:)(Float:oper1, oper2)
197{
198 return oper1 / float(oper2);
199}
200
201Float:operator-(Float:,_:)(Float:oper1, oper2)
202{
203 return oper1 - float(oper2);
204}
205
206bool:operator<(Float:,Float:)(Float:oper1, Float:oper2)
207{
208 return FloatCompare(oper1, oper2) < 0;
209}
210
211bool:operator<=(Float:,Float:)(Float:oper1, Float:oper2)
212{
213 return FloatCompare(oper1, oper2) <= 0;
214}
215
216bool:StrEqual(String:str1[], String:str2[], bool:caseSensitive)
217{
218 return strcmp(str1, str2, caseSensitive) == 0;
219}
220
221Handle:StartMessageOne(String:msgname[], client, flags)
222{
223 new players[1];
224 players[0] = client;
225 return StartMessage(msgname, players, 1, flags);
226}
227
228ShowMOTDPanel(client, String:title[], String:msg[], type)
229{
230 decl String:num[4];
231 new Handle:Kv = CreateKeyValues("data", "", "");
232 IntToString(type, num, 3);
233 KvSetString(Kv, "title", title);
234 KvSetString(Kv, "type", num);
235 KvSetString(Kv, "msg", msg);
236 ShowVGUIPanel(client, "info", Kv, true);
237 CloseHandle(Kv);
238 return 0;
239}
240
241ByteCountToCells(size)
242{
243 if (!size)
244 {
245 return 1;
246 }
247 return size + 3 / 4;
248}
249
250ReplyToTargetError(client, reason)
251{
252 switch (reason)
253 {
254 case -7:
255 {
256 ReplyToCommand(client, "[SM] %t", "More than one client matched");
257 }
258 case -6:
259 {
260 ReplyToCommand(client, "[SM] %t", "Cannot target bot");
261 }
262 case -5:
263 {
264 ReplyToCommand(client, "[SM] %t", "No matching clients");
265 }
266 case -4:
267 {
268 ReplyToCommand(client, "[SM] %t", "Unable to target");
269 }
270 case -3:
271 {
272 ReplyToCommand(client, "[SM] %t", "Target is not in game");
273 }
274 case -2:
275 {
276 ReplyToCommand(client, "[SM] %t", "Target must be dead");
277 }
278 case -1:
279 {
280 ReplyToCommand(client, "[SM] %t", "Target must be alive");
281 }
282 case 0:
283 {
284 ReplyToCommand(client, "[SM] %t", "No matching client");
285 }
286 default:
287 {
288 }
289 }
290 return 0;
291}
292
293FindTarget(client, String:target[], bool:nobots, bool:immunity)
294{
295 decl String:target_name[64];
296 decl target_list[1];
297 decl target_count;
298 decl bool:tn_is_ml;
299 new flags = 16;
300 if (nobots)
301 {
302 flags |= 32;
303 }
304 if (!immunity)
305 {
306 flags |= 8;
307 }
308 if (0 < (target_count = ProcessTargetString(target, client, target_list, 1, flags, target_name, 64, tn_is_ml)))
309 {
310 return target_list[0];
311 }
312 ReplyToTargetError(client, target_count);
313 return -1;
314}
315
316GetPlayerID(client)
317{
318 return GetClientID(client);
319}
320
321RegConsoleCmdEx(String:sCommand[], ConCmd:callback, String:sDescription[])
322{
323 RegConsoleCmd(sCommand, callback, sDescription, 0);
324 RegisterCommand(sCommand, sDescription);
325 return 0;
326}
327
328PrintColorText(client, String:msg[])
329{
330 if (IsClientInGame(client))
331 {
332 new String:buffer[300];
333 VFormat(buffer, 300, msg, 3);
334 new Handle:hMessage = StartMessageOne("SayText2", client, 0);
335 if (hMessage)
336 {
337 new var1;
338 if (GetFeatureStatus(FeatureType:0, "GetUserMessageType") && GetUserMessageType() == 1)
339 {
340 PbSetInt(hMessage, "ent_idx", client, -1);
341 PbSetBool(hMessage, "chat", true, -1);
342 PbSetString(hMessage, "msg_name", buffer, -1);
343 PbAddString(hMessage, "params", "");
344 PbAddString(hMessage, "params", "");
345 PbAddString(hMessage, "params", "");
346 PbAddString(hMessage, "params", "");
347 }
348 else
349 {
350 BfWriteByte(hMessage, client);
351 BfWriteByte(hMessage, 1);
352 BfWriteString(hMessage, buffer);
353 }
354 EndMessage();
355 }
356 }
357 return 0;
358}
359
360FormatPlayerTime(Float:Time, String:result[], maxlength, bool:showDash, precision)
361{
362 new var1;
363 if (Time <= 0.0 && showDash == true)
364 {
365 Format(result, maxlength, "-");
366 return 0;
367 }
368 new hours = RoundToFloor(Time / 3600);
369 Time -= hours * 3600;
370 new minutes = RoundToFloor(Time / 60);
371 Time -= minutes * 60;
372 new Float:seconds = Time;
373 decl String:sPrecision[16];
374 if (precision)
375 {
376 if (precision == 1)
377 {
378 new var4;
379 if (hours > 0 || minutes > 0)
380 {
381 var5[0] = 1580;
382 }
383 else
384 {
385 var5[0] = 1588;
386 }
387 Format(sPrecision, 16, var5, seconds);
388 }
389 if (precision == 2)
390 {
391 new var6;
392 if (hours > 0 || minutes > 0)
393 {
394 var7[0] = 1596;
395 }
396 else
397 {
398 var7[0] = 1604;
399 }
400 Format(sPrecision, 16, var7, seconds);
401 }
402 }
403 else
404 {
405 new var2;
406 if (hours > 0 || minutes > 0)
407 {
408 var3[0] = 1564;
409 }
410 else
411 {
412 var3[0] = 1572;
413 }
414 Format(sPrecision, 16, var3, seconds);
415 }
416 if (0 < hours)
417 {
418 Format(result, maxlength, "%d:%02d:%s", hours, minutes, sPrecision);
419 }
420 else
421 {
422 if (0 < minutes)
423 {
424 Format(result, maxlength, "%d:%s", minutes, sPrecision);
425 }
426 Format(result, maxlength, "%s", sPrecision);
427 }
428 return 0;
429}
430
431Team_GetAnyClient(index)
432{
433 static client_cache[32] =
434 {
435 -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
436 };
437 new client;
438 if (0 < index)
439 {
440 client = localIPRanges[index];
441 new var1;
442 if (client > 0 && client <= MaxClients)
443 {
444 new var2;
445 if (IsClientInGame(client) && index == GetClientTeam(client))
446 {
447 return client;
448 }
449 }
450 client = -1;
451 }
452 client = 1;
453 while (client <= MaxClients)
454 {
455 if (IsClientInGame(client))
456 {
457 if (!(index != GetClientTeam(client)))
458 {
459 localIPRanges[index] = client;
460 return client;
461 }
462 }
463 client++;
464 }
465 return -1;
466}
467
468Color_ChatInitialize()
469{
470 static initialized;
471 if (initialized)
472 {
473 return 0;
474 }
475 initialized = 1;
476 decl String:gameFolderName[32];
477 GetGameFolderName(gameFolderName, 32);
478 chatColorInfo[11][2] = 0;
479 new var1;
480 if (strncmp(gameFolderName, "left4dead", 9, false) && !StrEqual(gameFolderName, "cstrike", false) && !StrEqual(gameFolderName, "tf", false))
481 {
482 chatColorInfo[7][2] = 0;
483 chatColorInfo[8][2] = 0;
484 }
485 if (StrEqual(gameFolderName, "tf", false))
486 {
487 chatColorInfo[11][2] = 1;
488 chatColorInfo[8] = 1;
489 chatColorInfo[8][3] = -3;
490 }
491 else
492 {
493 if (strncmp(gameFolderName, "left4dead", 9, false))
494 {
495 if (StrEqual(gameFolderName, "hl2mp", false))
496 {
497 chatColorInfo[2][3] = 3;
498 chatColorInfo[3][3] = 3;
499 chatColorInfo[4][3] = 2;
500 chatColorInfo[5][3] = 2;
501 chatColorInfo[11][2] = 1;
502 checkTeamPlay = true;
503 }
504 if (StrEqual(gameFolderName, "dod", false))
505 {
506 chatColorInfo[8] = 1;
507 chatColorInfo[8][3] = -3;
508 chatColorInfo[11][2] = 1;
509 chatColorInfo[1][2] = 0;
510 }
511 }
512 chatColorInfo[2][3] = 3;
513 chatColorInfo[3][3] = 3;
514 chatColorInfo[4][3] = 2;
515 chatColorInfo[5][3] = 2;
516 chatColorInfo[1] = 4;
517 chatColorInfo[9] = 5;
518 }
519 if (GetUserMessageId("SayText2") == -1)
520 {
521 isSayText2_supported = false;
522 }
523 decl String:path_gamedata[256];
524 BuildPath(PathType:0, path_gamedata, 256, "gamedata/%s.txt", "smlib_colors.games");
525 if (FileExists(path_gamedata, false))
526 {
527 new Handle:gamedata;
528 if ((gamedata = LoadGameConfigFile("smlib_colors.games")))
529 {
530 decl String:keyName[32];
531 decl String:buffer[8];
532 new i;
533 while (i < 12)
534 {
535 Format(keyName, 32, "%s_code", chatColorNames[i]);
536 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
537 {
538 chatColorInfo[i][0] = StringToInt(buffer, 10);
539 }
540 Format(keyName, 32, "%s_alternative", chatColorNames[i]);
541 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
542 {
543 chatColorInfo[i][1] = buffer[0];
544 }
545 Format(keyName, 32, "%s_supported", chatColorNames[i]);
546 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
547 {
548 chatColorInfo[i][2] = StrEqual(buffer, "true", true);
549 }
550 Format(keyName, 32, "%s_subjecttype", chatColorNames[i]);
551 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
552 {
553 chatColorInfo[i][3] = StringToInt(buffer, 10);
554 }
555 i++;
556 }
557 if (GameConfGetKeyValue(gamedata, "checkteamplay", buffer, 6))
558 {
559 checkTeamPlay = StrEqual(buffer, "true", true);
560 }
561 CloseHandle(gamedata);
562 }
563 }
564 mp_teamplay = FindConVar("mp_teamplay");
565 return 0;
566}
567
568Color_GetChatColorInfo(&index, &subject)
569{
570 Color_ChatInitialize();
571 if (index == -1)
572 {
573 index = 0;
574 }
575 while (!chatColorInfo[index][2])
576 {
577 new alternative = chatColorInfo[index][1];
578 if (alternative == -1)
579 {
580 index = 0;
581 if (index == -1)
582 {
583 index = 0;
584 }
585 new newSubject = -2;
586 new ChatColorSubjectType:type = chatColorInfo[index][3];
587 switch (type)
588 {
589 case -3:
590 {
591 }
592 case -2:
593 {
594 newSubject = chatSubject;
595 }
596 case -1:
597 {
598 newSubject = -1;
599 }
600 case 0:
601 {
602 newSubject = 0;
603 }
604 default:
605 {
606 new var1;
607 if (!checkTeamPlay || GetConVarBool(mp_teamplay))
608 {
609 new var2;
610 if (subject > 0 && subject <= MaxClients)
611 {
612 if (type == GetClientTeam(subject))
613 {
614 newSubject = subject;
615 }
616 }
617 if (subject == -2)
618 {
619 new client = Team_GetAnyClient(type);
620 if (client != -1)
621 {
622 newSubject = client;
623 }
624 }
625 }
626 }
627 }
628 new var5;
629 if (type > ChatColorSubjectType:-3 && ((subject != -2 && newSubject != subject) || (newSubject == -2 || !isSayText2_supported)))
630 {
631 index = chatColorInfo[index][1];
632 newSubject = Color_GetChatColorInfo(index, subject);
633 }
634 if (subject == -2)
635 {
636 subject = newSubject;
637 }
638 return newSubject;
639 }
640 index = alternative;
641 }
642 if (index == -1)
643 {
644 index = 0;
645 }
646 new newSubject = -2;
647 new ChatColorSubjectType:type = chatColorInfo[index][3];
648 switch (type)
649 {
650 case -3:
651 {
652 }
653 case -2:
654 {
655 newSubject = chatSubject;
656 }
657 case -1:
658 {
659 newSubject = -1;
660 }
661 case 0:
662 {
663 newSubject = 0;
664 }
665 default:
666 {
667 new var1;
668 if (!checkTeamPlay || GetConVarBool(mp_teamplay))
669 {
670 new var2;
671 if (subject > 0 && subject <= MaxClients)
672 {
673 if (type == GetClientTeam(subject))
674 {
675 newSubject = subject;
676 }
677 }
678 if (subject == -2)
679 {
680 new client = Team_GetAnyClient(type);
681 if (client != -1)
682 {
683 newSubject = client;
684 }
685 }
686 }
687 }
688 }
689 new var5;
690 if (type > ChatColorSubjectType:-3 && ((subject != -2 && newSubject != subject) || (newSubject == -2 || !isSayText2_supported)))
691 {
692 index = chatColorInfo[index][1];
693 newSubject = Color_GetChatColorInfo(index, subject);
694 }
695 if (subject == -2)
696 {
697 subject = newSubject;
698 }
699 return newSubject;
700}
701
702public bool:_smlib_TraceEntityFilter(entity, contentsMask)
703{
704 return entity == 0;
705}
706
707Client_SetMaxSpeed(client, Float:value)
708{
709 Client_SetMaxSpeed(client, value);
710 return 0;
711}
712
713public OnPluginStart()
714{
715 decl String:sGame[64];
716 GetGameFolderName(sGame, 64);
717 if (StrEqual(sGame, "cstrike", true))
718 {
719 g_GameType = 0;
720 }
721 else
722 {
723 if (StrEqual(sGame, "csgo", true))
724 {
725 g_GameType = 1;
726 }
727 SetFailState("This timer does not support this game (%s)", sGame);
728 }
729 DB_Connect();
730 if (!g_GameType)
731 {
732 g_hChangeLogURL = CreateConVar("timer_changelog", "http://textuploader.com/14vc/raw", "The URL in to the timer changelog, in case the current URL breaks for some reason.", 0, false, 0.0, false, 0.0);
733 RegConsoleCmdEx("sm_changes", SM_Changes, "See the changes in the newer timer version.");
734 }
735 AutoExecConfig(true, "core", "timer");
736 HookEvent("player_changename", Event_PlayerChangeName, EventHookMode:0);
737 HookEvent("player_team", Event_PlayerTeam_Post, EventHookMode:1);
738 RegConsoleCmdEx("sm_mostplayed", SM_TopMaps, "Displays the most played maps");
739 RegConsoleCmdEx("sm_lastplayed", SM_LastPlayed, "Shows the last played maps");
740 RegConsoleCmdEx("sm_playtime", SM_Playtime, "Shows the people who played the most.");
741 RegConsoleCmdEx("sm_thelp", SM_THelp, "Shows the timer commands.");
742 RegConsoleCmdEx("sm_commands", SM_THelp, "Shows the timer commands.");
743 RegConsoleCmdEx("sm_search", SM_Search, "Search the command list for the given string of text.");
744 LoadTranslations("common.phrases");
745 return 0;
746}
747
748public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
749{
750 CreateNative("GetClientID", Native_GetClientID);
751 CreateNative("IsSpamming", Native_IsSpamming);
752 CreateNative("SetIsSpamming", Native_SetIsSpamming);
753 CreateNative("RegisterCommand", Native_RegisterCommand);
754 CreateNative("GetMapIdFromMapName", Native_GetMapIdFromMapName);
755 CreateNative("GetMapNameFromMapId", Native_GetMapNameFromMapId);
756 CreateNative("GetNameFromPlayerID", Native_GetNameFromPlayerID);
757 CreateNative("GetSteamIDFromPlayerID", Native_GetSteamIDFromPlayerID);
758 g_fwdMapIDPostCheck = CreateGlobalForward("OnMapIDPostCheck", ExecType:2);
759 g_fwdPlayerIDLoaded = CreateGlobalForward("OnPlayerIDLoaded", ExecType:2, 2);
760 g_fwdMapListLoaded = CreateGlobalForward("OnDatabaseMapListLoaded", ExecType:2);
761 return APLRes:0;
762}
763
764public OnMapStart()
765{
766 GetCurrentMap(g_sMapName, 64);
767 g_fMapStart = GetEngineTime();
768 if (g_MapList)
769 {
770 CloseHandle(g_MapList);
771 }
772 g_MapList = ReadMapList(Handle:0, -1, "default", 2);
773 CreateCurrentMapID();
774 return 0;
775}
776
777public OnMapEnd()
778{
779 DB_SaveMapPlaytime();
780 DB_SetMapLastPlayed();
781 return 0;
782}
783
784public OnClientPutInServer(client)
785{
786 g_fJoinTime[client] = GetEngineTime();
787 return 0;
788}
789
790public OnClientDisconnect(client)
791{
792 new var1;
793 if (g_PlayerID[client] && !IsFakeClient(client))
794 {
795 DB_SavePlaytime(client);
796 }
797 g_PlayerID[client] = 0;
798 return 0;
799}
800
801public OnClientAuthorized(client)
802{
803 new var1;
804 if (!IsFakeClient(client) && g_bPlayerListLoaded == true)
805 {
806 CreatePlayerID(client);
807 }
808 return 0;
809}
810
811public OnTimerChatChanged(MessageType, String:Message[])
812{
813 if (MessageType)
814 {
815 if (MessageType == 1)
816 {
817 Format(g_msg_varcol, 128, Message);
818 ReplaceMessage(g_msg_varcol, 128);
819 }
820 if (MessageType == 2)
821 {
822 Format(g_msg_textcol, 128, Message);
823 ReplaceMessage(g_msg_textcol, 128);
824 }
825 }
826 else
827 {
828 Format(g_msg_start, 128, Message);
829 ReplaceMessage(g_msg_start, 128);
830 }
831 return 0;
832}
833
834ReplaceMessage(String:message[], maxlength)
835{
836 if (g_GameType)
837 {
838 if (g_GameType == 1)
839 {
840 ReplaceString(message, maxlength, "^A", "\n", true);
841 ReplaceString(message, maxlength, "^1", "\x01", true);
842 ReplaceString(message, maxlength, "^2", "\x02", true);
843 ReplaceString(message, maxlength, "^3", "\x03", true);
844 ReplaceString(message, maxlength, "^4", "\x04", true);
845 ReplaceString(message, maxlength, "^5", "\x05", true);
846 ReplaceString(message, maxlength, "^6", "", true);
847 ReplaceString(message, maxlength, "^7", "\x07", true);
848 }
849 }
850 else
851 {
852 ReplaceString(message, maxlength, "^", "\x07", false);
853 }
854 return 0;
855}
856
857public Action:Event_PlayerTeam_Post(Handle:event, String:name[], bool:dontBroadcast)
858{
859 new client = GetClientOfUserId(GetEventInt(event, "userid"));
860 if (0 < client <= MaxClients)
861 {
862 if (IsClientInGame(client))
863 {
864 new oldteam = GetEventInt(event, "oldteam");
865 if (oldteam)
866 {
867 }
868 else
869 {
870 if (g_GameType)
871 {
872 if (g_GameType == 1)
873 {
874 PrintColorText(client, "%s%sType %s!thelp%s for a command list.", g_msg_start, g_msg_textcol, g_msg_varcol, g_msg_textcol);
875 }
876 }
877 PrintColorText(client, "%s%sType %s!thelp%s for a command list. %s!changes%s to see the changelog.", g_msg_start, g_msg_textcol, g_msg_varcol, g_msg_textcol, g_msg_varcol, g_msg_textcol);
878 }
879 }
880 }
881 return Action:0;
882}
883
884public Action:OnChatMessage(&author, Handle:recipients, String:name[], String:message[])
885{
886 if (IsChatTrigger())
887 {
888 return Action:4;
889 }
890 return Action:0;
891}
892
893public Action:SM_TopMaps(client, args)
894{
895 if (!IsSpamming(client))
896 {
897 SetIsSpamming(client, 1.0);
898 decl String:query[256];
899 Format(query, 256, "SELECT MapName, MapPlaytime FROM maps ORDER BY MapPlaytime DESC");
900 SQL_TQuery(g_DB, TopMaps_Callback, query, client, DBPriority:1);
901 }
902 return Action:3;
903}
904
905public TopMaps_Callback(Handle:owner, Handle:hndl, String:error[], any:client)
906{
907 if (hndl)
908 {
909 if (IsClientInGame(client))
910 {
911 new Handle:menu = CreateMenu(Menu_TopMaps, MenuAction:28);
912 SetMenuTitle(menu, "Most played maps\n---------------------------------------");
913 new rows = SQL_GetRowCount(hndl);
914 if (0 < rows)
915 {
916 decl String:mapname[64];
917 decl String:timeplayed[32];
918 decl String:display[128];
919 decl iTime;
920 new i;
921 new j;
922 while (i < rows)
923 {
924 SQL_FetchRow(hndl);
925 iTime = SQL_FetchInt(hndl, 1, 0);
926 if (iTime)
927 {
928 SQL_FetchString(hndl, 0, mapname, 64, 0);
929 if (FindStringInArray(g_MapList, mapname) != -1)
930 {
931 FormatPlayerTime(float(iTime), timeplayed, 32, false, 1);
932 SplitString(timeplayed, ".", timeplayed, 32);
933 j++;
934 Format(display, 128, "#%d: %s - %s", j, mapname, timeplayed);
935 AddMenuItem(menu, display, display, 0);
936 }
937 }
938 i++;
939 }
940 SetMenuExitButton(menu, true);
941 DisplayMenu(menu, client, 0);
942 }
943 }
944 }
945 else
946 {
947 LogError(error);
948 }
949 return 0;
950}
951
952public Menu_TopMaps(Handle:menu, MenuAction:action, param1, param2)
953{
954 if (action == MenuAction:4)
955 {
956 decl String:info[32];
957 GetMenuItem(menu, param2, info, 32, 0, "", 0);
958 FakeClientCommand(param1, "sm_nominate %s", info);
959 }
960 else
961 {
962 if (action == MenuAction:16)
963 {
964 CloseHandle(menu);
965 }
966 }
967 return 0;
968}
969
970public Action:SM_LastPlayed(client, argS)
971{
972 if (!IsSpamming(client))
973 {
974 SetIsSpamming(client, 1.0);
975 decl String:query[256];
976 Format(query, 256, "SELECT MapName, LastPlayed FROM maps ORDER BY LastPlayed DESC");
977 SQL_TQuery(g_DB, LastPlayed_Callback, query, client, DBPriority:1);
978 }
979 return Action:3;
980}
981
982public LastPlayed_Callback(Handle:owner, Handle:hndl, String:error[], any:client)
983{
984 if (hndl)
985 {
986 if (IsClientInGame(client))
987 {
988 new Handle:menu = CreateMenu(Menu_LastPlayed, MenuAction:28);
989 SetMenuTitle(menu, "Last played maps\n---------------------------------------");
990 decl String:sMapName[64];
991 decl String:sDate[32];
992 decl String:sTimeOfDay[32];
993 decl String:display[256];
994 decl iTime;
995 new rows = SQL_GetRowCount(hndl);
996 new i = 1;
997 while (i <= rows)
998 {
999 SQL_FetchRow(hndl);
1000 iTime = SQL_FetchInt(hndl, 1, 0);
1001 if (iTime)
1002 {
1003 SQL_FetchString(hndl, 0, sMapName, 64, 0);
1004 if (FindStringInArray(g_MapList, sMapName) != -1)
1005 {
1006 FormatTime(sDate, 32, "%x", iTime);
1007 FormatTime(sTimeOfDay, 32, "%X", iTime);
1008 Format(display, 256, "%s - %s - %s", sMapName, sDate, sTimeOfDay);
1009 AddMenuItem(menu, display, display, 0);
1010 }
1011 }
1012 i++;
1013 }
1014 SetMenuExitButton(menu, true);
1015 DisplayMenu(menu, client, 0);
1016 }
1017 }
1018 else
1019 {
1020 LogError(error);
1021 }
1022 return 0;
1023}
1024
1025public Menu_LastPlayed(Handle:menu, MenuAction:action, param1, param2)
1026{
1027 if (action == MenuAction:4)
1028 {
1029 decl String:info[32];
1030 GetMenuItem(menu, param2, info, 32, 0, "", 0);
1031 FakeClientCommand(param1, "sm_nominate %s", info);
1032 }
1033 else
1034 {
1035 if (action == MenuAction:16)
1036 {
1037 CloseHandle(menu);
1038 }
1039 }
1040 return 0;
1041}
1042
1043public Action:Event_PlayerChangeName(Handle:event, String:name[], bool:dontBroadcast)
1044{
1045 new client = GetClientOfUserId(GetEventInt(event, "userid"));
1046 new var1;
1047 if (!IsFakeClient(client) && g_PlayerID[client])
1048 {
1049 decl String:sNewName[32];
1050 GetEventString(event, "newname", sNewName, 32);
1051 UpdateName(client, sNewName);
1052 }
1053 return Action:0;
1054}
1055
1056public Action:SM_Changes(client, args)
1057{
1058 if (g_GameType)
1059 {
1060 return Action:0;
1061 }
1062 decl String:sChangeLog[256];
1063 GetConVarString(g_hChangeLogURL, sChangeLog, 256);
1064 ShowMOTDPanel(client, "Timer changelog", sChangeLog, 2);
1065 return Action:3;
1066}
1067
1068DB_Connect()
1069{
1070 if (g_DB)
1071 {
1072 CloseHandle(g_DB);
1073 }
1074 new String:error[256];
1075 g_DB = SQL_Connect("timer", true, error, 255);
1076 if (g_DB)
1077 {
1078 decl String:query[512];
1079 Format(query, 512, "CREATE TABLE IF NOT EXISTS maps(MapID INTEGER NOT NULL AUTO_INCREMENT, MapName TEXT, MapPlaytime INTEGER NOT NULL, LastPlayed INTEGER NOT NULL, PRIMARY KEY (MapID))");
1080 SQL_TQuery(g_DB, DB_Connect_Callback, query, any:0, DBPriority:1);
1081 Format(query, 512, "CREATE TABLE IF NOT EXISTS zones(RowID INTEGER NOT NULL AUTO_INCREMENT, MapID INTEGER, Type INTEGER, point00 REAL, point01 REAL, point02 REAL, point10 REAL, point11 REAL, point12 REAL, flags INTEGER, PRIMARY KEY (RowID))");
1082 SQL_TQuery(g_DB, DB_Connect_Callback, query, any:0, DBPriority:1);
1083 Format(query, 512, "CREATE TABLE IF NOT EXISTS players(PlayerID INTEGER NOT NULL AUTO_INCREMENT, SteamID TEXT, User Text, Playtime INTEGER NOT NULL, ccname TEXT, ccmsgcol TEXT, ccuse INTEGER, PRIMARY KEY (PlayerID))");
1084 SQL_TQuery(g_DB, DB_Connect_Callback, query, any:0, DBPriority:1);
1085 Format(query, 512, "CREATE TABLE IF NOT EXISTS times(rownum INTEGER NOT NULL AUTO_INCREMENT, MapID INTEGER, Type INTEGER, Style INTEGER, PlayerID INTEGER, Time REAL, Jumps INTEGER, Strafes INTEGER, Points REAL, Timestamp INTEGER, Sync REAL, SyncTwo REAL, PRIMARY KEY (rownum))");
1086 SQL_TQuery(g_DB, DB_Connect_Callback, query, any:0, DBPriority:1);
1087 LoadPlayers();
1088 LoadDatabaseMapList();
1089 }
1090 else
1091 {
1092 LogError(error);
1093 CloseHandle(g_DB);
1094 }
1095 return 0;
1096}
1097
1098public DB_Connect_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1099{
1100 if (!hndl)
1101 {
1102 LogError(error);
1103 }
1104 return 0;
1105}
1106
1107LoadDatabaseMapList()
1108{
1109 decl String:query[256];
1110 FormatEx(query, 256, "SELECT MapID, MapName FROM maps");
1111 SQL_TQuery(g_DB, LoadDatabaseMapList_Callback, query, any:0, DBPriority:1);
1112 return 0;
1113}
1114
1115public LoadDatabaseMapList_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1116{
1117 if (hndl)
1118 {
1119 if (!g_bDbMapsLoaded)
1120 {
1121 g_hDbMapNameList = CreateArray(ByteCountToCells(64), 0);
1122 g_hDbMapIdList = CreateArray(1, 0);
1123 g_bDbMapsLoaded = true;
1124 }
1125 decl String:sMapName[64];
1126 while (SQL_FetchRow(hndl))
1127 {
1128 SQL_FetchString(hndl, 1, sMapName, 64, 0);
1129 PushArrayString(g_hDbMapNameList, sMapName);
1130 PushArrayCell(g_hDbMapIdList, SQL_FetchInt(hndl, 0, 0));
1131 }
1132 Call_StartForward(g_fwdMapListLoaded);
1133 Call_Finish(0);
1134 }
1135 else
1136 {
1137 LogError(error);
1138 }
1139 return 0;
1140}
1141
1142LoadPlayers()
1143{
1144 g_hPlayerID = CreateArray(ByteCountToCells(32), 0);
1145 g_hUser = CreateArray(ByteCountToCells(32), 0);
1146 decl String:query[128];
1147 FormatEx(query, 128, "SELECT SteamID, PlayerID, User FROM players");
1148 SQL_TQuery(g_DB, LoadPlayers_Callback, query, any:0, DBPriority:1);
1149 return 0;
1150}
1151
1152public LoadPlayers_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1153{
1154 if (hndl)
1155 {
1156 decl String:sName[32];
1157 decl String:sAuth[32];
1158 new RowCount = SQL_GetRowCount(hndl);
1159 new PlayerID;
1160 new iSize;
1161 new Row;
1162 while (Row < RowCount)
1163 {
1164 SQL_FetchRow(hndl);
1165 SQL_FetchString(hndl, 0, sAuth, 32, 0);
1166 PlayerID = SQL_FetchInt(hndl, 1, 0);
1167 SQL_FetchString(hndl, 2, sName, 32, 0);
1168 iSize = GetArraySize(g_hPlayerID);
1169 if (PlayerID >= iSize)
1170 {
1171 ResizeArray(g_hPlayerID, PlayerID + 1);
1172 ResizeArray(g_hUser, PlayerID + 1);
1173 }
1174 SetArrayString(g_hPlayerID, PlayerID, sAuth);
1175 SetArrayString(g_hUser, PlayerID, sName);
1176 Row++;
1177 }
1178 g_bPlayerListLoaded = true;
1179 new client = 1;
1180 while (client <= MaxClients)
1181 {
1182 new var1;
1183 if (IsClientConnected(client) && !IsFakeClient(client))
1184 {
1185 if (IsClientAuthorized(client))
1186 {
1187 CreatePlayerID(client);
1188 }
1189 }
1190 client++;
1191 }
1192 }
1193 else
1194 {
1195 LogError(error);
1196 }
1197 return 0;
1198}
1199
1200CreateCurrentMapID()
1201{
1202 new Handle:pack = CreateDataPack();
1203 WritePackString(pack, g_sMapName);
1204 decl String:query[512];
1205 FormatEx(query, 512, "INSERT INTO maps (MapName) SELECT * FROM (SELECT '%s') AS tmp WHERE NOT EXISTS (SELECT MapName FROM maps WHERE MapName = '%s') LIMIT 1", g_sMapName, g_sMapName);
1206 SQL_TQuery(g_DB, DB_CreateCurrentMapID_Callback, query, pack, DBPriority:1);
1207 return 0;
1208}
1209
1210public DB_CreateCurrentMapID_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1211{
1212 if (hndl)
1213 {
1214 if (0 < SQL_GetAffectedRows(hndl))
1215 {
1216 ResetPack(data, false);
1217 decl String:sMapName[64];
1218 ReadPackString(data, sMapName, 64);
1219 new MapID = SQL_GetInsertId(hndl);
1220 LogMessage("MapID for %s created (%d)", sMapName, MapID);
1221 if (!g_bDbMapsLoaded)
1222 {
1223 g_hDbMapNameList = CreateArray(ByteCountToCells(64), 0);
1224 g_hDbMapIdList = CreateArray(1, 0);
1225 g_bDbMapsLoaded = true;
1226 }
1227 PushArrayString(g_hDbMapNameList, sMapName);
1228 PushArrayCell(g_hDbMapIdList, MapID);
1229 }
1230 Call_StartForward(g_fwdMapIDPostCheck);
1231 Call_Finish(0);
1232 }
1233 else
1234 {
1235 LogError(error);
1236 }
1237 CloseHandle(data);
1238 return 0;
1239}
1240
1241CreatePlayerID(client)
1242{
1243 decl String:sName[32];
1244 GetClientName(client, sName, 32);
1245 decl String:sAuth[32];
1246 GetClientAuthString(client, sAuth, 32, true);
1247 new idx = FindStringInArray(g_hPlayerID, sAuth);
1248 if (idx != -1)
1249 {
1250 g_PlayerID[client] = idx;
1251 decl String:sOldName[32];
1252 GetArrayString(g_hUser, idx, sOldName, 32);
1253 if (!StrEqual(sName, sOldName, true))
1254 {
1255 UpdateName(client, sName);
1256 }
1257 Call_StartForward(g_fwdPlayerIDLoaded);
1258 Call_PushCell(client);
1259 Call_Finish(0);
1260 }
1261 else
1262 {
1263 decl String:sEscapeName[68];
1264 SQL_LockDatabase(g_DB);
1265 SQL_EscapeString(g_DB, sName, sEscapeName, 65, 0);
1266 SQL_UnlockDatabase(g_DB);
1267 new Handle:pack = CreateDataPack();
1268 WritePackCell(pack, GetClientUserId(client));
1269 WritePackString(pack, sAuth);
1270 WritePackString(pack, sName);
1271 decl String:query[128];
1272 FormatEx(query, 128, "INSERT INTO players (SteamID, User) VALUES ('%s', '%s')", sAuth, sEscapeName);
1273 SQL_TQuery(g_DB, CreatePlayerID_Callback, query, pack, DBPriority:1);
1274 }
1275 return 0;
1276}
1277
1278public CreatePlayerID_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1279{
1280 if (hndl)
1281 {
1282 ResetPack(data, false);
1283 new client = GetClientOfUserId(ReadPackCell(data));
1284 decl String:sAuth[32];
1285 ReadPackString(data, sAuth, 32);
1286 decl String:sName[32];
1287 ReadPackString(data, sName, 32);
1288 new PlayerID = SQL_GetInsertId(hndl);
1289 new iSize = GetArraySize(g_hPlayerID);
1290 if (PlayerID >= iSize)
1291 {
1292 ResizeArray(g_hPlayerID, PlayerID + 1);
1293 ResizeArray(g_hUser, PlayerID + 1);
1294 }
1295 SetArrayString(g_hPlayerID, PlayerID, sAuth);
1296 SetArrayString(g_hUser, PlayerID, sName);
1297 if (client)
1298 {
1299 g_PlayerID[client] = PlayerID;
1300 Call_StartForward(g_fwdPlayerIDLoaded);
1301 Call_PushCell(client);
1302 Call_Finish(0);
1303 }
1304 }
1305 else
1306 {
1307 LogError(error);
1308 }
1309 return 0;
1310}
1311
1312UpdateName(client, String:sName[])
1313{
1314 SetArrayString(g_hUser, g_PlayerID[client], sName);
1315 decl String:sEscapeName[68];
1316 SQL_LockDatabase(g_DB);
1317 SQL_EscapeString(g_DB, sName, sEscapeName, 65, 0);
1318 SQL_UnlockDatabase(g_DB);
1319 decl String:query[128];
1320 FormatEx(query, 128, "UPDATE players SET User='%s' WHERE PlayerID=%d", sEscapeName, g_PlayerID[client]);
1321 SQL_TQuery(g_DB, UpdateName_Callback, query, any:0, DBPriority:1);
1322 return 0;
1323}
1324
1325public UpdateName_Callback(Handle:owner, Handle:hndl, String:error[], any:userid)
1326{
1327 if (!hndl)
1328 {
1329 LogError(error);
1330 }
1331 return 0;
1332}
1333
1334public Native_GetClientID(Handle:plugin, numParams)
1335{
1336 return g_PlayerID[GetNativeCell(1)];
1337}
1338
1339DB_SavePlaytime(client)
1340{
1341 if (IsClientInGame(client))
1342 {
1343 new PlayerID = GetPlayerID(client);
1344 if (PlayerID)
1345 {
1346 decl String:query[128];
1347 Format(query, 128, "UPDATE players SET Playtime=(SELECT Playtime FROM (SELECT * FROM players) AS x WHERE PlayerID=%d)+%d WHERE PlayerID=%d", PlayerID, RoundToFloor(GetEngineTime() - g_fJoinTime[client]), PlayerID);
1348 SQL_TQuery(g_DB, DB_SavePlaytime_Callback, query, any:0, DBPriority:1);
1349 }
1350 }
1351 return 0;
1352}
1353
1354public DB_SavePlaytime_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1355{
1356 if (!hndl)
1357 {
1358 LogError(error);
1359 }
1360 return 0;
1361}
1362
1363DB_SaveMapPlaytime()
1364{
1365 decl String:query[256];
1366 Format(query, 256, "UPDATE maps SET MapPlaytime=(SELECT MapPlaytime FROM (SELECT * FROM maps) AS x WHERE MapName='%s' LIMIT 0, 1)+%d WHERE MapName='%s'", g_sMapName, RoundToFloor(GetEngineTime() - g_fMapStart), g_sMapName);
1367 SQL_TQuery(g_DB, DB_SaveMapPlaytime_Callback, query, any:0, DBPriority:1);
1368 return 0;
1369}
1370
1371public DB_SaveMapPlaytime_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1372{
1373 if (!hndl)
1374 {
1375 LogError(error);
1376 }
1377 return 0;
1378}
1379
1380DB_SetMapLastPlayed()
1381{
1382 decl String:query[128];
1383 Format(query, 128, "UPDATE maps SET LastPlayed=%d WHERE MapName='%s'", GetTime({0,0}), g_sMapName);
1384 SQL_TQuery(g_DB, DB_SetMapLastPlayed_Callback, query, any:0, DBPriority:1);
1385 return 0;
1386}
1387
1388public DB_SetMapLastPlayed_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1389{
1390 if (!hndl)
1391 {
1392 LogError(error);
1393 }
1394 return 0;
1395}
1396
1397public Action:SM_Playtime(client, args)
1398{
1399 if (!IsSpamming(client))
1400 {
1401 SetIsSpamming(client, 1.0);
1402 if (args)
1403 {
1404 decl String:sArg[32];
1405 GetCmdArgString(sArg, 32);
1406 new target = FindTarget(client, sArg, true, false);
1407 if (target != -1)
1408 {
1409 if (g_PlayerID[target])
1410 {
1411 DB_ShowPlaytime(client, g_PlayerID[target]);
1412 }
1413 }
1414 }
1415 if (g_PlayerID[client])
1416 {
1417 DB_ShowPlaytime(client, g_PlayerID[client]);
1418 }
1419 }
1420 return Action:3;
1421}
1422
1423DB_ShowPlaytime(client, PlayerID)
1424{
1425 new Handle:pack = CreateDataPack();
1426 WritePackCell(pack, GetClientUserId(client));
1427 WritePackCell(pack, PlayerID);
1428 decl String:query[512];
1429 Format(query, 512, "SELECT (SELECT Playtime FROM players WHERE PlayerID=%d) AS TargetPlaytime, User, Playtime, PlayerID FROM players ORDER BY Playtime DESC LIMIT 0, 100", PlayerID);
1430 SQL_TQuery(g_DB, DB_ShowPlaytime_Callback, query, pack, DBPriority:1);
1431 return 0;
1432}
1433
1434public DB_ShowPlaytime_Callback(Handle:owner, Handle:hndl, String:error[], any:data)
1435{
1436 if (hndl)
1437 {
1438 ResetPack(data, false);
1439 new client = GetClientOfUserId(ReadPackCell(data));
1440 if (client)
1441 {
1442 new rows = SQL_GetRowCount(hndl);
1443 if (rows)
1444 {
1445 new TargetPlayerID = ReadPackCell(data);
1446 new Handle:menu = CreateMenu(Menu_ShowPlaytime, MenuAction:28);
1447 decl String:sName[32];
1448 decl String:sTime[32];
1449 decl String:sDisplay[64];
1450 decl String:sInfo[16];
1451 decl PlayTime;
1452 decl PlayerID;
1453 decl TargetPlaytime;
1454 new i = 1;
1455 while (i <= rows)
1456 {
1457 SQL_FetchRow(hndl);
1458 TargetPlaytime = SQL_FetchInt(hndl, 0, 0);
1459 SQL_FetchString(hndl, 1, sName, 32, 0);
1460 PlayTime = SQL_FetchInt(hndl, 2, 0);
1461 PlayerID = SQL_FetchInt(hndl, 3, 0);
1462 IntToString(PlayerID, sInfo, 16);
1463 FormatPlayerTime(float(PlayTime), sTime, 32, false, 1);
1464 SplitString(sTime, ".", sTime, 32);
1465 FormatEx(sDisplay, 64, "#%d: %s: %s", i, sName, sTime);
1466 new var1;
1467 if (i % 7 && rows != i)
1468 {
1469 Format(sDisplay, 64, "%s\n--------------------------------------", sDisplay);
1470 }
1471 AddMenuItem(menu, sInfo, sDisplay, 0);
1472 i++;
1473 }
1474 GetNameFromPlayerID(TargetPlayerID, sName, 32);
1475 new Float:ConnectionTime = 0.0;
1476 new target;
1477 if ((target = GetClientFromPlayerID(TargetPlayerID)))
1478 {
1479 ConnectionTime = GetEngineTime() - g_fJoinTime[target];
1480 }
1481 FormatPlayerTime(ConnectionTime + float(TargetPlaytime), sTime, 32, false, 1);
1482 SplitString(sTime, ".", sTime, 32);
1483 SetMenuTitle(menu, "Playtimes\n \n%s: %s\n--------------------------------------", sName, sTime);
1484 SetMenuExitButton(menu, true);
1485 DisplayMenu(menu, client, 0);
1486 }
1487 }
1488 }
1489 else
1490 {
1491 LogError(error);
1492 }
1493 CloseHandle(data);
1494 return 0;
1495}
1496
1497public Menu_ShowPlaytime(Handle:menu, MenuAction:action, param1, param2)
1498{
1499 if (action == MenuAction:16)
1500 {
1501 CloseHandle(menu);
1502 }
1503 return 0;
1504}
1505
1506public Action:SM_THelp(client, args)
1507{
1508 new iSize = GetArraySize(g_hCommandList);
1509 decl String:sResult[256];
1510 if (0 < client <= MaxClients)
1511 {
1512 if (GetCmdReplySource() == 1)
1513 {
1514 ReplyToCommand(client, "[SM] Look in your console for timer command list.");
1515 }
1516 decl String:sCommand[32];
1517 GetCmdArg(0, sCommand, 32);
1518 if (args)
1519 {
1520 decl String:arg[252];
1521 GetCmdArgString(arg, 250);
1522 new iStart = StringToInt(arg, 10);
1523 if (iSize + -10 > iStart)
1524 {
1525 ReplyToCommand(client, "[SM] %s %d for the next page.", sCommand, iStart + 10);
1526 }
1527 new i = iStart;
1528 while (i < iStart + 10 && i < iSize)
1529 {
1530 GetArrayString(g_hCommandList, i, sResult, 256);
1531 PrintToConsole(client, sResult);
1532 i++;
1533 }
1534 }
1535 else
1536 {
1537 ReplyToCommand(client, "[SM] %s 10 for the next page.", sCommand);
1538 new i;
1539 while (i < 10 && i < iSize)
1540 {
1541 GetArrayString(g_hCommandList, i, sResult, 256);
1542 PrintToConsole(client, sResult);
1543 i++;
1544 }
1545 }
1546 }
1547 else
1548 {
1549 if (!client)
1550 {
1551 new i;
1552 while (i < iSize)
1553 {
1554 GetArrayString(g_hCommandList, i, sResult, 256);
1555 PrintToServer(sResult);
1556 i++;
1557 }
1558 }
1559 }
1560 return Action:3;
1561}
1562
1563public Action:SM_Search(client, args)
1564{
1565 if (0 < args)
1566 {
1567 decl String:sArgString[256];
1568 decl String:sResult[256];
1569 GetCmdArgString(sArgString, 255);
1570 new iSize = GetArraySize(g_hCommandList);
1571 new i;
1572 while (i < iSize)
1573 {
1574 GetArrayString(g_hCommandList, i, sResult, 256);
1575 if (StrContains(sResult, sArgString, false) != -1)
1576 {
1577 PrintToConsole(client, sResult);
1578 }
1579 i++;
1580 }
1581 }
1582 else
1583 {
1584 PrintColorText(client, "%s%ssm_search must have a string to search with after it.", g_msg_start, g_msg_textcol);
1585 }
1586 return Action:3;
1587}
1588
1589GetClientFromPlayerID(PlayerID)
1590{
1591 new client = 1;
1592 while (client <= MaxClients)
1593 {
1594 new var1;
1595 if (IsClientInGame(client) && !IsFakeClient(client) && PlayerID == g_PlayerID[client])
1596 {
1597 return client;
1598 }
1599 client++;
1600 }
1601 return 0;
1602}
1603
1604public Native_IsSpamming(Handle:plugin, numParams)
1605{
1606 return GetEngineTime() < g_fSpamTime[GetNativeCell(1)];
1607}
1608
1609public Native_SetIsSpamming(Handle:plugin, numParams)
1610{
1611 g_fSpamTime[GetNativeCell(1)] = GetNativeCell(2) + GetEngineTime();
1612 return 0;
1613}
1614
1615public Native_RegisterCommand(Handle:plugin, numParams)
1616{
1617 if (!g_bCommandListLoaded)
1618 {
1619 g_hCommandList = CreateArray(ByteCountToCells(256), 0);
1620 g_bCommandListLoaded = true;
1621 }
1622 decl String:sListing[256];
1623 decl String:sCommand[32];
1624 decl String:sDesc[224];
1625 GetNativeString(1, sCommand, 32, 0);
1626 GetNativeString(2, sDesc, 224, 0);
1627 FormatEx(sListing, 256, "%s - %s", sCommand, sDesc);
1628 decl String:sIndex[256];
1629 new idx;
1630 new idxlen;
1631 new listlen = strlen(sListing);
1632 new iSize = GetArraySize(g_hCommandList);
1633 new bool:IdxFound;
1634 while (idx < iSize)
1635 {
1636 GetArrayString(g_hCommandList, idx, sIndex, 256);
1637 idxlen = strlen(sIndex);
1638 new cmpidx;
1639 while (cmpidx < listlen && cmpidx < idxlen)
1640 {
1641 if (sIndex[cmpidx] > sListing[cmpidx])
1642 {
1643 IdxFound = true;
1644 if (IdxFound == true)
1645 {
1646 if (idx >= iSize)
1647 {
1648 ResizeArray(g_hCommandList, idx + 1);
1649 }
1650 else
1651 {
1652 ShiftArrayUp(g_hCommandList, idx);
1653 }
1654 SetArrayString(g_hCommandList, idx, sListing);
1655 return 0;
1656 }
1657 idx++;
1658 }
1659 if (sIndex[cmpidx] < sListing[cmpidx])
1660 {
1661 if (IdxFound == true)
1662 {
1663 if (idx >= iSize)
1664 {
1665 ResizeArray(g_hCommandList, idx + 1);
1666 }
1667 else
1668 {
1669 ShiftArrayUp(g_hCommandList, idx);
1670 }
1671 SetArrayString(g_hCommandList, idx, sListing);
1672 return 0;
1673 }
1674 idx++;
1675 }
1676 cmpidx++;
1677 }
1678 if (IdxFound == true)
1679 {
1680 if (idx >= iSize)
1681 {
1682 ResizeArray(g_hCommandList, idx + 1);
1683 }
1684 else
1685 {
1686 ShiftArrayUp(g_hCommandList, idx);
1687 }
1688 SetArrayString(g_hCommandList, idx, sListing);
1689 return 0;
1690 }
1691 idx++;
1692 }
1693 if (idx >= iSize)
1694 {
1695 ResizeArray(g_hCommandList, idx + 1);
1696 }
1697 else
1698 {
1699 ShiftArrayUp(g_hCommandList, idx);
1700 }
1701 SetArrayString(g_hCommandList, idx, sListing);
1702 return 0;
1703}
1704
1705public Native_GetMapNameFromMapId(Handle:plugin, numParams)
1706{
1707 new Index = FindValueInArray(g_hDbMapIdList, GetNativeCell(1));
1708 if (Index != -1)
1709 {
1710 decl String:sMapName[64];
1711 GetArrayString(g_hDbMapNameList, Index, sMapName, 64);
1712 SetNativeString(2, sMapName, GetNativeCell(3), true, 0);
1713 return 1;
1714 }
1715 return 0;
1716}
1717
1718public Native_GetNameFromPlayerID(Handle:plugin, numParams)
1719{
1720 decl String:sName[32];
1721 GetArrayString(g_hUser, GetNativeCell(1), sName, 32);
1722 SetNativeString(2, sName, GetNativeCell(3), true, 0);
1723 return 0;
1724}
1725
1726public Native_GetSteamIDFromPlayerID(Handle:plugin, numParams)
1727{
1728 decl String:sAuth[32];
1729 GetArrayString(g_hPlayerID, GetNativeCell(1), sAuth, 32);
1730 SetNativeString(2, sAuth, GetNativeCell(3), true, 0);
1731 return 0;
1732}
1733
1734public Native_GetMapIdFromMapName(Handle:plugin, numParams)
1735{
1736 decl String:sMapName[64];
1737 GetNativeString(1, sMapName, 64, 0);
1738 new Index = FindStringInArray(g_hDbMapNameList, sMapName);
1739 if (Index != -1)
1740 {
1741 return GetArrayCell(g_hDbMapIdList, Index, 0, false);
1742 }
1743 return 0;
1744}