Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.10 KB | None | 0 0
  1. #include <amxmodx>
  2. #include <amxmisc>
  3.  
  4. #if !defined MAX_PLAYERS
  5. const MAX_PLAYERS = 32
  6. #endif
  7.  
  8. #if !defined MAX_NAME_LENGTH
  9. const MAX_NAME_LENGTH = 32
  10. #endif
  11.  
  12. #if !defined MAX_AUTHID_LENGTH
  13. const MAX_AUTHID_LENGTH = 64
  14. #endif
  15.  
  16. #if !defined MAX_IP_LENGTH
  17. const MAX_IP_LENGTH = 16
  18. #endif
  19.  
  20. const SECONDS_IN_DAY = 86400
  21. const SECONDS_IN_WEEK = 604800
  22. const SECONDS_IN_MONTH = 2628000
  23. const SECONDS_IN_YEAR = 31536000
  24.  
  25. new const LIST_FILE_DESC[] = "# This file is generated automatically. Do not modify anything here as it would have no effect.^n\
  26. # extra <extra value> -- description [main plugin that contains the extra]^n"
  27.  
  28. new const PLUGIN_VERSION[] = "3.0-beta"
  29. new const TIME_FORMAT[] = "%d.%m.%Y"
  30. const Float:DELAY_ON_CHANGE = 0.1
  31. const EXTRAS_PER_PAGE = 20
  32. const MAX_DATA_LENGTH = 256
  33. const MAX_FILE_LENGTH = 256
  34. const MAX_DESC_LENGTH = 128
  35. const MAX_PLUGIN_NAME = 64
  36. const MAX_TYPE_LENGTH = 32
  37. const MAX_EXTRA_LENGTH = 32
  38. const MAX_DATE_LENGTH = 12
  39.  
  40. enum _:Extras
  41. {
  42. Date[MAX_DATE_LENGTH],
  43. Type[MAX_TYPE_LENGTH],
  44. Info[MAX_AUTHID_LENGTH],
  45. Extra[MAX_EXTRA_LENGTH],
  46. ExtraValue[MAX_EXTRA_LENGTH]
  47. }
  48.  
  49. enum _:PlayerData
  50. {
  51. PDATA_NAME[MAX_NAME_LENGTH],
  52. PDATA_IP[MAX_IP_LENGTH],
  53. PDATA_AUTHID[MAX_AUTHID_LENGTH]
  54. }
  55.  
  56. new Array:g_aExtras
  57. new Array:g_aUserExtras[MAX_PLAYERS + 1]
  58. new Trie:g_tUserExtras[MAX_PLAYERS + 1]
  59. new g_ePlayerData[MAX_PLAYERS + 1][PlayerData]
  60. new g_szConfigFile[MAX_FILE_LENGTH]
  61. new g_szListFile[MAX_FILE_LENGTH]
  62. new g_fwUserExtrasUpdated
  63. new g_fwConfigFileRead
  64. new g_iUserExtras[MAX_PLAYERS + 1]
  65. new g_iListFilePointer
  66. new g_iTotalExtras
  67. new g_iToday
  68.  
  69. #if defined GetFileTime
  70. new g_iFileTime
  71. #endif
  72.  
  73. new const g_szComments[][] =
  74. {
  75. "#===============================================#",
  76. "# Player Extras by OciXCrom: Configuration file #",
  77. "#===============================================#",
  78. "",
  79. "# Add each extra on a new line following the format:",
  80. "# ^"duration^" ^"type^" ^"info^" ^"extra^" ^"extra value [optional]^"",
  81. "",
  82. "# The ^"duration^" field should contain the date when the extra will end, following the format ^"day.month.year^", e.g. ^"20.09.2018^"",
  83. "# You can also type in the amount of days, weeks, months or years for the extra to last, e.g. ^"30 days^" - the date will be converted automatically after mapchange.",
  84. "# If you want the extra to be permanent, set this field to 0.",
  85. "",
  86. "# The ^"type^" field can be one of the following: ^"name^", ^"ip^", ^"steam^"",
  87. "# The ^"info^" field is the actual player's info according to the type, e.g. if ^"type^" is set to ^"name^", the ^"info^" field should be ^"OciXCrom^".",
  88. "# The ^"extra^" field is where you actually write the extra's name.",
  89. "# Some extras accept an extra value that can be entered in the ^"extra value^" field.",
  90. "",
  91. "# Players can have only one same extra at a time. If duplicate values are found, the player will receive the one that's listed first in the file.",
  92. "# For a full list of available extras, take a look at the file PlayerExtrasList.ini in the configs folder.",
  93. "",
  94. "# Here are some examples:",
  95. "# ^"20.09.2018^" ^"name^" ^"OciXCrom^" ^"colorchat^"",
  96. "# ^"08.10.2020^" ^"ip^" ^"77.29.42.36^" ^"prefix^" ^"{Pro Player}^"",
  97. "# ^"15 days^" ^"steam^" ^"STEAM_0:0:50153248^" ^"health^" ^"125^"",
  98. "# ^"0^" ^"steam^" ^"BOT^" ^"prefix^" ^"{I'm a bot}^"",
  99. "#===============================================#"
  100. }
  101.  
  102. public plugin_init()
  103. {
  104. register_plugin("Player Extras", PLUGIN_VERSION, "OciXCrom")
  105. register_cvar("CRXPlayerExtras", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)
  106. register_dictionary("PlayerExtras.txt")
  107.  
  108. register_clcmd( "pex_myextras", "Cmd_MyExtras", ADMIN_ALL, "[starting extra number]")
  109. register_concmd("pex_add", "Cmd_Add", ADMIN_RCON, "<duration> <type> <info> <extra> [extra value]")
  110. register_concmd("pex_reload", "Cmd_Reload", ADMIN_RCON)
  111.  
  112. SetupVars()
  113. }
  114.  
  115. public plugin_precache()
  116. {
  117. SetupFiles()
  118. }
  119.  
  120. public plugin_cfg()
  121. {
  122. if(g_iListFilePointer)
  123. {
  124. fclose(g_iListFilePointer)
  125. }
  126. }
  127.  
  128. SetupFiles()
  129. {
  130. get_configsdir(g_szConfigFile, charsmax(g_szConfigFile))
  131. copy(g_szListFile, charsmax(g_szListFile), g_szConfigFile)
  132. add(g_szConfigFile, charsmax(g_szConfigFile), "/PlayerExtras.ini")
  133. add(g_szListFile, charsmax(g_szListFile), "/PlayerExtrasList.ini")
  134. g_iListFilePointer = fopen(g_szListFile, "w")
  135. fputs(g_iListFilePointer, LIST_FILE_DESC)
  136. }
  137.  
  138. SetupVars()
  139. {
  140. g_aExtras = ArrayCreate(Extras)
  141. g_fwUserExtrasUpdated = CreateMultiForward("pex_user_extras_updated", ET_IGNORE, FP_CELL, FP_CELL)
  142. g_fwConfigFileRead = CreateMultiForward("pex_config_file_reloaded", ET_IGNORE, FP_CELL)
  143.  
  144. for(new i = 1; i <= MAX_PLAYERS; i++)
  145. {
  146. g_aUserExtras[i] = ArrayCreate(Extras)
  147. g_tUserExtras[i] = TrieCreate()
  148. }
  149.  
  150. g_iToday = get_systime()
  151. ReadFile(true)
  152. }
  153.  
  154. public plugin_end()
  155. {
  156. #if defined GetFileTime
  157. if(g_iFileTime != get_filetime())
  158. {
  159. ReadFile(false)
  160. }
  161. #else
  162. ReadFile(false)
  163. #endif
  164.  
  165. WriteFile()
  166. ArrayDestroy(g_aExtras)
  167.  
  168. for(new i = 1; i <= MAX_PLAYERS; i++)
  169. {
  170. ArrayDestroy(g_aUserExtras[i])
  171. TrieDestroy(g_tUserExtras[i])
  172. }
  173. }
  174.  
  175. WriteFile()
  176. {
  177. new iFilePointer = fopen(g_szConfigFile, "w")
  178.  
  179. if(iFilePointer)
  180. {
  181. for(new i; i < sizeof(g_szComments); i++)
  182. {
  183. fputs(iFilePointer, g_szComments[i])
  184. fputs(iFilePointer, "^n")
  185. }
  186.  
  187. for(new eExtra[Extras], i; i < g_iTotalExtras; i++)
  188. {
  189. ArrayGetArray(g_aExtras, i, eExtra)
  190. fprintf(iFilePointer, "^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", eExtra[Date], eExtra[Type], eExtra[Info], eExtra[Extra])
  191.  
  192. if(eExtra[ExtraValue][0])
  193. {
  194. fprintf(iFilePointer, " ^"%s^"", eExtra[ExtraValue])
  195. }
  196. }
  197.  
  198. fclose(iFilePointer)
  199. }
  200. }
  201.  
  202. ReadFile(bool:bFirstTime)
  203. {
  204. new iFilePointer = fopen(g_szConfigFile, "rt")
  205.  
  206. if(iFilePointer)
  207. {
  208. if(bFirstTime)
  209. {
  210. #if defined GetFileTime
  211. g_iFileTime = get_filetime()
  212. #endif
  213. }
  214. else
  215. {
  216. g_iTotalExtras = 0
  217. ArrayClear(g_aExtras)
  218. }
  219.  
  220. new szData[MAX_DATA_LENGTH], eExtra[Extras]
  221.  
  222. while(!feof(iFilePointer))
  223. {
  224. fgets(iFilePointer, szData, charsmax(szData))
  225. trim(szData)
  226.  
  227. switch(szData[0])
  228. {
  229. case EOS, '#', ';': continue
  230. default:
  231. {
  232. parse
  233. (
  234. szData,
  235. eExtra[Date], charsmax(eExtra[Date]),
  236. eExtra[Type], charsmax(eExtra[Type]),
  237. eExtra[Info], charsmax(eExtra[Info]),
  238. eExtra[Extra], charsmax(eExtra[Extra]),
  239. eExtra[ExtraValue], charsmax(eExtra[ExtraValue])
  240. )
  241.  
  242. if(convert_date(eExtra[Date], charsmax(eExtra[Date])) < g_iToday)
  243. {
  244. continue
  245. }
  246.  
  247. if(!is_valid_type(eExtra[Type]))
  248. {
  249. continue
  250. }
  251.  
  252. g_iTotalExtras++
  253. ArrayPushArray(g_aExtras, eExtra)
  254. eExtra[ExtraValue][0] = EOS
  255. }
  256. }
  257. }
  258.  
  259. fclose(iFilePointer)
  260. }
  261.  
  262. new iReturn
  263. ExecuteForward(g_fwConfigFileRead, iReturn, bFirstTime)
  264. }
  265.  
  266. public client_putinserver(id)
  267. {
  268. get_user_name(id, g_ePlayerData[id][PDATA_NAME], charsmax(g_ePlayerData[][PDATA_NAME]))
  269. get_user_ip(id, g_ePlayerData[id][PDATA_IP], charsmax(g_ePlayerData[][PDATA_IP]), 1)
  270. get_user_authid(id, g_ePlayerData[id][PDATA_AUTHID], charsmax(g_ePlayerData[][PDATA_AUTHID]))
  271. load_player_extras(id, true)
  272. }
  273.  
  274. public client_infochanged(id)
  275. {
  276. if(!is_user_connected(id))
  277. {
  278. return
  279. }
  280.  
  281. static szNewName[MAX_NAME_LENGTH]
  282. get_user_info(id, "name", szNewName, charsmax(szNewName))
  283.  
  284. if(!equal(szNewName, g_ePlayerData[id][PDATA_NAME]))
  285. {
  286. copy(g_ePlayerData[id][PDATA_NAME], charsmax(g_ePlayerData[][PDATA_NAME]), szNewName)
  287. set_task(DELAY_ON_CHANGE, "reload_player_extras", id)
  288. }
  289. }
  290.  
  291. public Cmd_MyExtras(id, iLevel, iCid)
  292. {
  293. if(!cmd_access(id, iLevel, iCid, 1))
  294. {
  295. return PLUGIN_HANDLED
  296. }
  297.  
  298. if(!g_iTotalExtras || !g_iUserExtras[id])
  299. {
  300. console_print(id, "%L", id, "PEX_NO_EXTRAS")
  301. return PLUGIN_HANDLED
  302. }
  303.  
  304. static eExtra[Extras]
  305. print_separator(id, true)
  306. console_print(id, "%L", id, "PEX_YOUR_EXTRAS", g_iUserExtras[id])
  307. print_separator(id, false)
  308.  
  309. new szArg[5]
  310. read_argv(1, szArg, charsmax(szArg))
  311.  
  312. new iStart = clamp(str_to_num(szArg) - 1, 0, clamp(g_iUserExtras[id] - EXTRAS_PER_PAGE, 0))
  313. new iMax = clamp(iStart + EXTRAS_PER_PAGE, .max = g_iUserExtras[id])
  314.  
  315. for(new i = iStart; i < iMax; i++)
  316. {
  317. ArrayGetArray(g_aUserExtras[id], i, eExtra)
  318. console_print(id, "%2d %-16.15s %-16.15s %s", i + 1, eExtra[Date], eExtra[Extra], eExtra[ExtraValue])
  319. }
  320.  
  321. if(g_iUserExtras[id] - iStart > EXTRAS_PER_PAGE)
  322. {
  323. print_separator(id, false)
  324. console_print(id, "%L", id, "PEX_SEE_MORE", iStart + EXTRAS_PER_PAGE + 1)
  325. }
  326.  
  327. print_separator(id, true)
  328. return PLUGIN_HANDLED
  329. }
  330.  
  331. public Cmd_Add(id, iLevel, iCid)
  332. {
  333. if(!cmd_access(id, iLevel, iCid, 5))
  334. {
  335. return PLUGIN_HANDLED
  336. }
  337.  
  338. static eExtra[Extras]
  339. eExtra[ExtraValue][0] = EOS
  340. read_argv(1, eExtra[Date], charsmax(eExtra[Date]))
  341.  
  342. if(convert_date(eExtra[Date], charsmax(eExtra[Date])) < g_iToday)
  343. {
  344. console_print(id, "%L", id, "PEX_INVALID_DATE", eExtra[Date])
  345. return PLUGIN_HANDLED
  346. }
  347.  
  348. read_argv(2, eExtra[Type], charsmax(eExtra[Type]))
  349.  
  350. if(!is_valid_type(eExtra[Type]))
  351. {
  352. console_print(id, "%L", id, "PEX_INVALID_TYPE", eExtra[Type])
  353. return PLUGIN_HANDLED
  354. }
  355.  
  356. read_argv(3, eExtra[Info], charsmax(eExtra[Info]))
  357. read_argv(4, eExtra[Extra], charsmax(eExtra[Extra]))
  358. read_argv(5, eExtra[ExtraValue], charsmax(eExtra[ExtraValue]))
  359.  
  360. new iFilePointer = fopen(g_szConfigFile, "a")
  361.  
  362. if(!iFilePointer)
  363. {
  364. console_print(id, "%L", id, "PEX_CANT_OPEN")
  365. return PLUGIN_HANDLED
  366. }
  367.  
  368. g_iTotalExtras++
  369. ArrayPushArray(g_aExtras, eExtra)
  370. fprintf(iFilePointer, "^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", eExtra[Date], eExtra[Type], eExtra[Info], eExtra[Extra])
  371.  
  372. print_separator(id, true)
  373. console_print(id, "%L", id, "PEX_ADD_SUCCESS")
  374. print_separator(id, false)
  375. console_print(id, "%L: %s", id, "PEX_DATE", eExtra[Date])
  376. console_print(id, "%L: %s", id, "PEX_TYPE", eExtra[Type])
  377. console_print(id, "%L: %s", id, "PEX_INFO", eExtra[Info])
  378. console_print(id, "%L: %s", id, "PEX_EXTRA", eExtra[Extra])
  379.  
  380. if(eExtra[ExtraValue][0])
  381. {
  382. console_print(id, "%L: %s", id, "PEX_EXTRA_VALUE", eExtra[ExtraValue])
  383. fprintf(iFilePointer, " ^"%s^"", eExtra[ExtraValue])
  384. }
  385.  
  386. fclose(iFilePointer)
  387. print_separator(id, true)
  388. return PLUGIN_HANDLED
  389. }
  390.  
  391. public Cmd_Reload(id, iLevel, iCid)
  392. {
  393. if(!cmd_access(id, iLevel, iCid, 1))
  394. {
  395. return PLUGIN_HANDLED
  396. }
  397.  
  398. ReadFile(false)
  399.  
  400. new iPlayers[32], iPnum
  401. get_players(iPlayers, iPnum)
  402.  
  403. for(new i; i < sizeof(g_iTotalExtras); i++)
  404. {
  405. load_player_extras(iPlayers[i], false)
  406. }
  407.  
  408. console_print(id, "%L", id, "PEX_RELOAD_SUCCESS", g_iTotalExtras)
  409. return PLUGIN_HANDLED
  410. }
  411.  
  412. public reload_player_extras(id)
  413. {
  414. load_player_extras(id, false)
  415. }
  416.  
  417. load_player_extras(id, bool:bOnConnect)
  418. {
  419. if(!is_user_connected(id))
  420. {
  421. return
  422. }
  423.  
  424. g_iUserExtras[id] = 0
  425. ArrayClear(g_aUserExtras[id])
  426. TrieClear(g_tUserExtras[id])
  427. static eExtra[Extras]
  428.  
  429. for(new i; i < g_iTotalExtras; i++)
  430. {
  431. ArrayGetArray(g_aExtras, i, eExtra)
  432.  
  433. if(meets_requirements(id, eExtra[Type], eExtra[Info]) && !TrieKeyExists(g_tUserExtras[id], eExtra[Extra]))
  434. {
  435. g_iUserExtras[id]++
  436. ArrayPushArray(g_aUserExtras[id], eExtra)
  437. TrieSetString(g_tUserExtras[id], eExtra[Extra], eExtra[ExtraValue])
  438. }
  439. }
  440.  
  441. new iReturn
  442. ExecuteForward(g_fwUserExtrasUpdated, iReturn, id, bOnConnect)
  443. }
  444.  
  445. print_separator(id, bool:bMain)
  446. {
  447. console_print(id, bMain ? "===============================" : "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
  448. }
  449.  
  450. convert_date(szDate[], iLen)
  451. {
  452. static szAmount[5], szCurrency[2], iTimeStamp
  453.  
  454. if(contain(szDate, " ") != -1)
  455. {
  456. parse(szDate, szAmount, charsmax(szAmount), szCurrency, charsmax(szCurrency))
  457.  
  458. switch(szCurrency[0])
  459. {
  460. case 'D', 'd': iTimeStamp = SECONDS_IN_DAY
  461. case 'W', 'w': iTimeStamp = SECONDS_IN_WEEK
  462. case 'M', 'm': iTimeStamp = SECONDS_IN_MONTH
  463. case 'Y', 'y': iTimeStamp = SECONDS_IN_YEAR
  464. }
  465.  
  466. iTimeStamp = clamp(iTimeStamp * str_to_num(szAmount) + g_iToday)
  467. format_time(szDate, iLen, TIME_FORMAT, iTimeStamp)
  468. }
  469. else
  470. {
  471. iTimeStamp = parse_time(szDate, TIME_FORMAT)
  472. }
  473.  
  474. return iTimeStamp
  475. }
  476.  
  477. bool:is_valid_type(szType[])
  478. {
  479. switch(szType[0])
  480. {
  481. case 'N', 'n', 'I', 'i', 'S', 's': return true
  482. }
  483.  
  484. return false
  485. }
  486.  
  487. bool:meets_requirements(id, szType[], szInfo[])
  488. {
  489. switch(szType[0])
  490. {
  491. case 'N', 'n':
  492. {
  493. if(equali(g_ePlayerData[id][PDATA_NAME], szInfo))
  494. {
  495. return true
  496. }
  497. }
  498. case 'I', 'i':
  499. {
  500. if(equal(g_ePlayerData[id][PDATA_IP], szInfo))
  501. {
  502. return true
  503. }
  504. }
  505. case 'S', 's':
  506. {
  507. if(equal(g_ePlayerData[id][PDATA_AUTHID], szInfo))
  508. {
  509. return true
  510. }
  511. }
  512. }
  513.  
  514. return false
  515. }
  516.  
  517. #if defined GetFileTime
  518. get_filetime()
  519. {
  520. return GetFileTime(g_szConfigFile, FileTime_LastChange)
  521. }
  522. #endif
  523.  
  524. public plugin_natives()
  525. {
  526. register_library("pex")
  527. register_native("pex_get_config_file", "_pex_get_config_file")
  528. register_native("pex_get_extra_value", "_pex_get_extra_value")
  529. register_native("pex_get_list_file", "_pex_get_list_file")
  530. register_native("pex_get_total_extras", "_pex_get_total_extras")
  531. register_native("pex_get_user_extras", "_pex_get_user_extras")
  532. register_native("pex_register_extra", "_pex_register_extra")
  533. register_native("pex_reload_config_file", "_pex_reload_config_file")
  534. register_native("pex_reload_user_extras", "_pex_reload_user_extras")
  535. register_native("pex_user_has_extra", "_pex_user_has_extra")
  536. }
  537.  
  538. public _pex_get_config_file(iPlugin, iParams)
  539. {
  540. set_string(1, g_szConfigFile, get_param(2))
  541. }
  542.  
  543. public bool:_pex_get_extra_value(iPlugin, iParams)
  544. {
  545. static szExtra[MAX_EXTRA_LENGTH], szTrieValue[MAX_EXTRA_LENGTH]
  546. get_string(2, szExtra, charsmax(szExtra))
  547. TrieGetString(g_tUserExtras[get_param(1)], szExtra, szTrieValue, charsmax(szTrieValue))
  548. set_string(3, szTrieValue, get_param(4))
  549. }
  550.  
  551. public _pex_get_list_file(iPlugin, iParams)
  552. {
  553. set_string(1, g_szListFile, get_param(2))
  554. }
  555.  
  556. public _pex_get_total_extras(iPlugin, iParams)
  557. {
  558. return g_iTotalExtras
  559. }
  560.  
  561. public _pex_get_user_extras(iPlugin, iParams)
  562. {
  563. return g_iUserExtras[get_param(1)]
  564. }
  565.  
  566. public _pex_register_extra(iPlugin, iParams)
  567. {
  568. if(g_iListFilePointer)
  569. {
  570. static szExtra[MAX_EXTRA_LENGTH], szDescription[MAX_DESC_LENGTH], szExtraValue[MAX_EXTRA_LENGTH], szPlugin[MAX_PLUGIN_NAME]
  571.  
  572. get_string(1, szExtra, charsmax(szExtra))
  573. get_string(2, szDescription, charsmax(szDescription))
  574. get_string(3, szExtraValue, charsmax(szExtraValue))
  575. get_plugin(iPlugin, szPlugin, charsmax(szPlugin))
  576.  
  577. fprintf(g_iListFilePointer, szExtra)
  578.  
  579. if(szExtraValue[0])
  580. {
  581. fprintf(g_iListFilePointer, " <%s>", szExtraValue)
  582. }
  583.  
  584. fprintf(g_iListFilePointer, " -- %s [%s]^n", szDescription, szPlugin)
  585. }
  586. }
  587.  
  588. public _pex_reload_config_file(iPlugin, iParams)
  589. {
  590. ReadFile(false)
  591. }
  592.  
  593. public _pex_reload_user_extras(iPlugin, iParams)
  594. {
  595. load_player_extras(get_param(1), false)
  596. }
  597.  
  598. public bool:_pex_user_has_extra(iPlugin, iParams)
  599. {
  600. static szExtra[MAX_EXTRA_LENGTH]
  601. get_string(2, szExtra, charsmax(szExtra))
  602. return TrieKeyExists(g_tUserExtras[get_param(1)], szExtra)
  603. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement