· 6 years ago · Aug 07, 2019, 02:46 PM
1#include <amxmodx>
2#include <amxmisc>
3#include <cromchat>
4#include <crxranks_const>
5#include <csx>
6#include <fakemeta>
7#include <nvault>
8#include <sqlx>
9
10#if AMXX_VERSION_NUM < 183 || !defined set_dhudmessage
11 #tryinclude <dhudmessage>
12
13 #if !defined _dhudmessage_included
14 #error "dhudmessage.inc" is missing in your "scripting/include" folder. Download it from: "https://amxx-bg.info/inc/"
15 #endif
16#endif
17
18#if !defined client_disconnected
19 #define client_disconnected client_disconnect
20#endif
21
22#if !defined replace_string
23 #define replace_string replace_all
24#endif
25
26new const PLUGIN_VERSION[] = "3.6.1"
27const Float:DELAY_ON_CONNECT = 5.0
28const Float:HUD_REFRESH_FREQ = 1.0
29const Float:DELAY_ON_CHANGE = 0.1
30const MAX_SQL_LENGTH = 512
31const MAX_QUERY_LENGTH = 256
32const MAX_SOUND_LENGTH = 128
33const MAX_SQL_PLAYER_LENGTH = 64
34const MAX_SQL_RANK_LENGTH = CRXRANKS_MAX_RANK_LENGTH * 2
35const TASK_HUD = 304500
36
37#if !defined MAX_NAME_LENGTH
38const MAX_NAME_LENGTH = 32
39#endif
40
41#if !defined MAX_PLAYERS
42const MAX_PLAYERS = 32
43#endif
44
45new const ARG_CURRENT_XP[] = "$current_xp$"
46new const ARG_NEXT_XP[] = "$next_xp$"
47new const ARG_XP_NEEDED[] = "$xp_needed$"
48new const ARG_LEVEL[] = "$level$"
49new const ARG_NEXT_LEVEL[] = "$next_level$"
50new const ARG_RANK[] = "$rank$"
51new const ARG_NEXT_RANK[] = "$next_rank$"
52new const ARG_MAX_LEVELS[] = "$max_levels$"
53new const ARG_LINE_BREAK[] = "$br$"
54new const ARG_NAME[] = "$name$"
55
56new const XPREWARD_KILL[] = "kill"
57new const XPREWARD_HEADSHOT[] = "headshot"
58new const XPREWARD_TEAMKILL[] = "teamkill"
59new const XPREWARD_SUICIDE[] = "suicide"
60new const XPREWARD_DEATH[] = "death"
61
62new const XPREWARD_BOMB_PLANTED[] = "bomb_planted"
63new const XPREWARD_BOMB_DEFUSED[] = "bomb_defused"
64new const XPREWARD_BOMB_EXPLODED[] = "bomb_exploded"
65
66#define clr(%1) %1 == -1 ? random(256) : %1
67
68#define HUDINFO_PARAMS clr(g_eSettings[HUDINFO_COLOR][0]), clr(g_eSettings[HUDINFO_COLOR][1]), clr(g_eSettings[HUDINFO_COLOR][2]),\
69g_eSettings[HUDINFO_POSITION][0], g_eSettings[HUDINFO_POSITION][1], 0, 0.1, 1.0, 0.1, 0.1
70
71#define HUDINFO_PARAMS_DEAD clr(g_eSettings[HUDINFO_COLOR][0]), clr(g_eSettings[HUDINFO_COLOR][1]), clr(g_eSettings[HUDINFO_COLOR][2]),\
72g_eSettings[HUDINFO_POSITION_DEAD][0], g_eSettings[HUDINFO_POSITION_DEAD][1], 0, 0.1, 1.0, 0.1, 0.1
73
74#define XP_NOTIFIER_PARAMS_GET clr(g_eSettings[XP_NOTIFIER_COLOR_GET][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][2]),\
75g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime = g_eSettings[XP_NOTIFIER_DURATION]
76
77#define XP_NOTIFIER_PARAMS_LOSE clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][2]),\
78g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime = g_eSettings[XP_NOTIFIER_DURATION]
79
80enum _:SaveLoad
81{
82 SL_SAVE_DATA,
83 SL_LOAD_DATA
84}
85
86enum _:Objects
87{
88 OBJ_HUDINFO,
89 OBJ_XP_NOTIFIER
90}
91
92enum _:SaveTypes
93{
94 SAVE_NICKNAME,
95 SAVE_IP,
96 SAVE_STEAMID
97}
98
99enum _:SaveMethods
100{
101 SAVE_NVAULT,
102 SAVE_MYSQL
103}
104
105enum _:Sections
106{
107 SECTION_NONE,
108 SECTION_SETTINGS,
109 SECTION_RANKS,
110 SECTION_XP_REWARDS
111}
112
113enum _:PlayerData
114{
115 XP,
116 Level,
117 NextXP,
118 Rank[CRXRANKS_MAX_RANK_LENGTH],
119 NextRank[CRXRANKS_MAX_RANK_LENGTH],
120 HUDInfo[CRXRANKS_MAX_HUDINFO_LENGTH],
121 bool:HudInfoEnabled,
122 bool:IsOnFinalLevel,
123 bool:IsVIP,
124 bool:IsBot
125}
126
127enum _:Settings
128{
129 SAVE_TYPE,
130 bool:USE_MYSQL,
131 SQL_HOST[MAX_NAME_LENGTH],
132 SQL_USER[MAX_NAME_LENGTH],
133 SQL_PASSWORD[MAX_NAME_LENGTH],
134 SQL_DATABASE[MAX_NAME_LENGTH],
135 SQL_TABLE[MAX_NAME_LENGTH],
136 LEVELUP_MESSAGE_TYPE,
137 LEVELUP_SOUND[MAX_SOUND_LENGTH],
138 bool:LEVELUP_SCREEN_FADE_ENABLED,
139 LEVELUP_SCREEN_FADE_COLOR[4],
140 LEVELDN_SOUND[MAX_SOUND_LENGTH],
141 bool:LEVELDN_SCREEN_FADE_ENABLED,
142 LEVELDN_SCREEN_FADE_COLOR[4],
143 FINAL_LEVEL_FLAGS[MAX_NAME_LENGTH],
144 FINAL_LEVEL_FLAGS_BIT,
145 VIP_FLAGS[MAX_NAME_LENGTH],
146 VIP_FLAGS_BIT,
147 VAULT_NAME[MAX_NAME_LENGTH],
148 TEAM_LOCK,
149 MINIMUM_PLAYERS,
150 bool:IGNORE_BOTS,
151 bool:USE_COMBINED_EVENTS,
152 bool:NOTIFY_ON_KILL,
153 bool:HUDINFO_ENABLED,
154 bool:HUDINFO_ALIVE_ONLY,
155 bool:HUDINFO_TEAM_LOCK,
156 bool:HUDINFO_OTHER_PLAYERS,
157 HUDINFO_COLOR[3],
158 Float:HUDINFO_POSITION[2],
159 Float:HUDINFO_POSITION_DEAD[2],
160 bool:HUDINFO_USE_DHUD,
161 HUDINFO_FORMAT[CRXRANKS_MAX_HUDINFO_LENGTH],
162 HUDINFO_FORMAT_FINAL[CRXRANKS_MAX_HUDINFO_LENGTH],
163 HUDINFO_INVALID_TEXT[MAX_NAME_LENGTH],
164 bool:XP_NOTIFIER_ENABLED,
165 XP_NOTIFIER_COLOR_GET[3],
166 XP_NOTIFIER_COLOR_LOSE[3],
167 Float:XP_NOTIFIER_POSITION[2],
168 Float:XP_NOTIFIER_DURATION,
169 bool:XP_NOTIFIER_USE_DHUD
170}
171
172new g_eSettings[Settings]
173new g_ePlayerData[MAX_PLAYERS + 1][PlayerData]
174new g_szMaxLevels[CRXRANKS_MAX_XP_LENGTH]
175new g_szSqlError[MAX_SQL_LENGTH]
176new Handle:g_iSqlTuple
177new Array:g_aLevels
178new Array:g_aRankNames
179new Trie:g_tSettings
180new Trie:g_tXPRewards
181new Trie:g_tXPRewardsVIP
182new bool:g_bIsCstrike
183
184new g_iVault
185new g_iMaxLevels
186new g_iFlagZ
187new g_iScreenFade
188new g_iObject[2]
189
190new g_fwdUserLevelUpdated
191new g_fwdUserReceiveXP
192new g_fwdUserXPUpdated
193
194public plugin_init()
195{
196 register_plugin("OciXCrom's Rank System", PLUGIN_VERSION, "OciXCrom")
197 register_cvar("CRXRankSystem", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)
198
199 register_dictionary(g_bIsCstrike ? "RankSystem.txt" : "RankSystemNoColors.txt")
200
201 register_event("DeathMsg", "OnPlayerKilled", "a")
202
203 register_clcmd("say /xplist", "Cmd_XPList", ADMIN_BAN)
204 register_clcmd("say_team /xplist", "Cmd_XPList", ADMIN_BAN)
205 register_clcmd("say /hudinfo", "Cmd_HudInfo", ADMIN_ALL)
206 register_clcmd("say_team /hudinfo", "Cmd_HudInfo", ADMIN_ALL)
207 register_concmd("crxranks_give_xp", "Cmd_GiveXP", ADMIN_RCON, "<nick|#userid> <amount>")
208 register_concmd("crxranks_reset_xp", "Cmd_ResetXP", ADMIN_RCON, "<nick|#userid>")
209 register_srvcmd("crxranks_update_mysql", "Cmd_UpdateMySQL")
210
211 if(g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] || g_eSettings[LEVELDN_SCREEN_FADE_ENABLED])
212 {
213 g_iScreenFade = get_user_msgid("ScreenFade")
214 }
215
216 g_fwdUserLevelUpdated = CreateMultiForward("crxranks_user_level_updated", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
217 g_fwdUserReceiveXP = CreateMultiForward("crxranks_user_receive_xp", ET_STOP, FP_CELL, FP_CELL, FP_CELL)
218 g_fwdUserXPUpdated = CreateMultiForward("crxranks_user_xp_updated", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
219
220 if(g_eSettings[USE_MYSQL])
221 {
222 g_iSqlTuple = SQL_MakeDbTuple(g_eSettings[SQL_HOST], g_eSettings[SQL_USER], g_eSettings[SQL_PASSWORD], g_eSettings[SQL_DATABASE])
223
224 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
225
226 if(iSqlConnection == Empty_Handle)
227 {
228 log_amx(g_szSqlError)
229 switch_to_nvault()
230 goto @AFTER_MYSQL
231 }
232
233 new Handle:iQueries = SQL_PrepareQuery(iSqlConnection,\
234 "CREATE TABLE IF NOT EXISTS `%s` (`Player` VARCHAR(%i) NOT NULL, `XP` INT(%i) NOT NULL, `Level` INT(%i) NOT NULL,\
235 `Next XP` INT(%i) NOT NULL, `Rank` VARCHAR(%i) NOT NULL, `Next Rank` VARCHAR(%i) NOT NULL, PRIMARY KEY(Player));",\
236 g_eSettings[SQL_TABLE], MAX_SQL_PLAYER_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH,\
237 MAX_SQL_RANK_LENGTH, MAX_SQL_RANK_LENGTH)
238
239 if(!SQL_Execute(iQueries))
240 {
241 SQL_QueryError(iQueries, g_szSqlError, charsmax(g_szSqlError))
242 log_amx(g_szSqlError)
243 switch_to_nvault()
244 goto @AFTER_MYSQL
245 }
246
247 SQL_FreeHandle(iQueries)
248 SQL_FreeHandle(iSqlConnection)
249 }
250
251 @AFTER_MYSQL:
252
253 if(!g_eSettings[USE_MYSQL])
254 {
255 g_iVault = nvault_open(g_eSettings[VAULT_NAME])
256 }
257}
258
259public plugin_precache()
260{
261 new szModname[MAX_NAME_LENGTH]
262 get_modname(szModname, charsmax(szModname))
263
264 if(equal(szModname, "cstrike"))
265 {
266 g_bIsCstrike = true
267 }
268
269 g_aLevels = ArrayCreate(16)
270 ArrayPushCell(g_aLevels, 0)
271
272 g_aRankNames = ArrayCreate(MAX_NAME_LENGTH)
273 ArrayPushString(g_aRankNames, "")
274
275 g_tSettings = TrieCreate()
276 g_tXPRewards = TrieCreate()
277 g_tXPRewardsVIP = TrieCreate()
278
279 ReadFile()
280}
281
282public plugin_end()
283{
284 ArrayDestroy(g_aLevels)
285 ArrayDestroy(g_aRankNames)
286 TrieDestroy(g_tSettings)
287 TrieDestroy(g_tXPRewards)
288 TrieDestroy(g_tXPRewardsVIP)
289 DestroyForward(g_fwdUserLevelUpdated)
290
291 if(!g_eSettings[USE_MYSQL])
292 {
293 nvault_close(g_iVault)
294 }
295}
296
297ReadFile()
298{
299 new szFilename[256]
300 get_configsdir(szFilename, charsmax(szFilename))
301 add(szFilename, charsmax(szFilename), "/RankSystem.ini")
302
303 new iFilePointer = fopen(szFilename, "rt")
304
305 if(iFilePointer)
306 {
307 new szData[CRXRANKS_MAX_HUDINFO_LENGTH + MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], szMap[MAX_NAME_LENGTH], szKey[MAX_NAME_LENGTH]
308 new szTemp[4][5], bool:bRead = true, bool:bHasDeadPosition, i, iSize, iSection = SECTION_NONE
309 get_mapname(szMap, charsmax(szMap))
310
311 while(!feof(iFilePointer))
312 {
313 fgets(iFilePointer, szData, charsmax(szData))
314 trim(szData)
315
316 switch(szData[0])
317 {
318 case EOS, '#', ';': continue
319 case '-':
320 {
321 iSize = strlen(szData)
322
323 if(szData[iSize - 1] == '-')
324 {
325 szData[0] = ' '
326 szData[iSize - 1] = ' '
327 trim(szData)
328
329 if(contain(szData, "*") != -1)
330 {
331 strtok(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '*')
332 copy(szValue, strlen(szKey), szMap)
333 bRead = equal(szValue, szKey) ? true : false
334 }
335 else
336 {
337 static const szAll[] = "#all"
338 bRead = equal(szData, szAll) || equali(szData, szMap)
339 }
340 }
341 else continue
342 }
343 case '[':
344 {
345 iSize = strlen(szData)
346
347 if(szData[iSize - 1] == ']')
348 {
349 switch(szData[1])
350 {
351 case 'S', 's': iSection = SECTION_SETTINGS
352 case 'R', 'r': iSection = SECTION_RANKS
353 case 'X', 'x': iSection = SECTION_XP_REWARDS
354 default: iSection = SECTION_NONE
355 }
356 }
357 else continue
358 }
359 default:
360 {
361 if(!bRead || iSection == SECTION_NONE)
362 {
363 continue
364 }
365
366 strtok(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=')
367 trim(szKey); trim(szValue)
368
369 switch(iSection)
370 {
371 case SECTION_SETTINGS:
372 {
373 TrieSetString(g_tSettings, szKey, szValue)
374
375 if(equal(szKey, "CHAT_PREFIX"))
376 {
377 if(g_bIsCstrike)
378 {
379 CC_SetPrefix(szValue)
380 }
381 else
382 {
383 copy(CC_PREFIX, charsmax(CC_PREFIX), szValue)
384 }
385 }
386 else if(equal(szKey, "SAVE_TYPE"))
387 {
388 g_eSettings[SAVE_TYPE] = clamp(str_to_num(szValue), SAVE_NICKNAME, SAVE_STEAMID)
389 }
390 else if(equal(szKey, "USE_MYSQL"))
391 {
392 g_eSettings[USE_MYSQL] = _:clamp(str_to_num(szValue), false, true)
393 }
394 else if(equal(szKey, "SQL_HOST"))
395 {
396 copy(g_eSettings[SQL_HOST], charsmax(g_eSettings[SQL_HOST]), szValue)
397 }
398 else if(equal(szKey, "SQL_USER"))
399 {
400 copy(g_eSettings[SQL_USER], charsmax(g_eSettings[SQL_USER]), szValue)
401 }
402 else if(equal(szKey, "SQL_PASSWORD"))
403 {
404 copy(g_eSettings[SQL_PASSWORD], charsmax(g_eSettings[SQL_PASSWORD]), szValue)
405 }
406 else if(equal(szKey, "SQL_DATABASE"))
407 {
408 copy(g_eSettings[SQL_DATABASE], charsmax(g_eSettings[SQL_DATABASE]), szValue)
409 }
410 else if(equal(szKey, "SQL_TABLE"))
411 {
412 copy(g_eSettings[SQL_TABLE], charsmax(g_eSettings[SQL_TABLE]), szValue)
413 }
414 else if(equal(szKey, "XP_COMMANDS"))
415 {
416 while(szValue[0] != 0 && strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ','))
417 {
418 trim(szKey); trim(szValue)
419 register_clcmd(szKey, "Cmd_XP")
420 }
421 }
422 else if(equal(szKey, "LEVELUP_MESSAGE_TYPE"))
423 {
424 g_eSettings[LEVELUP_MESSAGE_TYPE] = clamp(str_to_num(szValue), 0, 2)
425 }
426 else if(equal(szKey, "LEVELUP_SOUND"))
427 {
428 copy(g_eSettings[LEVELUP_SOUND], charsmax(g_eSettings[LEVELUP_SOUND]), szValue)
429
430 if(szValue[0])
431 {
432 precache_sound_if_found(szValue)
433 }
434 }
435 else if(equal(szKey, "LEVELUP_SCREEN_FADE_ENABLED"))
436 {
437 g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), false, true)
438 }
439 else if(equal(szKey, "LEVELUP_SCREEN_FADE_COLOR"))
440 {
441 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))
442
443 for(i = 0; i < 4; i++)
444 {
445 g_eSettings[LEVELUP_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
446 }
447 }
448 else if(equal(szKey, "LEVELDN_SOUND"))
449 {
450 copy(g_eSettings[LEVELDN_SOUND], charsmax(g_eSettings[LEVELDN_SOUND]), szValue)
451
452 if(szValue[0])
453 {
454 precache_sound_if_found(szValue)
455 }
456 }
457 else if(equal(szKey, "LEVELDN_SCREEN_FADE_ENABLED"))
458 {
459 g_eSettings[LEVELDN_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), false, true)
460 }
461 else if(equal(szKey, "LEVELDN_SCREEN_FADE_COLOR"))
462 {
463 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))
464
465 for(i = 0; i < 4; i++)
466 {
467 g_eSettings[LEVELDN_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
468 }
469 }
470 else if(equal(szKey, "FINAL_LEVEL_FLAGS"))
471 {
472 copy(g_eSettings[FINAL_LEVEL_FLAGS], charsmax(g_eSettings[FINAL_LEVEL_FLAGS]), szValue)
473 g_eSettings[FINAL_LEVEL_FLAGS_BIT] = read_flags(szValue)
474 g_iFlagZ = read_flags("z")
475 }
476 else if(equal(szKey, "VIP_FLAGS"))
477 {
478 copy(g_eSettings[VIP_FLAGS], charsmax(g_eSettings[VIP_FLAGS]), szValue)
479 g_eSettings[VIP_FLAGS_BIT] = read_flags(szValue)
480 }
481 else if(equal(szKey, "VAULT_NAME"))
482 {
483 copy(g_eSettings[VAULT_NAME], charsmax(g_eSettings[VAULT_NAME]), szValue)
484 }
485 else if(equal(szKey, "TEAM_LOCK"))
486 {
487 g_eSettings[TEAM_LOCK] = str_to_num(szValue)
488 }
489 else if(equal(szKey, "MINIMUM_PLAYERS"))
490 {
491 g_eSettings[MINIMUM_PLAYERS] = clamp(str_to_num(szValue), 0, 32)
492 }
493 else if(equal(szKey, "IGNORE_BOTS"))
494 {
495 g_eSettings[IGNORE_BOTS] = _:clamp(str_to_num(szValue), false, true)
496 }
497 else if(equal(szKey, "USE_COMBINED_EVENTS"))
498 {
499 g_eSettings[USE_COMBINED_EVENTS] = _:clamp(str_to_num(szValue), false, true)
500 }
501 else if(equal(szKey, "NOTIFY_ON_KILL"))
502 {
503 g_eSettings[NOTIFY_ON_KILL] = _:clamp(str_to_num(szValue), false, true)
504 }
505 else if(equal(szKey, "HUDINFO_ENABLED"))
506 {
507 g_eSettings[HUDINFO_ENABLED] = _:clamp(str_to_num(szValue), false, true)
508 }
509 else if(equal(szKey, "HUDINFO_ALIVE_ONLY"))
510 {
511 g_eSettings[HUDINFO_ALIVE_ONLY] = _:clamp(str_to_num(szValue), false, true)
512 }
513 else if(equal(szKey, "HUDINFO_TEAM_LOCK"))
514 {
515 g_eSettings[HUDINFO_TEAM_LOCK] = _:clamp(str_to_num(szValue), false, true)
516 }
517 else if(equal(szKey, "HUDINFO_OTHER_PLAYERS"))
518 {
519 g_eSettings[HUDINFO_OTHER_PLAYERS] = _:clamp(str_to_num(szValue), false, true)
520 }
521 else if(equal(szKey, "HUDINFO_COLOR"))
522 {
523 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))
524
525 for(i = 0; i < 3; i++)
526 {
527 g_eSettings[HUDINFO_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
528 }
529 }
530 else if(equal(szKey, "HUDINFO_POSITION"))
531 {
532 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))
533
534 for(i = 0; i < 2; i++)
535 {
536 g_eSettings[HUDINFO_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
537 }
538 }
539 else if(equal(szKey, "HUDINFO_POSITION_DEAD"))
540 {
541 bHasDeadPosition = true
542 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))
543
544 for(i = 0; i < 2; i++)
545 {
546 g_eSettings[HUDINFO_POSITION_DEAD][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
547 }
548 }
549 else if(equal(szKey, "HUDINFO_USE_DHUD"))
550 {
551 g_eSettings[HUDINFO_USE_DHUD] = _:clamp(str_to_num(szValue), false, true)
552
553 if(!g_eSettings[HUDINFO_USE_DHUD])
554 {
555 g_iObject[OBJ_HUDINFO] = CreateHudSyncObj()
556 }
557 }
558 else if(equal(szKey, "HUDINFO_FORMAT"))
559 {
560 copy(g_eSettings[HUDINFO_FORMAT], charsmax(g_eSettings[HUDINFO_FORMAT]), szValue)
561 }
562 else if(equal(szKey, "HUDINFO_FORMAT_FINAL"))
563 {
564 copy(g_eSettings[HUDINFO_FORMAT_FINAL], charsmax(g_eSettings[HUDINFO_FORMAT_FINAL]), szValue)
565 }
566 else if(equal(szKey, "HUDINFO_INVALID_TEXT"))
567 {
568 copy(g_eSettings[HUDINFO_INVALID_TEXT], charsmax(g_eSettings[HUDINFO_INVALID_TEXT]), szValue)
569 }
570 else if(equal(szKey, "XP_NOTIFIER_ENABLED"))
571 {
572 g_eSettings[XP_NOTIFIER_ENABLED] = _:clamp(str_to_num(szValue), false, true)
573 }
574 else if(equal(szKey, "XP_NOTIFIER_COLOR_GET"))
575 {
576 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))
577
578 for(i = 0; i < 3; i++)
579 {
580 g_eSettings[XP_NOTIFIER_COLOR_GET][i] = clamp(str_to_num(szTemp[i]), -1, 255)
581 }
582 }
583 else if(equal(szKey, "XP_NOTIFIER_COLOR_LOSE"))
584 {
585 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))
586
587 for(i = 0; i < 3; i++)
588 {
589 g_eSettings[XP_NOTIFIER_COLOR_LOSE][i] = clamp(str_to_num(szTemp[i]), -1, 255)
590 }
591 }
592 else if(equal(szKey, "XP_NOTIFIER_POSITION"))
593 {
594 parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))
595
596 for(i = 0; i < 2; i++)
597 {
598 g_eSettings[XP_NOTIFIER_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
599 }
600 }
601 else if(equal(szKey, "XP_NOTIFIER_DURATION"))
602 {
603 g_eSettings[XP_NOTIFIER_DURATION] = _:floatclamp(str_to_float(szValue), 0.0, float(cellmax))
604 }
605 else if(equal(szKey, "XP_NOTIFIER_USE_DHUD"))
606 {
607 g_eSettings[XP_NOTIFIER_USE_DHUD] = _:clamp(str_to_num(szValue), false, true)
608
609 if(!g_eSettings[XP_NOTIFIER_USE_DHUD])
610 {
611 g_iObject[OBJ_XP_NOTIFIER] = CreateHudSyncObj()
612 }
613 }
614 }
615 case SECTION_RANKS:
616 {
617 ArrayPushCell(g_aLevels, g_iMaxLevels == 0 ? 0 : max(str_to_num(szValue), 0))
618 ArrayPushString(g_aRankNames, szKey)
619 g_iMaxLevels++
620 }
621 case SECTION_XP_REWARDS:
622 {
623 static szReward[2][16]
624 szReward[1][0] = EOS
625
626 parse(szValue, szReward[0], charsmax(szReward[]), szReward[1], charsmax(szReward[]))
627 TrieSetCell(g_tXPRewards, szKey, str_to_num(szReward[0]))
628
629 if(szReward[1][0])
630 {
631 TrieSetCell(g_tXPRewardsVIP, szKey, str_to_num(szReward[1]))
632 }
633 }
634 }
635 }
636 }
637 }
638
639 if(!bHasDeadPosition)
640 {
641 for(i = 0; i < 2; i++)
642 {
643 g_eSettings[HUDINFO_POSITION_DEAD][i] = _:g_eSettings[HUDINFO_POSITION][i]
644 }
645 }
646
647 num_to_str(g_iMaxLevels, g_szMaxLevels, charsmax(g_szMaxLevels))
648 fclose(iFilePointer)
649 }
650}
651
652public client_connect(id)
653{
654 reset_player_stats(id)
655
656 new szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
657 get_user_saveinfo(id, szInfo, charsmax(szInfo))
658 save_or_load(id, szInfo, SL_LOAD_DATA)
659
660 g_ePlayerData[id][IsBot] = is_user_bot(id) != 0
661 set_task(DELAY_ON_CONNECT, "update_vip_status", id)
662
663 if(g_eSettings[HUDINFO_ENABLED])
664 {
665 set_task(HUD_REFRESH_FREQ, "DisplayHUD", id + TASK_HUD, .flags = "b")
666 }
667}
668
669public client_disconnected(id)
670{
671 new szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
672 get_user_saveinfo(id, szInfo, charsmax(szInfo))
673 save_or_load(id, szInfo, SL_SAVE_DATA)
674 remove_task(id + TASK_HUD)
675}
676
677public client_infochanged(id)
678{
679 if(!is_user_connected(id))
680 {
681 return
682 }
683
684 static const szKey[] = "name"
685
686 new szNewName[MAX_NAME_LENGTH], szOldName[MAX_NAME_LENGTH]
687 get_user_info(id, szKey, szNewName, charsmax(szNewName))
688 get_user_name(id, szOldName, charsmax(szOldName))
689
690 if(!equal(szNewName, szOldName))
691 {
692 if(g_eSettings[SAVE_TYPE] == SAVE_NICKNAME)
693 {
694 save_or_load(id, szOldName, SL_SAVE_DATA)
695
696 if(g_eSettings[USE_MYSQL])
697 {
698 reset_player_stats(id)
699 set_task(DELAY_ON_CHANGE, "load_after_change", id)
700 }
701 else
702 {
703 save_or_load(id, szNewName, SL_LOAD_DATA)
704 update_hudinfo(id)
705 }
706 }
707
708 set_task(DELAY_ON_CHANGE, "update_vip_status", id)
709 }
710}
711
712public load_after_change(id)
713{
714 new szName[MAX_NAME_LENGTH]
715 get_user_name(id, szName, charsmax(szName))
716 save_or_load(id, szName, SL_LOAD_DATA)
717 update_hudinfo(id)
718}
719
720public DisplayHUD(id)
721{
722 id -= TASK_HUD
723
724 if(!g_ePlayerData[id][HudInfoEnabled])
725 {
726 return
727 }
728
729 new bool:bIsAlive, iTarget
730
731 bIsAlive = is_user_alive(id) != 0
732 iTarget = id
733
734 if(!bIsAlive)
735 {
736 if(g_eSettings[HUDINFO_ALIVE_ONLY])
737 {
738 return
739 }
740
741 if(g_eSettings[HUDINFO_OTHER_PLAYERS])
742 {
743 iTarget = pev(id, pev_iuser2)
744 }
745 }
746
747 if(!iTarget)
748 {
749 return
750 }
751
752 if(g_eSettings[TEAM_LOCK] && g_eSettings[HUDINFO_TEAM_LOCK] && get_user_team(iTarget) != g_eSettings[TEAM_LOCK])
753 {
754 return
755 }
756
757 if(g_eSettings[HUDINFO_USE_DHUD])
758 {
759 if(bIsAlive)
760 {
761 set_dhudmessage(HUDINFO_PARAMS)
762 }
763 else
764 {
765 set_dhudmessage(HUDINFO_PARAMS_DEAD)
766 }
767
768 show_dhudmessage(id, g_ePlayerData[iTarget][HUDInfo])
769 }
770 else
771 {
772 if(bIsAlive)
773 {
774 set_hudmessage(HUDINFO_PARAMS)
775 }
776 else
777 {
778 set_hudmessage(HUDINFO_PARAMS_DEAD)
779 }
780
781 ShowSyncHudMsg(id, g_iObject[OBJ_HUDINFO], g_ePlayerData[iTarget][HUDInfo])
782 }
783}
784
785public bomb_planted(id)
786{
787 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_PLANTED), CRXRANKS_XPS_REWARD)
788}
789
790public bomb_defused(id)
791{
792 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_DEFUSED), CRXRANKS_XPS_REWARD)
793}
794
795public bomb_explode(id)
796{
797 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_EXPLODED), CRXRANKS_XPS_REWARD)
798}
799
800public Cmd_XP(id)
801{
802 if(g_ePlayerData[id][Level] == g_iMaxLevels)
803 {
804 send_chat_message(id, false, "%L", id, "CRXRANKS_RANKINFO_FINAL", g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
805 }
806 else
807 {
808 send_chat_message(id, false, "%L", id, "CRXRANKS_RANKINFO_NORMAL", g_ePlayerData[id][XP], g_ePlayerData[id][NextXP],\
809 g_ePlayerData[id][Level], g_ePlayerData[id][Rank], g_ePlayerData[id][NextRank])
810 }
811
812 return PLUGIN_HANDLED
813}
814
815public Cmd_XPList(id, iLevel, iCid)
816{
817 if(!cmd_access(id, iLevel, iCid, 1))
818 {
819 return PLUGIN_HANDLED
820 }
821
822 new szTitle[128]
823 formatex(szTitle, charsmax(szTitle), "%L", id, "CRXRANKS_MENU_TITLE")
824
825 new iPlayers[MAX_PLAYERS], iPnum, iMenu = menu_create(szTitle, "XPList_Handler")
826 get_players(iPlayers, iPnum); SortCustom1D(iPlayers, iPnum, "sort_players_by_xp")
827
828 for(new szItem[128], szName[MAX_NAME_LENGTH], iPlayer, i; i < iPnum; i++)
829 {
830 iPlayer = iPlayers[i]
831 get_user_name(iPlayer, szName, charsmax(szName))
832 formatex(szItem, charsmax(szItem), "%L", id, "CRXRANKS_ITEM_FORMAT", g_ePlayerData[iPlayer][XP], szName, g_ePlayerData[iPlayer][Level], g_ePlayerData[iPlayer][Rank])
833 menu_additem(iMenu, szItem)
834 }
835
836 menu_display(id, iMenu)
837 return PLUGIN_HANDLED
838}
839
840public Cmd_HudInfo(id, iLevel, iCid)
841{
842 if(!cmd_access(id, iLevel, iCid, 1))
843 {
844 return PLUGIN_HANDLED
845 }
846
847 if(!g_eSettings[HUDINFO_ENABLED])
848 {
849 send_chat_message(id, false, "%L", id, "CRXRANKS_HUDINFO_UNAVAILABLE")
850 return PLUGIN_HANDLED
851 }
852
853 g_ePlayerData[id][HudInfoEnabled] = !g_ePlayerData[id][HudInfoEnabled]
854 send_chat_message(id, false, "%L", id, g_ePlayerData[id][HudInfoEnabled] ? "CRXRANKS_HUDINFO_ENABLED" : "CRXRANKS_HUDINFO_DISABLED")
855 return PLUGIN_HANDLED
856}
857
858public XPList_Handler(id, iMenu, iItem)
859{
860 menu_destroy(iMenu)
861 return PLUGIN_HANDLED
862}
863
864public Cmd_GiveXP(id, iLevel, iCid)
865{
866 if(!cmd_access(id, iLevel, iCid, 3))
867 {
868 return PLUGIN_HANDLED
869 }
870
871 new szPlayer[MAX_NAME_LENGTH]
872 read_argv(1, szPlayer, charsmax(szPlayer))
873
874 new iPlayer = cmd_target(id, szPlayer, 0)
875
876 if(!iPlayer)
877 {
878 return PLUGIN_HANDLED
879 }
880
881 new szName[2][MAX_NAME_LENGTH], szAmount[CRXRANKS_MAX_XP_LENGTH]
882 read_argv(2, szAmount, charsmax(szAmount))
883 get_user_name(id, szName[0], charsmax(szName[]))
884 get_user_name(iPlayer, szName[1], charsmax(szName[]))
885
886 new szKey[MAX_NAME_LENGTH], iXP = str_to_num(szAmount)
887 give_user_xp(iPlayer, iXP, CRXRANKS_XPS_ADMIN)
888
889 if(iXP >= 0)
890 {
891 copy(szKey, charsmax(szKey), "CRXRANKS_GIVE_XP")
892 }
893 else
894 {
895 copy(szKey, charsmax(szKey), "CRXRANKS_TAKE_XP")
896 iXP *= -1
897 }
898
899 send_chat_message(0, true, "%L", id, szKey, szName[0], iXP, szName[1])
900 return PLUGIN_HANDLED
901}
902
903public Cmd_ResetXP(id, iLevel, iCid)
904{
905 if(!cmd_access(id, iLevel, iCid, 2))
906 {
907 return PLUGIN_HANDLED
908 }
909
910 new szPlayer[MAX_NAME_LENGTH]
911 read_argv(1, szPlayer, charsmax(szPlayer))
912
913 new iPlayer = cmd_target(id, szPlayer, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF)
914
915 if(!iPlayer)
916 {
917 return PLUGIN_HANDLED
918 }
919
920 new szName[2][MAX_NAME_LENGTH]
921 get_user_name(id, szName[0], charsmax(szName[]))
922 get_user_name(iPlayer, szName[1], charsmax(szName[]))
923
924 g_ePlayerData[iPlayer][XP] = 0
925 check_level(iPlayer, true)
926 send_chat_message(0, true, "%L", id, "CRXRANKS_RESET_XP", szName[0], szName[1])
927
928 return PLUGIN_HANDLED
929}
930
931// This command is here because the update from v3.0 to v3.1 changed the way data is stored in MySQL.
932// Because of that, a new table is required and this command is here to transfer the data from the old one.
933// The command will be removed in future versions, so I decided not to translate the strings used in it.
934public Cmd_UpdateMySQL()
935{
936 static bUsed
937
938 if(bUsed)
939 {
940 server_print("The MySQL table has already been updated to version v3.1. There's no point in doing this again.")
941 return PLUGIN_HANDLED
942 }
943
944 if(!g_eSettings[USE_MYSQL])
945 {
946 server_print("The plugin isn't using MySQL at the moment. Please enable the feature before using this command.")
947 return PLUGIN_HANDLED
948 }
949
950 new szTable[MAX_NAME_LENGTH]
951 read_argv(1, szTable, charsmax(szTable))
952
953 if(!szTable[0])
954 {
955 server_print("Plese provide the name of the previous table in order to transfer data to the current one.")
956 return PLUGIN_HANDLED
957 }
958
959 new szQuery[MAX_NAME_LENGTH * 2]
960 formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s`;", szTable)
961 SQL_ThreadQuery(g_iSqlTuple, "QueryUpdateMySQL", szQuery)
962
963 bUsed = true
964 return PLUGIN_HANDLED
965}
966
967public QueryUpdateMySQL(iFailState, Handle:iQuery, szError[], iErrorCode)
968{
969 if(iFailState == TQUERY_CONNECT_FAILED || iFailState == TQUERY_QUERY_FAILED)
970 {
971 server_print(szError)
972 return
973 }
974
975 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
976
977 if(iSqlConnection == Empty_Handle)
978 {
979 server_print(g_szSqlError)
980 return
981 }
982
983 new Handle:iQuery2, szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szInfo[MAX_SQL_PLAYER_LENGTH], iCounter, iPlayer, iXP
984 new szColumnPlayer = SQL_FieldNameToNum(iQuery, "User")
985 new szColumnXP = SQL_FieldNameToNum(iQuery, "XP")
986
987 while(SQL_MoreResults(iQuery))
988 {
989 SQL_ReadResult(iQuery, szColumnPlayer, szInfo, charsmax(szInfo))
990 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
991 iQuery2 = SQL_PrepareQuery(iSqlConnection, "SELECT * FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
992
993 if(!SQL_Execute(iQuery2))
994 {
995 SQL_QueryError(iQuery2, g_szSqlError, charsmax(g_szSqlError))
996 server_print(g_szSqlError)
997 return
998 }
999
1000 iXP = SQL_ReadResult(iQuery, szColumnXP)
1001
1002 if(SQL_NumResults(iQuery2) > 0)
1003 {
1004 formatex(szQuery, charsmax(szQuery), "UPDATE `%s` SET `XP`='%i' WHERE `Player`='%s';", g_eSettings[SQL_TABLE], iXP, szPlayer)
1005 }
1006 else
1007 {
1008 formatex(szQuery, charsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','%i','1','0','n/a','n/a');", g_eSettings[SQL_TABLE], szPlayer, iXP)
1009 }
1010
1011 switch(g_eSettings[SAVE_TYPE])
1012 {
1013 case CRXRANKS_ST_NICKNAME: iPlayer = find_player("a", szInfo)
1014 case CRXRANKS_ST_STEAMID: iPlayer = find_player("c", szInfo)
1015 case CRXRANKS_ST_IP: iPlayer = find_player("d", szInfo)
1016 }
1017
1018 if(iPlayer)
1019 {
1020 g_ePlayerData[iPlayer][XP] = iXP
1021 check_level(iPlayer, true)
1022 }
1023
1024 SQL_ThreadQuery(g_iSqlTuple, "QueryHandler", szQuery)
1025 SQL_NextRow(iQuery)
1026 iCounter++
1027 }
1028
1029 SQL_FreeHandle(iQuery2)
1030 SQL_FreeHandle(iSqlConnection)
1031}
1032
1033public OnPlayerKilled()
1034{
1035 new szWeapon[16], iAttacker = read_data(1), iVictim = read_data(2), iXP
1036 read_data(4, szWeapon, charsmax(szWeapon))
1037
1038 if(!is_user_connected(iVictim))
1039 {
1040 return
1041 }
1042
1043 if(iAttacker == iVictim || equal(szWeapon, "worldspawn") || equal(szWeapon, "door", 4) || equal(szWeapon, "trigger_hurt"))
1044 {
1045 iXP = get_xp_reward(iVictim, XPREWARD_SUICIDE)
1046
1047 if(g_eSettings[USE_COMBINED_EVENTS])
1048 {
1049 iXP += get_xp_reward(iVictim, XPREWARD_DEATH)
1050 }
1051
1052 give_user_xp(iVictim, iXP, CRXRANKS_XPS_REWARD)
1053
1054 if(should_send_kill_message(iXP))
1055 {
1056 send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_SUICIDE_GET" : "CRXRANKS_NOTIFY_SUICIDE_LOSE", abs(iXP))
1057 }
1058
1059 return
1060 }
1061
1062 if(!is_user_connected(iAttacker))
1063 {
1064 return
1065 }
1066
1067 new iReward, iTemp
1068
1069 if(iAttacker == iVictim)
1070 {
1071 iTemp = get_xp_reward(iAttacker, XPREWARD_SUICIDE)
1072 iReward += iTemp
1073
1074 if(should_skip(iTemp))
1075 {
1076 goto @GIVE_REWARD
1077 }
1078 }
1079 else if(get_user_team(iAttacker) == get_user_team(iVictim))
1080 {
1081 iTemp = get_xp_reward(iAttacker, XPREWARD_TEAMKILL)
1082 iReward += iTemp
1083
1084 if(should_skip(iTemp))
1085 {
1086 goto @GIVE_REWARD
1087 }
1088 }
1089 else
1090 {
1091 iTemp = get_xp_reward(iAttacker, szWeapon)
1092 iReward += iTemp
1093
1094 if(should_skip(iTemp))
1095 {
1096 goto @GIVE_REWARD
1097 }
1098
1099 if(read_data(3))
1100 {
1101 iTemp = get_xp_reward(iAttacker, XPREWARD_HEADSHOT)
1102 iReward += iTemp
1103
1104 if(should_skip(iTemp))
1105 {
1106 goto @GIVE_REWARD
1107 }
1108 }
1109
1110 iReward += get_xp_reward(iAttacker, XPREWARD_KILL)
1111 }
1112
1113 @GIVE_REWARD:
1114 iXP = give_user_xp(iAttacker, iReward, CRXRANKS_XPS_REWARD)
1115
1116 if(should_send_kill_message(iXP))
1117 {
1118 new szName[MAX_NAME_LENGTH]
1119 get_user_name(iVictim, szName, charsmax(szName))
1120 send_chat_message(iAttacker, false, "%L", iAttacker, iXP > 0 ? "CRXRANKS_NOTIFY_KILL_GET" : "CRXRANKS_NOTIFY_KILL_LOSE", abs(iXP), szName)
1121 }
1122
1123 iXP = give_user_xp(iVictim, get_xp_reward(iVictim, XPREWARD_DEATH), CRXRANKS_XPS_REWARD)
1124
1125 if(should_send_kill_message(iXP))
1126 {
1127 send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_DEATH_GET" : "CRXRANKS_NOTIFY_DEATH_LOSE", abs(iXP))
1128 }
1129}
1130
1131public sort_players_by_xp(id1, id2)
1132{
1133 if(g_ePlayerData[id1][XP] > g_ePlayerData[id2][XP])
1134 {
1135 return -1
1136 }
1137 else if(g_ePlayerData[id1][XP] < g_ePlayerData[id2][XP])
1138 {
1139 return 1
1140 }
1141
1142 return 0
1143}
1144
1145public QueryHandler(iFailState, Handle:iQuery, szError[], iErrorCode)
1146{
1147 switch(iFailState)
1148 {
1149 case TQUERY_CONNECT_FAILED: log_amx("[SQL Error] Connection failed (%i): %s", iErrorCode, szError)
1150 case TQUERY_QUERY_FAILED: log_amx("[SQL Error] Query failed (%i): %s", iErrorCode, szError)
1151 }
1152}
1153
1154save_or_load(const id, const szInfo[], const iType)
1155{
1156 if(!szInfo[0])
1157 {
1158 return
1159 }
1160
1161 switch(iType)
1162 {
1163 case SL_SAVE_DATA:
1164 {
1165 if(g_eSettings[USE_MYSQL])
1166 {
1167 new szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szRank[MAX_SQL_RANK_LENGTH], szNextRank[MAX_SQL_RANK_LENGTH]
1168 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1169
1170 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
1171 SQL_QuoteString(iSqlConnection, szRank, charsmax(szRank), g_ePlayerData[id][Rank])
1172 SQL_QuoteString(iSqlConnection, szNextRank, charsmax(szNextRank), g_ePlayerData[id][NextRank])
1173
1174 SQL_FreeHandle(iSqlConnection)
1175
1176 formatex(szQuery, charsmax(szQuery), "UPDATE `%s` SET `XP`='%i',`Level`='%i',`Next XP`='%i',`Rank`='%s',`Next Rank`='%s' WHERE `Player`='%s';",\
1177 g_eSettings[SQL_TABLE], g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][NextXP], szRank, szNextRank, szPlayer)
1178 SQL_ThreadQuery(g_iSqlTuple, "QueryHandler", szQuery)
1179 }
1180 else
1181 {
1182 new szData[CRXRANKS_MAX_XP_LENGTH]
1183 num_to_str(g_ePlayerData[id][XP], szData, charsmax(szData))
1184 nvault_set(g_iVault, szInfo, szData)
1185 }
1186 }
1187 case SL_LOAD_DATA:
1188 {
1189 if(g_eSettings[USE_MYSQL])
1190 {
1191 new szPlayer[MAX_SQL_PLAYER_LENGTH], iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1192 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
1193
1194 if(iSqlConnection == Empty_Handle)
1195 {
1196 log_amx(g_szSqlError)
1197 return
1198 }
1199
1200 new Handle:iQuery = SQL_PrepareQuery(iSqlConnection, "SELECT * FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
1201
1202 if(!SQL_Execute(iQuery))
1203 {
1204 SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
1205 log_amx(g_szSqlError)
1206 return
1207 }
1208
1209 prepare_player(id, szPlayer, SQL_NumResults(iQuery) > 0 ? false : true)
1210 SQL_FreeHandle(iQuery)
1211 SQL_FreeHandle(iSqlConnection)
1212 }
1213 else
1214 {
1215 new iData = nvault_get(g_iVault, szInfo)
1216 g_ePlayerData[id][XP] = iData ? clamp(iData, 0) : 0
1217 check_level(id, false)
1218 }
1219 }
1220 }
1221}
1222
1223prepare_player(id, const szPlayer[], bool:bNewPlayer)
1224{
1225 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1226
1227 if(iSqlConnection == Empty_Handle)
1228 {
1229 log_amx(g_szSqlError)
1230 return
1231 }
1232
1233 new szQuery[MAX_QUERY_LENGTH]
1234
1235 if(bNewPlayer)
1236 {
1237 formatex(szQuery, charsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','0','1','0','n/a','n/a');", g_eSettings[SQL_TABLE], szPlayer)
1238 }
1239 else
1240 {
1241 formatex(szQuery, charsmax(szQuery), "SELECT XP FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
1242 }
1243
1244 new Handle:iQuery = SQL_PrepareQuery(iSqlConnection, szQuery)
1245
1246 if(!SQL_Execute(iQuery))
1247 {
1248 SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
1249 log_amx(g_szSqlError)
1250 }
1251
1252 if(!bNewPlayer)
1253 {
1254 if(SQL_NumResults(iQuery) > 0)
1255 {
1256 g_ePlayerData[id][XP] = SQL_ReadResult(iQuery, 0)
1257 }
1258 }
1259
1260 check_level(id, false)
1261
1262 SQL_FreeHandle(iQuery)
1263 SQL_FreeHandle(iSqlConnection)
1264}
1265
1266get_xp_reward(const id, const szKey[])
1267{
1268 new iReward
1269
1270 if(g_ePlayerData[id][IsVIP])
1271 {
1272 if(TrieKeyExists(g_tXPRewardsVIP, szKey))
1273 {
1274 TrieGetCell(g_tXPRewardsVIP, szKey, iReward)
1275 return iReward
1276 }
1277 }
1278
1279 if(TrieKeyExists(g_tXPRewards, szKey))
1280 {
1281 TrieGetCell(g_tXPRewards, szKey, iReward)
1282 return iReward
1283 }
1284
1285 return 0
1286}
1287
1288give_user_xp(const id, iXP, CRXRanks_XPSources:iSource = CRXRANKS_XPS_PLUGIN)
1289{
1290 if(!iXP)
1291 {
1292 return 0
1293 }
1294
1295 if(g_eSettings[IGNORE_BOTS] && g_ePlayerData[id][IsBot])
1296 {
1297 return 0
1298 }
1299
1300 if(iSource == CRXRANKS_XPS_REWARD)
1301 {
1302 if(g_eSettings[MINIMUM_PLAYERS] && get_playersnum() < g_eSettings[MINIMUM_PLAYERS])
1303 {
1304 return 0
1305 }
1306
1307 if(g_eSettings[TEAM_LOCK] && get_user_team(id) != g_eSettings[TEAM_LOCK])
1308 {
1309 return 0
1310 }
1311 }
1312
1313 new iReturn
1314 ExecuteForward(g_fwdUserReceiveXP, iReturn, id, iXP, iSource)
1315
1316 switch(iReturn)
1317 {
1318 case CRXRANKS_HANDLED: return 0
1319 case CRXRANKS_CONTINUE: { }
1320 default:
1321 {
1322 if(iReturn != 0)
1323 {
1324 iXP = iReturn
1325 }
1326 }
1327 }
1328
1329 g_ePlayerData[id][XP] += iXP
1330
1331 if(g_ePlayerData[id][XP] < 0)
1332 {
1333 g_ePlayerData[id][XP] = 0
1334 }
1335
1336 check_level(id, true)
1337 ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)
1338
1339 if(g_eSettings[XP_NOTIFIER_ENABLED])
1340 {
1341 new szKey[MAX_NAME_LENGTH], bool:bPositive
1342 bPositive = iXP >= 0
1343
1344 copy(szKey, charsmax(szKey), bPositive ? "CRXRANKS_XP_NOTIFIER_GET" : "CRXRANKS_XP_NOTIFIER_LOSE")
1345
1346 if(g_eSettings[XP_NOTIFIER_USE_DHUD])
1347 {
1348 if(bPositive)
1349 {
1350 set_dhudmessage(XP_NOTIFIER_PARAMS_GET)
1351 }
1352 else
1353 {
1354 set_dhudmessage(XP_NOTIFIER_PARAMS_LOSE)
1355 }
1356
1357 show_dhudmessage(id, "%L", id, szKey, abs(iXP))
1358 }
1359 else
1360 {
1361 if(bPositive)
1362 {
1363 set_hudmessage(XP_NOTIFIER_PARAMS_GET)
1364 }
1365 else
1366 {
1367 set_hudmessage(XP_NOTIFIER_PARAMS_LOSE)
1368 }
1369
1370 ShowSyncHudMsg(id, g_iObject[OBJ_XP_NOTIFIER], "%L", id, szKey, abs(iXP))
1371 }
1372 }
1373
1374 return iXP
1375}
1376
1377get_user_saveinfo(const id, szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH], const iLen)
1378{
1379 switch(g_eSettings[SAVE_TYPE])
1380 {
1381 case SAVE_NICKNAME: get_user_name(id, szInfo, iLen)
1382 case SAVE_IP: get_user_ip(id, szInfo, iLen, 1)
1383 case SAVE_STEAMID: get_user_authid(id, szInfo, iLen)
1384 }
1385}
1386
1387precache_sound_if_found(const szValue[])
1388{
1389 new szSound[MAX_SOUND_LENGTH]
1390 format(szSound, charsmax(szSound), "sound/%s", szValue)
1391
1392 if(file_exists(szSound))
1393 {
1394 precache_sound(szValue)
1395 }
1396 else
1397 {
1398 log_amx("ERROR: sound file ^"%s^" not found", szValue)
1399 }
1400}
1401
1402reset_player_stats(const id)
1403{
1404 g_ePlayerData[id][XP] = 0
1405 g_ePlayerData[id][Level] = 0
1406 g_ePlayerData[id][NextXP] = 0
1407 g_ePlayerData[id][Rank][0] = EOS
1408 g_ePlayerData[id][NextRank][0] = EOS
1409 g_ePlayerData[id][HUDInfo][0] = EOS
1410 g_ePlayerData[id][HudInfoEnabled] = true
1411 g_ePlayerData[id][IsOnFinalLevel] = false
1412 g_ePlayerData[id][IsVIP] = false
1413 g_ePlayerData[id][IsBot] = false
1414}
1415
1416switch_to_nvault()
1417{
1418 if(g_eSettings[USE_MYSQL])
1419 {
1420 g_eSettings[USE_MYSQL] = false
1421 log_amx("%L", LANG_SERVER, "CRXRANKS_MYSQL_FAILED")
1422 }
1423}
1424
1425bool:has_argument(const szMessage[], const szArg[])
1426{
1427 return contain(szMessage, szArg) != -1
1428}
1429
1430bool:should_skip(const iNum)
1431{
1432 return (iNum != 0 && !g_eSettings[USE_COMBINED_EVENTS])
1433}
1434
1435bool:should_send_kill_message(const iXP)
1436{
1437 return (g_eSettings[NOTIFY_ON_KILL] && iXP != 0)
1438}
1439
1440send_chat_message(const id, const bool:bLog, const szInput[], any:...)
1441{
1442 new szMessage[192]
1443 vformat(szMessage, charsmax(szMessage), szInput, 4)
1444
1445 if(g_bIsCstrike)
1446 {
1447 if(bLog)
1448 {
1449 CC_LogMessage(id, _, szMessage)
1450 }
1451 else
1452 {
1453 CC_SendMessage(id, szMessage)
1454 }
1455 }
1456 else
1457 {
1458 format(szMessage, charsmax(szMessage), "%s %s", CC_PREFIX, szMessage)
1459 client_print(id, print_chat, szMessage)
1460
1461 if(bLog)
1462 {
1463 log_amx(szMessage)
1464 }
1465 }
1466}
1467
1468update_hudinfo(const id)
1469{
1470 if(!g_eSettings[HUDINFO_ENABLED])
1471 {
1472 return
1473 }
1474
1475 new szMessage[CRXRANKS_MAX_HUDINFO_LENGTH], szPlaceHolder[MAX_NAME_LENGTH], bool:bIsOnFinal
1476
1477 bIsOnFinal = g_ePlayerData[id][IsOnFinalLevel]
1478 copy(szMessage, charsmax(szMessage), g_eSettings[bIsOnFinal ? HUDINFO_FORMAT_FINAL : HUDINFO_FORMAT])
1479
1480 if(has_argument(szMessage, ARG_CURRENT_XP))
1481 {
1482 num_to_str(g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
1483 replace_string(szMessage, charsmax(szMessage), ARG_CURRENT_XP, szPlaceHolder)
1484 }
1485
1486 if(has_argument(szMessage, ARG_NEXT_XP))
1487 {
1488 num_to_str(g_ePlayerData[id][NextXP], szPlaceHolder, charsmax(szPlaceHolder))
1489 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_XP, szPlaceHolder)
1490 }
1491
1492 if(has_argument(szMessage, ARG_XP_NEEDED))
1493 {
1494 num_to_str(g_ePlayerData[id][NextXP] - g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
1495 replace_string(szMessage, charsmax(szMessage), ARG_XP_NEEDED, szPlaceHolder)
1496 }
1497
1498 if(has_argument(szMessage, ARG_LEVEL))
1499 {
1500 num_to_str(g_ePlayerData[id][Level], szPlaceHolder, charsmax(szPlaceHolder))
1501 replace_string(szMessage, charsmax(szMessage), ARG_LEVEL, szPlaceHolder)
1502 }
1503
1504 if(has_argument(szMessage, ARG_NEXT_LEVEL))
1505 {
1506 num_to_str(g_ePlayerData[id][bIsOnFinal ? Level : Level + 1], szPlaceHolder, charsmax(szPlaceHolder))
1507 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_LEVEL, szPlaceHolder)
1508 }
1509
1510 replace_string(szMessage, charsmax(szMessage), ARG_MAX_LEVELS, g_szMaxLevels)
1511
1512 if(has_argument(szMessage, ARG_NAME))
1513 {
1514 get_user_name(id, szPlaceHolder, charsmax(szPlaceHolder))
1515 replace_string(szMessage, charsmax(szMessage), ARG_NAME, szPlaceHolder)
1516 }
1517
1518 replace_string(szMessage, charsmax(szMessage), ARG_RANK, g_ePlayerData[id][Rank])
1519 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_RANK, g_ePlayerData[id][NextRank])
1520 replace_string(szMessage, charsmax(szMessage), ARG_LINE_BREAK, "^n")
1521 copy(g_ePlayerData[id][HUDInfo], charsmax(g_ePlayerData[][HUDInfo]), szMessage)
1522}
1523
1524check_level(const id, const bool:bNotify)
1525{
1526 new iLevel, i
1527
1528 for(i = 1; i < g_iMaxLevels + 1; i++)
1529 {
1530 if(g_ePlayerData[id][XP] >= ArrayGetCell(g_aLevels, i))
1531 {
1532 iLevel++
1533 }
1534 }
1535
1536 if(iLevel != g_ePlayerData[id][Level])
1537 {
1538 new bool:bLevelUp, iReturn
1539 bLevelUp = iLevel > g_ePlayerData[id][Level]
1540 g_ePlayerData[id][Level] = iLevel
1541 ArrayGetString(g_aRankNames, iLevel, g_ePlayerData[id][Rank], charsmax(g_ePlayerData[][Rank]))
1542
1543 if(iLevel < g_iMaxLevels)
1544 {
1545 g_ePlayerData[id][IsOnFinalLevel] = false
1546 g_ePlayerData[id][NextXP] = ArrayGetCell(g_aLevels, iLevel + 1)
1547 ArrayGetString(g_aRankNames, iLevel + 1, g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]))
1548 }
1549 else
1550 {
1551 g_ePlayerData[id][IsOnFinalLevel] = true
1552 g_ePlayerData[id][NextXP] = ArrayGetCell(g_aLevels, iLevel)
1553 copy(g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]), g_eSettings[HUDINFO_INVALID_TEXT])
1554
1555 if(g_eSettings[FINAL_LEVEL_FLAGS])
1556 {
1557 set_user_flags(id, g_eSettings[FINAL_LEVEL_FLAGS_BIT])
1558 remove_user_flags(id, g_iFlagZ)
1559 }
1560 }
1561
1562 ExecuteForward(g_fwdUserLevelUpdated, iReturn, id, iLevel, bLevelUp)
1563
1564 if(bNotify && g_eSettings[LEVELUP_MESSAGE_TYPE])
1565 {
1566 new szName[MAX_NAME_LENGTH]
1567 get_user_name(id, szName, charsmax(szName))
1568
1569 if(g_eSettings[LEVELUP_MESSAGE_TYPE] == 2)
1570 {
1571 new iPlayers[MAX_PLAYERS], iPlayer, iPnum
1572 get_players(iPlayers, iPnum)
1573
1574 for(i = 0; i < iPnum; i++)
1575 {
1576 iPlayer = iPlayers[i]
1577 send_chat_message(iPlayer, false, "%L", iPlayer, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
1578 }
1579 }
1580 else
1581 {
1582 send_chat_message(id, false, "%L", id, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
1583 }
1584
1585 if(bLevelUp && g_eSettings[LEVELUP_SOUND][0])
1586 {
1587 emit_sound(id, CHAN_AUTO, g_eSettings[LEVELUP_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
1588 }
1589 else if(!bLevelUp && g_eSettings[LEVELDN_SOUND][0])
1590 {
1591 emit_sound(id, CHAN_AUTO, g_eSettings[LEVELDN_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
1592 }
1593
1594 if(g_eSettings[bLevelUp ? LEVELUP_SCREEN_FADE_ENABLED : LEVELDN_SCREEN_FADE_ENABLED])
1595 {
1596 message_begin(MSG_ONE, g_iScreenFade, {0, 0, 0}, id)
1597 write_short(1<<10)
1598 write_short(1<<10)
1599 write_short(0)
1600
1601 if(bLevelUp)
1602 {
1603 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][0]))
1604 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][1]))
1605 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][2]))
1606 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][3]))
1607 }
1608 else
1609 {
1610 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][0]))
1611 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][1]))
1612 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][2]))
1613 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][3]))
1614 }
1615
1616 message_end()
1617 }
1618 }
1619 }
1620
1621 update_hudinfo(id)
1622}
1623
1624public update_vip_status(id)
1625{
1626 if(is_user_connected(id) && g_eSettings[VIP_FLAGS_BIT] != ADMIN_ALL)
1627 {
1628 g_ePlayerData[id][IsVIP] = bool:((get_user_flags(id) & g_eSettings[VIP_FLAGS_BIT]) == g_eSettings[VIP_FLAGS_BIT])
1629 }
1630}
1631
1632public plugin_natives()
1633{
1634 register_library("crxranks")
1635 register_native("crxranks_get_chat_prefix", "_crxranks_get_chat_prefix")
1636 register_native("crxranks_get_final_flags", "_crxranks_get_final_flags")
1637 register_native("crxranks_get_hudinfo_format", "_crxranks_get_hudinfo_format")
1638 register_native("crxranks_get_max_levels", "_crxranks_get_max_levels")
1639 register_native("crxranks_get_rank_by_level", "_crxranks_get_rank_by_level")
1640 register_native("crxranks_get_save_type", "_crxranks_get_save_type")
1641 register_native("crxranks_get_setting", "_crxranks_get_setting")
1642 register_native("crxranks_get_user_hudinfo", "_crxranks_get_user_hudinfo")
1643 register_native("crxranks_get_user_level", "_crxranks_get_user_level")
1644 register_native("crxranks_get_user_next_rank", "_crxranks_get_user_next_rank")
1645 register_native("crxranks_get_user_next_xp", "_crxranks_get_user_next_xp")
1646 register_native("crxranks_get_user_rank", "_crxranks_get_user_rank")
1647 register_native("crxranks_get_user_xp", "_crxranks_get_user_xp")
1648 register_native("crxranks_get_vault_name", "_crxranks_get_vault_name")
1649 register_native("crxranks_get_vip_flags", "_crxranks_get_vip_flags")
1650 register_native("crxranks_get_xp_for_level", "_crxranks_get_xp_for_level")
1651 register_native("crxranks_get_xp_reward", "_crxranks_get_xp_reward")
1652 register_native("crxranks_give_user_xp", "_crxranks_give_user_xp")
1653 register_native("crxranks_has_user_hudinfo", "_crxranks_has_user_hudinfo")
1654 register_native("crxranks_is_hi_using_dhud", "_crxranks_is_hi_using_dhud")
1655 register_native("crxranks_is_hud_enabled", "_crxranks_is_hud_enabled")
1656 register_native("crxranks_is_sfdn_enabled", "_crxranks_is_sfdn_enabled")
1657 register_native("crxranks_is_sfup_enabled", "_crxranks_is_sfup_enabled")
1658 register_native("crxranks_is_user_on_final", "_crxranks_is_user_on_final")
1659 register_native("crxranks_is_user_vip", "_crxranks_is_user_vip")
1660 register_native("crxranks_is_using_mysql", "_crxranks_is_using_mysql")
1661 register_native("crxranks_is_xpn_enabled", "_crxranks_is_xpn_enabled")
1662 register_native("crxranks_is_xpn_using_dhud", "_crxranks_is_xpn_using_dhud")
1663 register_native("crxranks_set_user_xp", "_crxranks_set_user_xp")
1664 register_native("crxranks_using_comb_events", "_crxranks_using_comb_events")
1665}
1666
1667public _crxranks_get_chat_prefix(iPlugin, iParams)
1668{
1669 set_string(1, CC_PREFIX, get_param(2))
1670}
1671
1672public _crxranks_get_final_flags(iPlugin, iParams)
1673{
1674 set_string(1, g_eSettings[FINAL_LEVEL_FLAGS], get_param(2))
1675 return g_eSettings[FINAL_LEVEL_FLAGS_BIT]
1676}
1677
1678public _crxranks_get_hudinfo_format(iPlugin, iParams)
1679{
1680 set_string(2, g_eSettings[get_param(1) ? HUDINFO_FORMAT_FINAL : HUDINFO_FORMAT], get_param(3))
1681}
1682
1683public _crxranks_get_max_levels(iPlugin, iParams)
1684{
1685 return g_iMaxLevels
1686}
1687
1688public _crxranks_get_rank_by_level(iPlugin, iParams)
1689{
1690 new iLevel = get_param(1)
1691
1692 if(iLevel < 1 || iLevel > g_iMaxLevels)
1693 {
1694 return 0
1695 }
1696
1697 new szRank[CRXRANKS_MAX_RANK_LENGTH]
1698 ArrayGetString(g_aRankNames, iLevel, szRank, charsmax(szRank))
1699 set_string(2, szRank, get_param(3))
1700 return 1
1701}
1702
1703public _crxranks_get_save_type(iPlugin, iParams)
1704{
1705 return g_eSettings[SAVE_TYPE]
1706}
1707
1708public bool:_crxranks_get_setting(iPlugin, iParams)
1709{
1710 new szKey[MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], bool:bReturn
1711 get_string(1, szKey, charsmax(szKey))
1712
1713 bReturn = TrieGetString(g_tSettings, szKey, szValue, charsmax(szValue))
1714 set_string(2, szValue, get_param(3))
1715 return bReturn
1716}
1717
1718public _crxranks_get_user_hudinfo(iPlugin, iParams)
1719{
1720 set_string(2, g_ePlayerData[get_param(1)][HUDInfo], get_param(3))
1721}
1722
1723public _crxranks_get_user_level(iPlugin, iParams)
1724{
1725 return g_ePlayerData[get_param(1)][Level]
1726}
1727
1728public _crxranks_get_user_next_rank(iPlugin, iParams)
1729{
1730 set_string(2, g_ePlayerData[get_param(1)][NextRank], get_param(3))
1731}
1732
1733public _crxranks_get_user_next_xp(iPlugin, iParams)
1734{
1735 return g_ePlayerData[get_param(1)][NextXP]
1736}
1737
1738public _crxranks_get_user_rank(iPlugin, iParams)
1739{
1740 set_string(2, g_ePlayerData[get_param(1)][Rank], get_param(3))
1741}
1742
1743public _crxranks_get_user_xp(iPlugin, iParams)
1744{
1745 return g_ePlayerData[get_param(1)][XP]
1746}
1747
1748public _crxranks_get_vault_name(iPlugin, iParams)
1749{
1750 set_string(1, g_eSettings[VAULT_NAME], get_param(2))
1751}
1752
1753public _crxranks_get_vip_flags(iPlugin, iParams)
1754{
1755 set_string(1, g_eSettings[VIP_FLAGS], get_param(2))
1756 return g_eSettings[VIP_FLAGS_BIT]
1757}
1758
1759public _crxranks_get_xp_for_level(iPlugin, iParams)
1760{
1761 new iLevel = get_param(1)
1762
1763 if(iLevel < 1 || iLevel > g_iMaxLevels)
1764 {
1765 return -1
1766 }
1767
1768 return ArrayGetCell(g_aLevels, iLevel)
1769}
1770
1771public _crxranks_get_xp_reward(iPlugin, iParams)
1772{
1773 new szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
1774 get_string(2, szReward, charsmax(szReward))
1775 return get_xp_reward(get_param(1), szReward)
1776}
1777
1778public _crxranks_give_user_xp(iPlugin, iParams)
1779{
1780 new szReward[CRXRANKS_MAX_XP_REWARD_LENGTH], iReward, id = get_param(1)
1781 get_string(3, szReward, charsmax(szReward))
1782
1783 if(szReward[0])
1784 {
1785 iReward = get_xp_reward(id, szReward)
1786
1787 if(iReward)
1788 {
1789 give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
1790 }
1791
1792 return iReward
1793 }
1794
1795 iReward = get_param(2)
1796 give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
1797 return iReward
1798}
1799
1800public bool:_crxranks_has_user_hudinfo(iPlugin, iParams)
1801{
1802 return g_ePlayerData[get_param(1)][HudInfoEnabled]
1803}
1804
1805public bool:_crxranks_is_hi_using_dhud(iPlugin, iParams)
1806{
1807 return g_eSettings[HUDINFO_USE_DHUD]
1808}
1809
1810public bool:_crxranks_is_hud_enabled(iPlugin, iParams)
1811{
1812 return g_eSettings[HUDINFO_ENABLED]
1813}
1814
1815public bool:_crxranks_is_sfdn_enabled(iPlugin, iParams)
1816{
1817 return g_eSettings[LEVELDN_SCREEN_FADE_ENABLED]
1818}
1819
1820public bool:_crxranks_is_sfup_enabled(iPlugin, iParams)
1821{
1822 return g_eSettings[LEVELUP_SCREEN_FADE_ENABLED]
1823}
1824
1825public bool:_crxranks_is_user_on_final(iPlugin, iParams)
1826{
1827 return g_ePlayerData[get_param(1)][IsOnFinalLevel]
1828}
1829
1830public bool:_crxranks_is_user_vip(iPlugin, iParams)
1831{
1832 return g_ePlayerData[get_param(1)][IsVIP]
1833}
1834
1835public bool:_crxranks_is_using_mysql(iPlugin, iParams)
1836{
1837 return g_eSettings[USE_MYSQL]
1838}
1839
1840public bool:_crxranks_is_xpn_enabled(iPlugin, iParams)
1841{
1842 return g_eSettings[XP_NOTIFIER_ENABLED]
1843}
1844
1845public bool:_crxranks_set_user_xp(iPlugin, iParams)
1846{
1847 new iReturn, id = get_param(1), CRXRanks_XPSources:iSource = CRXRanks_XPSources:get_param(3)
1848 g_ePlayerData[id][XP] = clamp(get_param(2), 0)
1849
1850 check_level(id, true)
1851 ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)
1852}
1853
1854public bool:_crxranks_using_comb_events(iPlugin, iParams)
1855{
1856 return g_eSettings[USE_COMBINED_EVENTS]
1857}
1858
1859public bool:_crxranks_is_xpn_using_dhud(iPlugin, iParams)
1860{
1861 return g_eSettings[XP_NOTIFIER_USE_DHUD]
1862}