Advertisement
Guest User

Untitled

a guest
Dec 2nd, 2019
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.88 KB | None | 0 0
  1. // **** Be aware that I use '\' as a control char instead of '^'
  2. #pragma ctrlchar '\'
  3.  
  4. // **** DO NOT EDIT THE QUERIES UNLESS YOU KNOW WHAT YOU'RE DOING!
  5. // **** YOU HAVE BEEN WARNED
  6.  
  7. #include <amxmodx>
  8. #include <amxmisc>
  9. #include <sqlx>
  10. #include <fakemeta>
  11.  
  12. // Do not touch unless you know.
  13. #define MAX_DATA_ARRAY_SIZE 5
  14.  
  15. #if AMXX_VERSION_NUM < 183
  16. #include <colorchat>
  17. #define print_team_default Blue
  18. #define print_team_red Red
  19. #define print_team_grey Grey
  20. #define print_team_blue Blue
  21.  
  22. #define MAX_NAME_LENGTH 32
  23. #define client_disconnected client_disconnect
  24. #endif
  25.  
  26. #define SQLITE 0
  27. #define MYSQL 1
  28.  
  29. /***** Stuff that you can Edit *****/
  30. /* Explanation of stuff inside:
  31. ADMIN_ACCESS_LETTER -> Access flag for the admin command that checks the time of a player
  32. USE_NAME -> Will make the plugin use the name of the player as the saving identifier. If a player changes his name, his time will reset.
  33. To disable: comment the line by adding // infront of #define
  34. making it //#define
  35. To Enable: Un comment the line by removing '//'
  36. SAVE_TYPE -> Decides which method should the plugin use to save data:
  37. Valid Values: 0 for SQLite (save locally in the server files), 1 for MySQL (must have an external server)
  38. PREPARE_TOP_MOTD -> If you're using an external MySQL server (or if you have a huge amount of players, you might actually want to use this
  39. This allows you to prepare the top motd as soon as the map starts instead of actually making it each time a player
  40. submits a command; however, it does not give up to date results.
  41. (TLDR: Good for servers with a huge load or amount of players,
  42. does not give up to date results though, and will disable /top#_time command.)
  43. Enable/Disable: Same method as USE_NAME
  44. PREFIX -> The prefix of the chat messages. Should be easy to edit. Does not need any more explanation.
  45. GET_TIME_INSTANT_QUERY ->
  46. TOP_DEFAULT_NUMBER -> Number of entries in Top MOTD when using /toptime commands and if using PREPARE_TOP_MOTD
  47. GET_TIME_INSTANT_QUERY -> This will force the plugin to not use threaded queries, only enable if you know what you're doing.
  48. I do not recomment using this on distant servers (for example, your game server is in one end
  49. while your sql server is at the other end of the world)
  50. DO_NOT_LOG -> Do not let the plugin to log queries.
  51. (Logging is useful for debuging, but if you don't want to, disable it by removing //)
  52. PS: Do not expect support from me if you have logging disabled.
  53. */
  54.  
  55. // Editables
  56. #define SAVE_TYPE 1
  57. #define ADMIN_ACCESS_LETTER "e"
  58. #define TOP_DEFAULT_NUMBER 15
  59.  
  60. // Enabled, Disabled
  61. //#define USE_NAME
  62. //#define PREPARE_TOP_MOTD
  63. //#define GET_TIME_INSTANT_QUERY
  64. //#define DO_NOT_LOG
  65.  
  66. new const PREFIX[] = "\x04[Played-Time]";
  67.  
  68. new const g_szTimeCheckChatCommands[][] = {
  69. "/mt",
  70. "mt",
  71. "/my_time",
  72. "my_time",
  73. "/mytime",
  74. "mytime"
  75. };
  76.  
  77. new const g_szTopTimeChatCommands[][] = {
  78. "/timetop",
  79. "/time15",
  80. "/toptime",
  81. "/time10"
  82. };
  83.  
  84. #if SAVE_TYPE == MYSQL
  85. new const SQL_CONNECT_DATA[][] = {
  86. "127.0.0.1",
  87. "root",
  88. "",
  89. "played_time"
  90. };
  91. #endif
  92.  
  93. new const LOG_FILE_PLAYED_TIME[] = "addons/amxmodx/logs/played_time_log.txt";
  94. /************************************/
  95. /***** End *****/
  96. /************************************/
  97. #define IDENTIFIER_MAX_LENGTH 35
  98. #define NOT_RETRIEVED -1
  99.  
  100. new Handle:g_hSqlHandle, g_szQuery[512];
  101. new g_iPlayedTime[33] = NOT_RETRIEVED;
  102.  
  103. #if defined PREPARE_TOP_MOTD
  104. new bool:g_bTopMotdNoData = false;
  105. #endif
  106.  
  107. new g_szTopMotd[1536];
  108.  
  109. new g_szOldName[33][MAX_NAME_LENGTH];
  110. new g_iQueryNumber;
  111. new g_iMaxPlayers;
  112. new g_hGetTimeForward, g_hSaveTimeForward;
  113.  
  114. public plugin_natives()
  115. {
  116. register_library("played_time");
  117.  
  118. register_native("pt_get_user_played_time", "native_get_user_played_time", 0);
  119. register_native("pt_set_user_played_time", "native_set_user_played_time", 0);
  120.  
  121. // Compatibility with other older plugins;
  122. register_native("get_user_playedtime", "native_get_user_played_time", 0);
  123. register_native("set_user_playedtime", "native_set_user_played_time", 0);
  124. register_native("get_user_played_time", "native_get_user_played_time", 0);
  125. register_native("set_user_played_time", "native_set_user_played_time", 0);
  126.  
  127. register_native("pt_get_save_type", "native_get_save_type", 0)
  128.  
  129. g_hGetTimeForward = CreateMultiForward("pt_client_get_time", ET_IGNORE, FP_CELL, FP_CELL);
  130. g_hSaveTimeForward = CreateMultiForward("pt_client_save_time", ET_IGNORE, FP_CELL, FP_CELL);
  131. }
  132.  
  133. public plugin_end()
  134. {
  135. SQL_FreeHandle(g_hSqlHandle);
  136. DestroyForward(g_hGetTimeForward);
  137. DestroyForward(g_hSaveTimeForward);
  138. }
  139.  
  140. public plugin_init()
  141. {
  142. // Why? Because it looks cool.
  143. register_plugin(.plugin_name = "Played Time: Extended", .author = "Khalid", .version = "1.0b");
  144.  
  145. new szMapName[32]; get_mapname(szMapName, charsmax(szMapName));
  146. log_to_file(LOG_FILE_PLAYED_TIME, "---- Map changed to: %s ----", szMapName);
  147.  
  148. new ADMIN_ACCESS = read_flags(ADMIN_ACCESS_LETTER);
  149.  
  150. // Filter chat to hook chat commands
  151. for(new i, szCommand[32]; i < sizeof g_szTimeCheckChatCommands; i++)
  152. {
  153. formatex(szCommand, charsmax(szCommand), "say %s", g_szTimeCheckChatCommands[i]);
  154. register_clcmd(szCommand, "ClCmdSay_CheckTime");
  155. formatex(szCommand, charsmax(szCommand), "say_team %s", g_szTimeCheckChatCommands[i]);
  156. register_clcmd(szCommand, "ClCmdSay_CheckTime");
  157. }
  158.  
  159. for(new i, szCommand[32]; i < sizeof g_szTopTimeChatCommands; i++)
  160. {
  161. formatex(szCommand, charsmax(szCommand), "say %s", g_szTopTimeChatCommands[i]);
  162. register_clcmd(szCommand, "ClCmdSay_TopTime");
  163. formatex(szCommand, charsmax(szCommand), "say_team %s", g_szTopTimeChatCommands[i]);
  164. register_clcmd(szCommand, "ClCmdSay_TopTime");
  165. }
  166.  
  167. register_clcmd("say", "ClCmdSay_TopNumberCommand");
  168. register_clcmd("say_team", "ClCmdSay_TopNumberCommand");
  169.  
  170. // Command to allow admins to check other players played time
  171. register_concmd("amx_playedtime", "AdminCmd_ShowPlayerTime", ADMIN_ACCESS," <name - #userid - steamid> - Show total and current time played by a specific player.");
  172. register_concmd("amx_show_played_time", "AdminCmd_ShowPlayerTime", ADMIN_ACCESS," <name - #userid - steamid> - Show total and current time played by a specific player.");
  173. register_concmd("amx_played_time", "AdminCmd_ShowPlayerTime", ADMIN_ACCESS," <name - #userid - steamid> - Show total and current time played by a specific player.");
  174.  
  175. register_forward(FM_ClientUserInfoChanged, "FMCallback_InfoChanged_Post", 1)
  176.  
  177. CreateTableInDB();
  178. g_iMaxPlayers = get_maxplayers();
  179. }
  180.  
  181. public AdminCmd_ShowPlayerTime(id, level, cid)
  182. {
  183. if(!cmd_access(id, level, cid, 1))
  184. return PLUGIN_HANDLED
  185.  
  186. new szName[32], iPlayer
  187. if(read_argc() == 1)
  188. {
  189. console_print(id, "Showing players times of all connected players")
  190. new iPlayers[32], iNum, iPlayer, szName[32]
  191. get_players(iPlayers, iNum, "h")
  192.  
  193. console_print(id, "%d. %-32s %-22s", "#", "Name", "Time Played");
  194. for(new i; i < iNum; i++)
  195. {
  196. iPlayer = iPlayers[i]
  197. get_user_name(iPlayer, szName, 31)
  198.  
  199. console_print(id, "%d. %-32s %-22d", i + 1, szName, (g_iPlayedTime[iPlayer] + get_user_time(iPlayer)) / 60)
  200. }
  201. }
  202.  
  203. else
  204. {
  205. new szArg[32]
  206. read_argv(1, szArg, charsmax(szArg))
  207.  
  208. iPlayer = cmd_target(id, szArg, CMDTARGET_OBEY_IMMUNITY)
  209.  
  210. if(iPlayer)
  211. {
  212. get_user_name(iPlayer, szName, charsmax(szName))
  213. console_print(id, "%s total played time is %d minute(s)", szName, ( g_iPlayedTime[iPlayer] + get_user_time(iPlayer) ) / 60);
  214. return PLUGIN_HANDLED;
  215. }
  216.  
  217. if(szArg[0] == '@')
  218. {
  219. new iPlayers[32], iNum
  220. if( equali(szArg, "@TERRORIST") || equali(szArg, "@T") || equal(szArg, "@TERR") )
  221. {
  222. console_print(id, "Showing players times for team Terrorist");
  223. get_players(iPlayers, iNum, "eh", "TERRORIST");
  224. }
  225.  
  226. else if( equali(szArg, "@COUNTERTERRORIST") || equali(szArg, "@CT") || equali(szArg, "@COUNTER") )
  227. {
  228. console_print(id, "Showing players times for team Counter-Terrorist");
  229. get_players(iPlayers, iNum, "eh", "CT");
  230. }
  231. else if( equali(szArg, "@SPECTATOR") || equali(szArg, "@SPEC") || equali(szArg, "@SPECTATOR") )
  232. {
  233. console_print(id, "Showing players times for team Spectators");
  234. get_players(iPlayers, iNum, "eh", "SPEC");
  235. }
  236.  
  237. else
  238. {
  239. console_print(id, "That's not a correct team");
  240. return PLUGIN_HANDLED
  241. }
  242.  
  243. for(new i; i < iNum; i++)
  244. {
  245. iPlayer = iPlayers[i]
  246. get_user_name(iPlayer, szName, 31)
  247. console_print(id, "%d. %s %22.22d", i + 1, szName, ( g_iPlayedTime[iPlayer] + get_user_time(iPlayer) ) / 60)
  248. }
  249. }
  250. }
  251.  
  252. return PLUGIN_HANDLED
  253. }
  254.  
  255. public ClCmdSay_CheckTime(id)
  256. {
  257. new iAdditionalTime = get_user_time(id);
  258.  
  259. client_print_color(id, print_team_default, "\x04-------------------------------#Played Time#-----------------------------------")
  260. if(g_iPlayedTime[id] != NOT_RETRIEVED)
  261. {
  262. client_print_color(id, print_team_grey, "%s \x03You have been playing on this server for \x03%d minute%s", PREFIX, iAdditionalTime / 60, iAdditionalTime / 60 == 1? "" : "s");
  263. client_print_color(id, print_team_grey, "%s \x03Your total played time on the server: \x03%d minute%s.", PREFIX, (iAdditionalTime + g_iPlayedTime[id]) / 60, ( (iAdditionalTime + g_iPlayedTime[id]) / 60 ) == 1 ? "" : "s");
  264. }
  265.  
  266. else
  267. {
  268. client_print_color(id, print_team_grey, "%s \x03Your total time is not retrieved yet.");
  269. }
  270.  
  271. client_print_color(id, print_team_default, "\x04-------------------------------------------------------------------------------")
  272.  
  273. return PLUGIN_CONTINUE;
  274. }
  275.  
  276. public ClCmdSay_TopTime(id)
  277. {
  278. #if defined PREPARE_TOP_MOTD
  279. if(g_bTopMotdNoData)
  280. {
  281. client_print_color(id, print_team_default, "%s \x03No data to do the top list yet.");
  282. return;
  283. }
  284.  
  285. show_motd(id, g_szTopMotd, "Time Top List");
  286. #else
  287. FormatTop(id, TOP_DEFAULT_NUMBER);
  288. #endif
  289. }
  290.  
  291. public ClCmdSay_TopNumberCommand(id)
  292. {
  293. #if defined PREPARE_TOP_MOTD
  294. ClCmdSay_TopTime(id)
  295. #else
  296. new szSaid[25]
  297. read_argv(1, szSaid, charsmax(szSaid))
  298.  
  299. if( containi(szSaid, "/top") != -1 && ( containi(szSaid, "_time") != -1 || containi(szSaid, "time") != -1) )
  300. {
  301. replace(szSaid, charsmax(szSaid), "/top", ""); replace(szSaid, charsmax(szSaid), "_time", "");
  302. replace(szSaid, charsmax(szSaid), "time", "");
  303.  
  304. if(!is_str_num(szSaid)) // If it has more other words than /top*_time
  305. {
  306. return PLUGIN_CONTINUE // stop plugin and continue to show the words
  307. }
  308.  
  309. new iNum = str_to_num(szSaid)
  310. FormatTop(id, iNum);
  311. }
  312. #endif
  313.  
  314. return PLUGIN_CONTINUE;
  315. }
  316.  
  317. stock FormatTop(id, iTopNumber)
  318. {
  319. new iData[MAX_DATA_ARRAY_SIZE];
  320. iData[0] = id; iData[1] = iTopNumber;
  321.  
  322. FormatQuery(g_szQuery, charsmax(g_szQuery),
  323. "SELECT `_name_field_`, `_time_field_` FROM `_table_name_` ORDER BY `_time_field_` DESC LIMIT %d", iTopNumber);
  324. SQL_SendThreadedQuery("FormatTop", g_hSqlHandle,"QueryHandler_FormatTopList", g_szQuery, iData);
  325. }
  326.  
  327. public QueryHandler_FormatTopList(FailState, Handle:hQuery, szError[], iError, Data[], iDataSize)
  328. {
  329. if(FailState)
  330. {
  331. PluginLog_SQLCallback("QueryHandler_FormatTopList", Data[iDataSize - 1], iError, FailState, szError);
  332. return;
  333. }
  334.  
  335. if(iError)
  336. {
  337. PluginLog_SQLCallback("QueryHandler_FormatTopList", Data[iDataSize - 1], iError, FailState, szError);
  338. return;
  339. }
  340.  
  341. #if !defined PREPARE_TOP_MOTD
  342. if(!is_user_connected(Data[0]))
  343. {
  344. return;
  345. }
  346. #endif
  347.  
  348. new iLen, szName[32], iPlace, iTime;
  349. iLen = formatex(g_szTopMotd, charsmax(g_szTopMotd), "<body bgcolor=#000000><font color=#FFB00><pre>");
  350. iLen += format(g_szTopMotd[iLen], charsmax(g_szTopMotd) - iLen,"%s %-22.22s %3s\n", "#", "Name", "Time in minutes");
  351.  
  352. new iCount;
  353.  
  354. if(!SQL_NumResults(hQuery))
  355. {
  356. #if defined PREPARE_TOP_MOTD
  357. g_bTopMotdNoData = true;
  358. #else
  359. client_print_color(Data[0], print_team_default, "%s \x03No top time motd as there is no data.");
  360. #endif
  361.  
  362. return;
  363. }
  364.  
  365. while(SQL_MoreResults(hQuery))
  366. {
  367. SQL_ReadResult(hQuery, 0, szName, charsmax(szName));
  368. iTime = SQL_ReadResult(hQuery, 1);
  369.  
  370. replace_all(szName, charsmax(szName), "<", "&lt;");
  371. replace_all(szName, charsmax(szName), ">", "&gt;");
  372.  
  373. iLen += formatex(g_szTopMotd[iLen], charsmax(g_szTopMotd) - iLen, "%d %-22.22s %d\n", ++iPlace, szName, iTime / 60);
  374. SQL_NextRow(hQuery)
  375. iCount++;
  376. }
  377.  
  378. if(iCount)
  379. {
  380. iLen += formatex(g_szTopMotd[iLen], charsmax(g_szTopMotd) - iLen, "</pre></font></body>");
  381.  
  382. new szTitle[25];
  383. formatex(szTitle, charsmax(szTitle), "Time Top%d", Data[1]);
  384.  
  385. if(Data[0] > 0)
  386. {
  387. show_motd(Data[0], g_szTopMotd, szTitle);
  388. }
  389. }
  390.  
  391. else
  392. {
  393. client_print_color(Data[0], print_team_default, "%s \x01No data in database yet..", PREFIX);
  394. }
  395. }
  396.  
  397. public client_disconnected(id)
  398. {
  399. if(is_user_bot(id))
  400. {
  401. return;
  402. }
  403.  
  404. if(g_iPlayedTime[id] != NOT_RETRIEVED)
  405. {
  406. SavePlayedTime(id, true);
  407. g_iPlayedTime[id] = NOT_RETRIEVED;
  408. }
  409. }
  410.  
  411. public client_authorized(id)
  412. {
  413. if(is_user_bot(id))
  414. {
  415. return;
  416. }
  417.  
  418. g_iPlayedTime[id] = NOT_RETRIEVED;
  419. #if !defined GET_TIME_INSTANT_QUERY
  420. GetClientPlayedTime(id, true);
  421. #else
  422. g_iPlayedTime[id] = GetClientPlayedTime(id, true);
  423. #endif
  424. }
  425.  
  426. public client_infochanged(id)
  427. {
  428. if(!is_user_connected(id))
  429. {
  430. return;
  431. }
  432.  
  433. get_user_name(id, g_szOldName[id], charsmax(g_szOldName[]));
  434. }
  435.  
  436. public FMCallback_InfoChanged_Post(id)
  437. {
  438. if(!is_user_connected(id))
  439. {
  440. return;
  441. }
  442.  
  443. new szNewName[32];
  444. get_user_name(id, szNewName, charsmax(szNewName));
  445.  
  446. if(!equal(g_szOldName[id], szNewName))
  447. {
  448. #if defined USE_NAME;
  449. g_iPlayedTime[id] = NOT_RETRIEVED;
  450. GetClientPlayedTime(id, false); // Get new played time for the new name.
  451. #else
  452. CleanString(szNewName, charsmax(szNewName))
  453. UpdateNameInDatabase(id, szNewName);
  454. #endif
  455. }
  456. }
  457.  
  458. #if !defined USE_NAME
  459. stock UpdateNameInDatabase(id, szNewName[])
  460. {
  461. if(g_iPlayedTime[id] == NOT_RETRIEVED)
  462. {
  463. return;
  464. }
  465.  
  466. new szAuthId[33]; get_user_authid(id, szAuthId, charsmax(szAuthId));
  467. FormatQuery(g_szQuery, charsmax(g_szQuery), "UPDATE `_table_name_` SET `_name_field_` = '%s' WHERE `_identifier_field_` = '%s'", szNewName, szAuthId);
  468. SQL_ThreadQuery(g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  469. }
  470. #endif
  471.  
  472. stock SavePlayedTime(id, bool:bIsDisconnect)
  473. {
  474. new szIdentifier[IDENTIFIER_MAX_LENGTH];
  475.  
  476. new iRet
  477. ExecuteForward(g_hSaveTimeForward, iRet, id, bIsDisconnect);
  478.  
  479. #if defined USE_NAME
  480. get_user_name(id, szIdentifier, charsmax(szIdentifier));
  481. CleanString(szIdentifier, charsmax(szIdentifier));
  482. #else
  483. get_user_authid(id, szIdentifier, charsmax(szIdentifier));
  484. #endif
  485.  
  486. #if defined USE_NAME
  487. FormatQuery(g_szQuery, charsmax(g_szQuery), "UPDATE _table_name_ SET `_time_field_` = '%d' WHERE `_name_field_` ='%s'", g_iPlayedTime[id] + get_user_time(id), szIdentifier);
  488. #else
  489. FormatQuery(g_szQuery, charsmax(g_szQuery), "UPDATE _table_name_ SET `_time_field_` = '%d' WHERE `_identifier_field_` ='%s'", g_iPlayedTime[id] + get_user_time(id), szIdentifier);
  490. #endif
  491.  
  492. SQL_SendThreadedQuery("SavePlayedTime", g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  493. }
  494.  
  495. #if !defined GET_TIME_INSTANT_QUERY
  496. stock GetClientPlayedTime(id, bool:bConnect = true)
  497. {
  498. new szIdentifier[MAX_NAME_LENGTH + 3];
  499. #if defined USE_NAME
  500. get_user_name(id, szIdentifier, charsmax(szIdentifier));
  501. CleanString(szIdentifier, charsmax(szIdentifier));
  502. #else
  503. get_user_authid(id, szIdentifier, charsmax(szIdentifier));
  504. #endif
  505.  
  506. #if defined USE_NAME
  507. FormatQuery(g_szQuery, charsmax(g_szQuery), "SELECT `_time_field_` FROM `_table_name_` WHERE `_name_field_` ='%s'", szIdentifier);
  508. #else
  509. new szName[MAX_NAME_LENGTH]; get_user_name(id, szName, charsmax(szName));
  510. FormatQuery(g_szQuery, charsmax(g_szQuery), "SELECT `_time_field_`, `_name_field_` FROM `_table_name_` WHERE `_identifier_field_` ='%s'", szIdentifier);
  511. #endif
  512.  
  513. new Data[MAX_DATA_ARRAY_SIZE];
  514. Data[0] = id; Data[1] = _:bConnect;
  515. SQL_SendThreadedQuery("QueryHandler_GetPlayedTime", g_hSqlHandle, "QueryHandler_GetPlayedTime", g_szQuery, Data);
  516. }
  517.  
  518. public QueryHandler_GetPlayedTime(FailState, Handle:hQuery, szError[], iError, Data[], iDataSize)
  519. {
  520. PluginLog_SQLCallback("QueryHandler_GetPlayedTime", Data[iDataSize - 1], iError, FailState, szError);
  521.  
  522. if(iError)
  523. {
  524. return;
  525. }
  526.  
  527. new szName[MAX_NAME_LENGTH];
  528.  
  529. #if !defined USE_NAME
  530. new szIdentifier[IDENTIFIER_MAX_LENGTH]; get_user_authid(Data[0], szIdentifier, charsmax(szIdentifier));
  531. #endif
  532.  
  533. new id = Data[0];
  534. if(!SQL_MoreResults(hQuery))
  535. {
  536. get_user_name(id, szName, charsmax(szName));
  537.  
  538. #if defined USE_NAME
  539. FormatQuery(g_szQuery, charsmax(g_szQuery), "INSERT INTO `_table_name_` (`_name_field_`, `_time_field_`) VALUES ('%s', '0')", szName);
  540. #else
  541. FormatQuery(g_szQuery, charsmax(g_szQuery), "INSERT INTO `_table_name_` (`_identifier_field_`, `_name_field_`, `_time_field_`) VALUES ('%s', '%s', '0')", szIdentifier, szName);
  542. #endif
  543.  
  544. g_iPlayedTime[id] = 0;
  545. SQL_SendThreadedQuery("QueryHandler_GetPlayedTime", g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  546. return;
  547. }
  548.  
  549. g_iPlayedTime[id] = SQL_ReadResult(hQuery, 0);
  550.  
  551. new iRet;
  552. ExecuteForward(g_hGetTimeForward, iRet, id, Data[1]);
  553.  
  554. get_user_name(id, szName, charsmax(szName));
  555. PluginLog("Got %d minutes (%d sec) for %s", g_iPlayedTime[id] / 60, g_iPlayedTime[id], szName);
  556.  
  557. #if !defined USE_NAME
  558. new szOldSavedName[MAX_NAME_LENGTH];
  559.  
  560. //get_user_name(id, szName, charsmax(szName));
  561. SQL_ReadResult(hQuery, 1, szOldSavedName, charsmax(szOldSavedName))
  562.  
  563. CleanString(szName, charsmax(szName));
  564.  
  565. if(!equal(szName, szOldSavedName))
  566. {
  567. FormatQuery(g_szQuery, charsmax(g_szQuery),
  568. "UPDATE `_table_name_` SET `_name_field_` = '%s' WHERE `_identifier_field_` = '%s'",
  569. szName, szIdentifier);
  570. SQL_SendThreadedQuery("QueryHandler_GetPlayedTime", g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  571. }
  572. #endif
  573. }
  574. #else
  575.  
  576. stock GetClientPlayedTime(id, bool:bConnect = true)
  577. {
  578. new szIdentifier[MAX_NAME_LENGTH + 3];
  579. new szName[MAX_NAME_LENGTH]; get_user_name(id, szName, charsmax(szName));
  580.  
  581. #if defined USE_NAME
  582. get_user_name(id, szIdentifier, charsmax(szIdentifier));
  583. CleanString(szIdentifier, charsmax(szIdentifier));
  584. #else
  585. get_user_authid(id, szIdentifier, charsmax(szIdentifier));
  586. #endif
  587.  
  588. #if defined USE_NAME
  589. FormatQuery(g_szQuery, charsmax(g_szQuery), "SELECT `_time_field_` FROM `_table_name_` WHERE `_name_field_` ='%s'", szIdentifier);
  590. #else
  591. FormatQuery(g_szQuery, charsmax(g_szQuery), "SELECT `_time_field_`, `_name_field_` FROM `_table_name_` WHERE `_identifier_field_` ='%s'", szIdentifier);
  592. #endif
  593.  
  594. //SQL_SendThreadedQuery("QueryHandler_GetPlayedTime", g_hSqlHandle, "QueryHandler_GetPlayedTime", g_szQuery, Data);
  595.  
  596. PluginLog_Query("GetClientPlayedTime", g_szQuery);
  597.  
  598. new Handle:hQuery, Handle:hConnection;
  599. new iError, szError[256];
  600. hConnection = SQL_Connect(g_hSqlHandle, iError, szError, charsmax(szError));
  601. ++g_iQueryNumber
  602.  
  603. if(iError)
  604. {
  605. SQL_FreeHandle(hConnection);
  606. PluginLog_SQLCallback("GetClientPlayedTime #1", g_iQueryNumber, iError, 0, szError);
  607.  
  608. return;
  609. }
  610.  
  611. hQuery = SQL_PrepareQuery(g_hSqlHandle, g_szQuery);
  612.  
  613. if(!SQL_Execute(hQuery))
  614. {
  615. SQL_QueryError(hQuery, szError, charsmax(szError));
  616. PluginLog_SQLCallback("GetClientPlayedTime #2", g_iQueryNumber, 0, 0, szError);
  617.  
  618. SQL_FreeHandle(hQuery);
  619. SQL_FreeHandle(hConnection);
  620. return;
  621. }
  622.  
  623. if(!SQL_MoreResults(hQuery))
  624. {
  625. SQL_FreeHandle(hQuery);
  626. SQL_FreeHandle(hConnection);
  627.  
  628. get_user_name(id, szName, charsmax(szName));
  629.  
  630. #if defined USE_NAME
  631. FormatQuery(g_szQuery, charsmax(g_szQuery), "INSERT INTO `_table_name_` (`_name_field_`, `_time_field_`) VALUES ('%s', '0')", szName);
  632. #else
  633. FormatQuery(g_szQuery, charsmax(g_szQuery), "INSERT INTO `_table_name_` (`_identifier_field_`, `_name_field_`, `_time_field_`) VALUES ('%s', '%s', '0')", szIdentifier, szName);
  634. #endif
  635.  
  636. g_iPlayedTime[id] = 0;
  637. SQL_SendThreadedQuery("GetClientPlayedTime #3", g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  638. return;
  639. }
  640.  
  641. new iRet;
  642. ExecuteForward(g_hGetTimeForward, iRet, id, bConnect);
  643.  
  644. get_user_name(id, szName, charsmax(szName));
  645. PluginLog("Got %d minutes (%d sec) for %s", g_iPlayedTime[id] / 60, g_iPlayedTime[id], szName);
  646.  
  647. #if !defined USE_NAME
  648. new szOldSavedName[MAX_NAME_LENGTH];
  649.  
  650. //get_user_name(id, szName, charsmax(szName));
  651. SQL_ReadResult(hQuery, 1, szOldSavedName, charsmax(szOldSavedName))
  652.  
  653. CleanString(szName, charsmax(szName));
  654.  
  655. if(!equal(szName, szOldSavedName))
  656. {
  657. FormatQuery(g_szQuery, charsmax(g_szQuery),
  658. "UPDATE `_table_name_` SET `_name_field_` = '%s' WHERE `_identifier_field_` = '%s'",
  659. szName, szIdentifier);
  660. SQL_SendThreadedQuery("GetClientPlayedTime #3", g_hSqlHandle, "QueryHandler_Dump", g_szQuery);
  661. }
  662. #endif
  663.  
  664. g_iPlayedTime[id] = SQL_ReadResult(hQuery, 0);
  665.  
  666. SQL_FreeHandle(hQuery);
  667. SQL_FreeHandle(hConnection);
  668. }
  669. #endif
  670.  
  671.  
  672. public QueryHandler_Dump(FailState, Handle:Query, szError[], iError, Data[], iDataSize)
  673. {
  674. PluginLog_SQLCallback("QueryHandler_Dump", Data[iDataSize - 1], iError, FailState, szError);
  675. }
  676.  
  677. CreateTableInDB()
  678. {
  679. #if SAVE_TYPE == SQLITE
  680. SQL_SetAffinity("sqlite");
  681. g_hSqlHandle = SQL_MakeDbTuple("", "", "", "played_time_database");
  682. #endif
  683.  
  684. #if SAVE_TYPE == MYSQL
  685. SQL_SetAffinity("mysql");
  686. g_hSqlHandle = SQL_MakeDbTuple(SQL_CONNECT_DATA[0], SQL_CONNECT_DATA[1], SQL_CONNECT_DATA[2], SQL_CONNECT_DATA[3]);
  687. #endif
  688.  
  689. if(g_hSqlHandle == Empty_Handle)
  690. {
  691. set_fail_state("Could not connect to the SQL Database.");
  692. }
  693.  
  694. #if SAVE_TYPE == SQLITE
  695. #if defined USE_NAME
  696. FormatQuery(g_szQuery, charsmax(g_szQuery),"CREATE TABLE IF NOT EXISTS `_table_name_` (`id` INTEGER PRIMARY KEY, `_name_field_` CHAR(32) UNIQUE, `_time_field_` INTEGER");
  697. #else
  698. FormatQuery(g_szQuery, charsmax(g_szQuery),"CREATE TABLE IF NOT EXISTS `_table_name_` (`id` INTEGER PRIMARY KEY, `_identifier_field_` CHAR(35) UNIQUE, `_name_field_` CHAR(32), _time_field_ INTEGER)");
  699. #endif
  700. #endif
  701. #if SAVE_TYPE == MYSQL
  702. #if defined USE_NAME
  703. FormatQuery(g_szQuery, charsmax(g_szQuery), "CREATE TABLE IF NOT EXISTS `_table_name_` (`_name_field_` VARCHAR(35) UNIQUE, `_time_field_` INT, `date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)");
  704. #else
  705. FormatQuery(g_szQuery, charsmax(g_szQuery), "CREATE TABLE IF NOT EXISTS `_table_name_` (`_identifier_field_` VARCHAR(35) UNIQUE, `_name_field_` VARCHAR(32), `_time_field_` INT, `date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)");
  706. #endif
  707. #endif
  708.  
  709. SQL_SendThreadedQuery("CreateTableInDB", g_hSqlHandle, "QueryHandler_Initialize", g_szQuery);
  710. }
  711.  
  712. public QueryHandler_Initialize(FailState, Handle:Query, szError[], iError, Data[], iDataSize)
  713. {
  714. if(FailState || iError)
  715. {
  716. PluginLog_SQLCallback("QueryHandler_Initialize", Data[iDataSize - 1], iError, FailState, szError);
  717. #if AMXX_VERSION_NUM < 183
  718. new szFailStateMessage[256];
  719. formatex(szFailStateMessage, charsmax(szFailStateMessage), "FailState %d %d: %s", FailState, iError, szError);
  720. set_fail_state(szFailStateMessage);
  721. #else
  722. set_fail_state("FailState %d %d: %s", FailState, iError, szError);
  723. #endif
  724. }
  725.  
  726. else
  727. {
  728. PluginLog("(QueryHandler_Initialize) [Query #: %d]: StartUp Query executed Successfully.", Data[iDataSize - 1]);
  729. }
  730.  
  731. #if defined PREPARE_TOP_MOTD
  732. FormatTop(-1, TOP_DEFAULT_NUMBER);
  733. #endif
  734. }
  735.  
  736. // NATIVES
  737. public native_get_user_played_time(plugin_id, argc)
  738. {
  739. new id = get_param(1);
  740. if(!IsValidPlayer_Native(id))
  741. {
  742. return -1
  743. }
  744.  
  745. return g_iPlayedTime[id];
  746. }
  747.  
  748. public native_set_user_played_time(plugin_id, argc)
  749. {
  750. new id = get_param(1);
  751. new iNewTime = get_param(2);
  752.  
  753. if(!IsValidPlayer_Native(id))
  754. {
  755. return 0
  756. }
  757.  
  758. g_iPlayedTime[id] = iNewTime;
  759. return 1;
  760. }
  761.  
  762. public native_get_save_type(plugin_id, argc)
  763. {
  764. return SAVE_TYPE;
  765. }
  766.  
  767. stock IsValidPlayer_Native(id)
  768. {
  769. if(!is_user_connected(id))
  770. {
  771. log_error(AMX_ERR_NATIVE, "Client %d is NOT connected", id);
  772. return 0;
  773. }
  774.  
  775. if(is_user_bot(id))
  776. {
  777. log_error(AMX_ERR_NATIVE, "Client %d is a BOT", id);
  778. return 0;
  779. }
  780.  
  781. if(is_user_hltv(id))
  782. {
  783. log_error(AMX_ERR_NATIVE, "HLTV client %d", id);
  784. return 0;
  785. }
  786.  
  787. if( !( 1 <= id <= g_iMaxPlayers ) )
  788. {
  789. log_error(AMX_ERR_NATIVE, "Index out of bounds %d", id);
  790. return 0
  791. }
  792.  
  793. return 1;
  794. }
  795.  
  796. stock CleanString(szName[], iSize)
  797. {
  798. replace_all(szName, iSize, "\"", "");
  799. replace_all(szName, iSize, "'", "");
  800. }
  801.  
  802. stock FormatQuery(szQueryStorage[], iSize, szQuery[], any:...)
  803. {
  804. vformat(szQueryStorage, iSize, szQuery, 4);
  805.  
  806. replace_all(szQueryStorage, iSize, "_identifier_field_", "steamid");
  807. replace_all(szQueryStorage, iSize, "_name_field_", "name");
  808. replace_all(szQueryStorage, iSize, "_time_field_", "time_played");
  809. replace_all(szQueryStorage, iSize, "_table_name_", "played_time");
  810. }
  811.  
  812. stock SQL_SendThreadedQuery(szPosition[], Handle:hSql, szQueryCallback[], szQuery[], Data[MAX_DATA_ARRAY_SIZE] = "")
  813. {
  814. new ModifiedData[MAX_DATA_ARRAY_SIZE + 1];
  815.  
  816. // Must be before, as this is where the increment happen.
  817. PluginLog_Query(szPosition, szQuery);
  818. for(new i; i < MAX_DATA_ARRAY_SIZE; i++)
  819. {
  820. ModifiedData[i] = Data[i];
  821. }
  822.  
  823. ModifiedData[MAX_DATA_ARRAY_SIZE] = g_iQueryNumber;
  824.  
  825. SQL_ThreadQuery(hSql, szQueryCallback, szQuery, ModifiedData, MAX_DATA_ARRAY_SIZE + 1);
  826. }
  827.  
  828. stock PluginLog(szString[], any:...)
  829. {
  830. #if !defined DO_NOT_LOG
  831. new szLog[1024]
  832. vformat(szLog, charsmax(szLog), szString, 2);
  833.  
  834. log_to_file(LOG_FILE_PLAYED_TIME, szLog);
  835. //log_amx("[Played Time] %s", szLog);
  836. #endif
  837. }
  838.  
  839. stock PluginLog_Query(szPosition[], szQuery[])
  840. {
  841. #if !defined DO_NOT_LOG
  842. log_to_file(LOG_FILE_PLAYED_TIME, "(%s) Query Executed (#%d): \n\t\t\t\t%s", szPosition, ++g_iQueryNumber, szQuery);
  843. //log_amx("[Played Time] (%s) Query Executed (#%d): \n\t\t%s", szPosition, g_iQueryNumber, szQuery);
  844. #endif
  845. }
  846.  
  847. stock PluginLog_SQLCallback(szPosition[], iQueryNumber, iError, FailState, szError[])
  848. {
  849. #if !defined DO_NOT_LOG
  850. if(iError || FailState)
  851. {
  852. log_to_file(LOG_FILE_PLAYED_TIME, "(%s) [Query#: %d] [Error# :%d] [FailState: %d]: %s", szPosition, iQueryNumber, iError, FailState, szError);
  853. }
  854.  
  855. else if(!iError && !FailState)
  856. {
  857. log_to_file(LOG_FILE_PLAYED_TIME, "(%s) [Query#: %d] executed successfully", szPosition, iQueryNumber);
  858. }
  859. #endif
  860. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement