· 6 years ago · Jul 22, 2019, 06:08 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"
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 new szModname[MAX_NAME_LENGTH]
200 get_modname(szModname, charsmax(szModname))
201
202 if(equal(szModname, "cstrike"))
203 {
204 g_bIsCstrike = true
205 }
206
207 register_dictionary(g_bIsCstrike ? "RankSystem.txt" : "RankSystemNoColors.txt")
208
209 register_event("DeathMsg", "OnPlayerKilled", "a")
210
211 register_clcmd("say /xplist", "Cmd_XPList", ADMIN_BAN)
212 register_clcmd("say_team /xplist", "Cmd_XPList", ADMIN_BAN)
213 register_clcmd("say /hudinfo", "Cmd_HudInfo", ADMIN_ALL)
214 register_clcmd("say_team /hudinfo", "Cmd_HudInfo", ADMIN_ALL)
215 register_concmd("crxranks_give_xp", "Cmd_GiveXP", ADMIN_RCON, "<nick|#userid> <amount>")
216 register_concmd("crxranks_reset_xp", "Cmd_ResetXP", ADMIN_RCON, "<nick|#userid>")
217 register_srvcmd("crxranks_update_mysql", "Cmd_UpdateMySQL")
218
219 if(g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] || g_eSettings[LEVELDN_SCREEN_FADE_ENABLED])
220 {
221 g_iScreenFade = get_user_msgid("ScreenFade")
222 }
223
224 g_fwdUserLevelUpdated = CreateMultiForward("crxranks_user_level_updated", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
225 g_fwdUserReceiveXP = CreateMultiForward("crxranks_user_receive_xp", ET_STOP, FP_CELL, FP_CELL, FP_CELL)
226 g_fwdUserXPUpdated = CreateMultiForward("crxranks_user_xp_updated", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
227
228 if(g_eSettings[USE_MYSQL])
229 {
230 g_iSqlTuple = SQL_MakeDbTuple(g_eSettings[SQL_HOST], g_eSettings[SQL_USER], g_eSettings[SQL_PASSWORD], g_eSettings[SQL_DATABASE])
231
232 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
233
234 if(iSqlConnection == Empty_Handle)
235 {
236 log_amx(g_szSqlError)
237 switch_to_nvault()
238 goto @AFTER_MYSQL
239 }
240
241 new Handle:iQueries = SQL_PrepareQuery(iSqlConnection,\
242 "CREATE TABLE IF NOT EXISTS `%s` (`Player` VARCHAR(%i) NOT NULL, `XP` INT(%i) NOT NULL, `Level` INT(%i) NOT NULL,\
243 `Next XP` INT(%i) NOT NULL, `Rank` VARCHAR(%i) NOT NULL, `Next Rank` VARCHAR(%i) NOT NULL, PRIMARY KEY(Player));",\
244 g_eSettings[SQL_TABLE], MAX_SQL_PLAYER_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH,\
245 MAX_SQL_RANK_LENGTH, MAX_SQL_RANK_LENGTH)
246
247 if(!SQL_Execute(iQueries))
248 {
249 SQL_QueryError(iQueries, g_szSqlError, charsmax(g_szSqlError))
250 log_amx(g_szSqlError)
251 switch_to_nvault()
252 goto @AFTER_MYSQL
253 }
254
255 SQL_FreeHandle(iQueries)
256 SQL_FreeHandle(iSqlConnection)
257 }
258
259 @AFTER_MYSQL:
260
261 if(!g_eSettings[USE_MYSQL])
262 {
263 g_iVault = nvault_open(g_eSettings[VAULT_NAME])
264 }
265}
266
267public plugin_precache()
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 static szNewName[MAX_NAME_LENGTH], szOldName[MAX_NAME_LENGTH]
686 get_user_info(id, szKey, szNewName, charsmax(szNewName))
687 get_user_name(id, szOldName, charsmax(szOldName))
688
689 if(!equal(szNewName, szOldName))
690 {
691 if(g_eSettings[SAVE_TYPE] == SAVE_NICKNAME)
692 {
693 save_or_load(id, szOldName, SL_SAVE_DATA)
694
695 if(g_eSettings[USE_MYSQL])
696 {
697 reset_player_stats(id)
698 set_task(DELAY_ON_CHANGE, "load_after_change", id)
699 }
700 else
701 {
702 save_or_load(id, szNewName, SL_LOAD_DATA)
703 update_hudinfo(id)
704 }
705 }
706
707 set_task(DELAY_ON_CHANGE, "update_vip_status", id)
708 }
709}
710
711public load_after_change(id)
712{
713 static szName[MAX_NAME_LENGTH]
714 get_user_name(id, szName, charsmax(szName))
715 save_or_load(id, szName, SL_LOAD_DATA)
716 update_hudinfo(id)
717}
718
719public DisplayHUD(id)
720{
721 id -= TASK_HUD
722
723 if(!g_ePlayerData[id][HudInfoEnabled])
724 {
725 return
726 }
727
728 static bool:bIsAlive, iTarget
729
730 bIsAlive = is_user_alive(id) != 0
731 iTarget = id
732
733 if(!bIsAlive)
734 {
735 if(g_eSettings[HUDINFO_ALIVE_ONLY])
736 {
737 return
738 }
739
740 if(g_eSettings[HUDINFO_OTHER_PLAYERS])
741 {
742 iTarget = pev(id, pev_iuser2)
743 }
744 }
745
746 if(!iTarget)
747 {
748 return
749 }
750
751 if(g_eSettings[TEAM_LOCK] && g_eSettings[HUDINFO_TEAM_LOCK] && get_user_team(iTarget) != g_eSettings[TEAM_LOCK])
752 {
753 return
754 }
755
756 if(g_eSettings[HUDINFO_USE_DHUD])
757 {
758 if(bIsAlive)
759 {
760 set_dhudmessage(HUDINFO_PARAMS)
761 }
762 else
763 {
764 set_dhudmessage(HUDINFO_PARAMS_DEAD)
765 }
766
767 show_dhudmessage(id, g_ePlayerData[iTarget][HUDInfo])
768 }
769 else
770 {
771 if(bIsAlive)
772 {
773 set_hudmessage(HUDINFO_PARAMS)
774 }
775 else
776 {
777 set_hudmessage(HUDINFO_PARAMS_DEAD)
778 }
779
780 ShowSyncHudMsg(id, g_iObject[OBJ_HUDINFO], g_ePlayerData[iTarget][HUDInfo])
781 }
782}
783
784public bomb_planted(id)
785{
786 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_PLANTED), CRXRANKS_XPS_REWARD)
787}
788
789public bomb_defused(id)
790{
791 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_DEFUSED), CRXRANKS_XPS_REWARD)
792}
793
794public bomb_explode(id)
795{
796 give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_EXPLODED), CRXRANKS_XPS_REWARD)
797}
798
799public Cmd_XP(id)
800{
801 if(g_ePlayerData[id][Level] == g_iMaxLevels)
802 {
803 send_chat_message(id, false, "%L", id, "CRXRANKS_RANKINFO_FINAL", g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
804 }
805 else
806 {
807 send_chat_message(id, false, "%L", id, "CRXRANKS_RANKINFO_NORMAL", g_ePlayerData[id][XP], g_ePlayerData[id][NextXP],\
808 g_ePlayerData[id][Level], g_ePlayerData[id][Rank], g_ePlayerData[id][NextRank])
809 }
810
811 return PLUGIN_HANDLED
812}
813
814public Cmd_XPList(id, iLevel, iCid)
815{
816 if(!cmd_access(id, iLevel, iCid, 1))
817 {
818 return PLUGIN_HANDLED
819 }
820
821 new szTitle[128]
822 formatex(szTitle, charsmax(szTitle), "%L", id, "CRXRANKS_MENU_TITLE")
823
824 new iPlayers[MAX_PLAYERS], iPnum, iMenu = menu_create(szTitle, "XPList_Handler")
825 get_players(iPlayers, iPnum); SortCustom1D(iPlayers, iPnum, "sort_players_by_xp")
826
827 for(new szItem[128], szName[MAX_NAME_LENGTH], iPlayer, i; i < iPnum; i++)
828 {
829 iPlayer = iPlayers[i]
830 get_user_name(iPlayer, szName, charsmax(szName))
831 formatex(szItem, charsmax(szItem), "%L", id, "CRXRANKS_ITEM_FORMAT", g_ePlayerData[iPlayer][XP], szName, g_ePlayerData[iPlayer][Level], g_ePlayerData[iPlayer][Rank])
832 menu_additem(iMenu, szItem)
833 }
834
835 menu_display(id, iMenu)
836 return PLUGIN_HANDLED
837}
838
839public Cmd_HudInfo(id, iLevel, iCid)
840{
841 if(!cmd_access(id, iLevel, iCid, 1))
842 {
843 return PLUGIN_HANDLED
844 }
845
846 if(!g_eSettings[HUDINFO_ENABLED])
847 {
848 send_chat_message(id, false, "%L", id, "CRXRANKS_HUDINFO_UNAVAILABLE")
849 return PLUGIN_HANDLED
850 }
851
852 g_ePlayerData[id][HudInfoEnabled] = !g_ePlayerData[id][HudInfoEnabled]
853 send_chat_message(id, false, "%L", id, g_ePlayerData[id][HudInfoEnabled] ? "CRXRANKS_HUDINFO_ENABLED" : "CRXRANKS_HUDINFO_DISABLED")
854 return PLUGIN_HANDLED
855}
856
857public XPList_Handler(id, iMenu, iItem)
858{
859 menu_destroy(iMenu)
860 return PLUGIN_HANDLED
861}
862
863public Cmd_GiveXP(id, iLevel, iCid)
864{
865 if(!cmd_access(id, iLevel, iCid, 3))
866 {
867 return PLUGIN_HANDLED
868 }
869
870 new szPlayer[MAX_NAME_LENGTH]
871 read_argv(1, szPlayer, charsmax(szPlayer))
872
873 new iPlayer = cmd_target(id, szPlayer, 0)
874
875 if(!iPlayer)
876 {
877 return PLUGIN_HANDLED
878 }
879
880 new szName[2][MAX_NAME_LENGTH], szAmount[CRXRANKS_MAX_XP_LENGTH]
881 read_argv(2, szAmount, charsmax(szAmount))
882 get_user_name(id, szName[0], charsmax(szName[]))
883 get_user_name(iPlayer, szName[1], charsmax(szName[]))
884
885 new szKey[MAX_NAME_LENGTH], iXP = str_to_num(szAmount)
886 give_user_xp(iPlayer, iXP, CRXRANKS_XPS_ADMIN)
887
888 if(iXP >= 0)
889 {
890 copy(szKey, charsmax(szKey), "CRXRANKS_GIVE_XP")
891 }
892 else
893 {
894 copy(szKey, charsmax(szKey), "CRXRANKS_TAKE_XP")
895 iXP *= -1
896 }
897
898 send_chat_message(0, true, "%L", id, szKey, szName[0], iXP, szName[1])
899 return PLUGIN_HANDLED
900}
901
902public Cmd_ResetXP(id, iLevel, iCid)
903{
904 if(!cmd_access(id, iLevel, iCid, 2))
905 {
906 return PLUGIN_HANDLED
907 }
908
909 new szPlayer[MAX_NAME_LENGTH]
910 read_argv(1, szPlayer, charsmax(szPlayer))
911
912 new iPlayer = cmd_target(id, szPlayer, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF)
913
914 if(!iPlayer)
915 {
916 return PLUGIN_HANDLED
917 }
918
919 new szName[2][MAX_NAME_LENGTH]
920 get_user_name(id, szName[0], charsmax(szName[]))
921 get_user_name(iPlayer, szName[1], charsmax(szName[]))
922
923 g_ePlayerData[iPlayer][XP] = 0
924 check_level(iPlayer, true)
925 send_chat_message(0, true, "%L", id, "CRXRANKS_RESET_XP", szName[0], szName[1])
926
927 return PLUGIN_HANDLED
928}
929
930// This command is here because the update from v3.0 to v3.1 changed the way data is stored in MySQL.
931// Because of that, a new table is required and this command is here to transfer the data from the old one.
932// The command will be removed in future versions, so I decided not to translate the strings used in it.
933public Cmd_UpdateMySQL()
934{
935 static bUsed
936
937 if(bUsed)
938 {
939 server_print("The MySQL table has already been updated to version v3.1. There's no point in doing this again.")
940 return PLUGIN_HANDLED
941 }
942
943 if(!g_eSettings[USE_MYSQL])
944 {
945 server_print("The plugin isn't using MySQL at the moment. Please enable the feature before using this command.")
946 return PLUGIN_HANDLED
947 }
948
949 new szTable[MAX_NAME_LENGTH]
950 read_argv(1, szTable, charsmax(szTable))
951
952 if(!szTable[0])
953 {
954 server_print("Plese provide the name of the previous table in order to transfer data to the current one.")
955 return PLUGIN_HANDLED
956 }
957
958 new szQuery[MAX_NAME_LENGTH * 2]
959 formatex(szQuery, charsmax(szQuery), "SELECT * FROM `%s`;", szTable)
960 SQL_ThreadQuery(g_iSqlTuple, "QueryUpdateMySQL", szQuery)
961
962 bUsed = true
963 return PLUGIN_HANDLED
964}
965
966public QueryUpdateMySQL(iFailState, Handle:iQuery, szError[], iErrorCode)
967{
968 if(iFailState == TQUERY_CONNECT_FAILED || iFailState == TQUERY_QUERY_FAILED)
969 {
970 server_print(szError)
971 return
972 }
973
974 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
975
976 if(iSqlConnection == Empty_Handle)
977 {
978 server_print(g_szSqlError)
979 return
980 }
981
982 new Handle:iQuery2, szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szInfo[MAX_SQL_PLAYER_LENGTH], iCounter, iPlayer, iXP
983 new szColumnPlayer = SQL_FieldNameToNum(iQuery, "User")
984 new szColumnXP = SQL_FieldNameToNum(iQuery, "XP")
985
986 while(SQL_MoreResults(iQuery))
987 {
988 SQL_ReadResult(iQuery, szColumnPlayer, szInfo, charsmax(szInfo))
989 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
990 iQuery2 = SQL_PrepareQuery(iSqlConnection, "SELECT * FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
991
992 if(!SQL_Execute(iQuery2))
993 {
994 SQL_QueryError(iQuery2, g_szSqlError, charsmax(g_szSqlError))
995 server_print(g_szSqlError)
996 return
997 }
998
999 iXP = SQL_ReadResult(iQuery, szColumnXP)
1000
1001 if(SQL_NumResults(iQuery2) > 0)
1002 {
1003 formatex(szQuery, charsmax(szQuery), "UPDATE `%s` SET `XP`='%i' WHERE `Player`='%s';", g_eSettings[SQL_TABLE], iXP, szPlayer)
1004 }
1005 else
1006 {
1007 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)
1008 }
1009
1010 switch(g_eSettings[SAVE_TYPE])
1011 {
1012 case CRXRANKS_ST_NICKNAME: iPlayer = find_player("a", szInfo)
1013 case CRXRANKS_ST_STEAMID: iPlayer = find_player("c", szInfo)
1014 case CRXRANKS_ST_IP: iPlayer = find_player("d", szInfo)
1015 }
1016
1017 if(iPlayer)
1018 {
1019 g_ePlayerData[iPlayer][XP] = iXP
1020 check_level(iPlayer, true)
1021 }
1022
1023 SQL_ThreadQuery(g_iSqlTuple, "QueryHandler", szQuery)
1024 SQL_NextRow(iQuery)
1025 iCounter++
1026 }
1027
1028 SQL_FreeHandle(iQuery2)
1029 SQL_FreeHandle(iSqlConnection)
1030}
1031
1032public OnPlayerKilled()
1033{
1034 new szWeapon[16], iAttacker = read_data(1), iVictim = read_data(2), iXP
1035 read_data(4, szWeapon, charsmax(szWeapon))
1036
1037 if(!is_user_connected(iVictim))
1038 {
1039 return
1040 }
1041
1042 if(iAttacker == iVictim || equal(szWeapon, "worldspawn") || equal(szWeapon, "door", 4) || equal(szWeapon, "trigger_hurt"))
1043 {
1044 iXP = get_xp_reward(iVictim, XPREWARD_SUICIDE)
1045
1046 if(g_eSettings[USE_COMBINED_EVENTS])
1047 {
1048 iXP += get_xp_reward(iVictim, XPREWARD_DEATH)
1049 }
1050
1051 give_user_xp(iVictim, iXP, CRXRANKS_XPS_REWARD)
1052
1053 if(should_send_kill_message(iXP))
1054 {
1055 send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_SUICIDE_GET" : "CRXRANKS_NOTIFY_SUICIDE_LOSE", abs(iXP))
1056 }
1057
1058 return
1059 }
1060
1061 if(!is_user_connected(iAttacker))
1062 {
1063 return
1064 }
1065
1066 new iReward, iTemp
1067
1068 if(iAttacker == iVictim)
1069 {
1070 iTemp = get_xp_reward(iAttacker, XPREWARD_SUICIDE)
1071 iReward += iTemp
1072
1073 if(should_skip(iTemp))
1074 {
1075 goto @GIVE_REWARD
1076 }
1077 }
1078 else if(get_user_team(iAttacker) == get_user_team(iVictim))
1079 {
1080 iTemp = get_xp_reward(iAttacker, XPREWARD_TEAMKILL)
1081 iReward += iTemp
1082
1083 if(should_skip(iTemp))
1084 {
1085 goto @GIVE_REWARD
1086 }
1087 }
1088 else
1089 {
1090 iTemp = get_xp_reward(iAttacker, szWeapon)
1091 iReward += iTemp
1092
1093 if(should_skip(iTemp))
1094 {
1095 goto @GIVE_REWARD
1096 }
1097
1098 if(read_data(3))
1099 {
1100 iTemp = get_xp_reward(iAttacker, XPREWARD_HEADSHOT)
1101 iReward += iTemp
1102
1103 if(should_skip(iTemp))
1104 {
1105 goto @GIVE_REWARD
1106 }
1107 }
1108
1109 iReward += get_xp_reward(iAttacker, XPREWARD_KILL)
1110 }
1111
1112 @GIVE_REWARD:
1113 iXP = give_user_xp(iAttacker, iReward, CRXRANKS_XPS_REWARD)
1114
1115 if(should_send_kill_message(iXP))
1116 {
1117 new szName[MAX_NAME_LENGTH]
1118 get_user_name(iVictim, szName, charsmax(szName))
1119 send_chat_message(iAttacker, false, "%L", iAttacker, iXP > 0 ? "CRXRANKS_NOTIFY_KILL_GET" : "CRXRANKS_NOTIFY_KILL_LOSE", abs(iXP), szName)
1120 }
1121
1122 iXP = give_user_xp(iVictim, get_xp_reward(iVictim, XPREWARD_DEATH), CRXRANKS_XPS_REWARD)
1123
1124 if(should_send_kill_message(iXP))
1125 {
1126 send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_DEATH_GET" : "CRXRANKS_NOTIFY_DEATH_LOSE", abs(iXP))
1127 }
1128}
1129
1130public sort_players_by_xp(id1, id2)
1131{
1132 if(g_ePlayerData[id1][XP] > g_ePlayerData[id2][XP])
1133 {
1134 return -1
1135 }
1136 else if(g_ePlayerData[id1][XP] < g_ePlayerData[id2][XP])
1137 {
1138 return 1
1139 }
1140
1141 return 0
1142}
1143
1144public QueryHandler(iFailState, Handle:iQuery, szError[], iErrorCode)
1145{
1146 switch(iFailState)
1147 {
1148 case TQUERY_CONNECT_FAILED: log_amx("[SQL Error] Connection failed (%i): %s", iErrorCode, szError)
1149 case TQUERY_QUERY_FAILED: log_amx("[SQL Error] Query failed (%i): %s", iErrorCode, szError)
1150 }
1151}
1152
1153save_or_load(const id, const szInfo[], const iType)
1154{
1155 if(!szInfo[0])
1156 {
1157 return
1158 }
1159
1160 switch(iType)
1161 {
1162 case SL_SAVE_DATA:
1163 {
1164 if(g_eSettings[USE_MYSQL])
1165 {
1166 static szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szRank[MAX_SQL_RANK_LENGTH], szNextRank[MAX_SQL_RANK_LENGTH]
1167 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1168
1169 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
1170 SQL_QuoteString(iSqlConnection, szRank, charsmax(szRank), g_ePlayerData[id][Rank])
1171 SQL_QuoteString(iSqlConnection, szNextRank, charsmax(szNextRank), g_ePlayerData[id][NextRank])
1172
1173 formatex(szQuery, charsmax(szQuery), "UPDATE `%s` SET `XP`='%i',`Level`='%i',`Next XP`='%i',`Rank`='%s',`Next Rank`='%s' WHERE `Player`='%s';",\
1174 g_eSettings[SQL_TABLE], g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][NextXP], szRank, szNextRank, szPlayer)
1175 SQL_ThreadQuery(g_iSqlTuple, "QueryHandler", szQuery)
1176 }
1177 else
1178 {
1179 static szData[CRXRANKS_MAX_XP_LENGTH]
1180 num_to_str(g_ePlayerData[id][XP], szData, charsmax(szData))
1181 nvault_set(g_iVault, szInfo, szData)
1182 }
1183 }
1184 case SL_LOAD_DATA:
1185 {
1186 if(g_eSettings[USE_MYSQL])
1187 {
1188 static szPlayer[MAX_SQL_PLAYER_LENGTH]
1189 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1190 SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
1191
1192 if(iSqlConnection == Empty_Handle)
1193 {
1194 log_amx(g_szSqlError)
1195 return
1196 }
1197
1198 new Handle:iQuery = SQL_PrepareQuery(iSqlConnection, "SELECT * FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
1199
1200 if(!SQL_Execute(iQuery))
1201 {
1202 SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
1203 log_amx(g_szSqlError)
1204 return
1205 }
1206
1207 prepare_player(id, szPlayer, SQL_NumResults(iQuery) > 0 ? false : true)
1208 SQL_FreeHandle(iQuery)
1209 SQL_FreeHandle(iSqlConnection)
1210 }
1211 else
1212 {
1213 new iData = nvault_get(g_iVault, szInfo)
1214 g_ePlayerData[id][XP] = iData ? clamp(iData, 0) : 0
1215 check_level(id, false)
1216 }
1217 }
1218 }
1219}
1220
1221prepare_player(id, const szPlayer[], bool:bNewPlayer)
1222{
1223 new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
1224
1225 if(iSqlConnection == Empty_Handle)
1226 {
1227 log_amx(g_szSqlError)
1228 return
1229 }
1230
1231 static szQuery[MAX_QUERY_LENGTH]
1232
1233 if(bNewPlayer)
1234 {
1235 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)
1236 }
1237 else
1238 {
1239 formatex(szQuery, charsmax(szQuery), "SELECT XP FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
1240 }
1241
1242 new Handle:iQuery = SQL_PrepareQuery(iSqlConnection, szQuery)
1243
1244 if(!SQL_Execute(iQuery))
1245 {
1246 SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
1247 log_amx(g_szSqlError)
1248 }
1249
1250 if(!bNewPlayer)
1251 {
1252 if(SQL_NumResults(iQuery) > 0)
1253 {
1254 g_ePlayerData[id][XP] = SQL_ReadResult(iQuery, 0)
1255 }
1256 }
1257
1258 check_level(id, false)
1259
1260 SQL_FreeHandle(iQuery)
1261 SQL_FreeHandle(iSqlConnection)
1262}
1263
1264get_xp_reward(const id, const szKey[])
1265{
1266 static iReward
1267
1268 if(g_ePlayerData[id][IsVIP])
1269 {
1270 if(TrieKeyExists(g_tXPRewardsVIP, szKey))
1271 {
1272 TrieGetCell(g_tXPRewardsVIP, szKey, iReward)
1273 return iReward
1274 }
1275 }
1276
1277 if(TrieKeyExists(g_tXPRewards, szKey))
1278 {
1279 TrieGetCell(g_tXPRewards, szKey, iReward)
1280 return iReward
1281 }
1282
1283 return 0
1284}
1285
1286give_user_xp(const id, iXP, CRXRanks_XPSources:iSource = CRXRANKS_XPS_PLUGIN)
1287{
1288 if(!iXP)
1289 {
1290 return 0
1291 }
1292
1293 if(g_eSettings[IGNORE_BOTS] && g_ePlayerData[id][IsBot])
1294 {
1295 return 0
1296 }
1297
1298 if(iSource == CRXRANKS_XPS_REWARD)
1299 {
1300 if(g_eSettings[MINIMUM_PLAYERS] && get_playersnum() < g_eSettings[MINIMUM_PLAYERS])
1301 {
1302 return 0
1303 }
1304
1305 if(g_eSettings[TEAM_LOCK] && get_user_team(id) != g_eSettings[TEAM_LOCK])
1306 {
1307 return 0
1308 }
1309 }
1310
1311 static iReturn
1312 ExecuteForward(g_fwdUserReceiveXP, iReturn, id, iXP, iSource)
1313
1314 switch(iReturn)
1315 {
1316 case CRXRANKS_HANDLED: return 0
1317 case CRXRANKS_CONTINUE: { }
1318 default:
1319 {
1320 if(iReturn != 0)
1321 {
1322 iXP = iReturn
1323 }
1324 }
1325 }
1326
1327 g_ePlayerData[id][XP] += iXP
1328
1329 if(g_ePlayerData[id][XP] < 0)
1330 {
1331 g_ePlayerData[id][XP] = 0
1332 }
1333
1334 check_level(id, true)
1335 ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)
1336
1337 if(g_eSettings[XP_NOTIFIER_ENABLED])
1338 {
1339 static szKey[MAX_NAME_LENGTH], bool:bPositive
1340 bPositive = iXP >= 0
1341
1342 copy(szKey, charsmax(szKey), bPositive ? "CRXRANKS_XP_NOTIFIER_GET" : "CRXRANKS_XP_NOTIFIER_LOSE")
1343
1344 if(g_eSettings[XP_NOTIFIER_USE_DHUD])
1345 {
1346 if(bPositive)
1347 {
1348 set_dhudmessage(XP_NOTIFIER_PARAMS_GET)
1349 }
1350 else
1351 {
1352 set_dhudmessage(XP_NOTIFIER_PARAMS_LOSE)
1353 }
1354
1355 show_dhudmessage(id, "%L", id, szKey, abs(iXP))
1356 }
1357 else
1358 {
1359 if(bPositive)
1360 {
1361 set_hudmessage(XP_NOTIFIER_PARAMS_GET)
1362 }
1363 else
1364 {
1365 set_hudmessage(XP_NOTIFIER_PARAMS_LOSE)
1366 }
1367
1368 ShowSyncHudMsg(id, g_iObject[OBJ_XP_NOTIFIER], "%L", id, szKey, abs(iXP))
1369 }
1370 }
1371
1372 return iXP
1373}
1374
1375get_user_saveinfo(const id, szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH], const iLen)
1376{
1377 switch(g_eSettings[SAVE_TYPE])
1378 {
1379 case SAVE_NICKNAME: get_user_name(id, szInfo, iLen)
1380 case SAVE_IP: get_user_ip(id, szInfo, iLen, 1)
1381 case SAVE_STEAMID: get_user_authid(id, szInfo, iLen)
1382 }
1383}
1384
1385precache_sound_if_found(const szValue[])
1386{
1387 new szSound[MAX_SOUND_LENGTH]
1388 format(szSound, charsmax(szSound), "sound/%s", szValue)
1389
1390 if(file_exists(szSound))
1391 {
1392 precache_sound(szValue)
1393 }
1394 else
1395 {
1396 log_amx("ERROR: sound file ^"%s^" not found", szValue)
1397 }
1398}
1399
1400reset_player_stats(const id)
1401{
1402 g_ePlayerData[id][XP] = 0
1403 g_ePlayerData[id][Level] = 0
1404 g_ePlayerData[id][NextXP] = 0
1405 g_ePlayerData[id][Rank][0] = EOS
1406 g_ePlayerData[id][NextRank][0] = EOS
1407 g_ePlayerData[id][HUDInfo][0] = EOS
1408 g_ePlayerData[id][HudInfoEnabled] = true
1409 g_ePlayerData[id][IsOnFinalLevel] = false
1410 g_ePlayerData[id][IsVIP] = false
1411 g_ePlayerData[id][IsBot] = false
1412}
1413
1414switch_to_nvault()
1415{
1416 if(g_eSettings[USE_MYSQL])
1417 {
1418 g_eSettings[USE_MYSQL] = false
1419 log_amx("%L", LANG_SERVER, "CRXRANKS_MYSQL_FAILED")
1420 }
1421}
1422
1423bool:has_argument(const szMessage[], const szArg[])
1424{
1425 return contain(szMessage, szArg) != -1
1426}
1427
1428bool:should_skip(const iNum)
1429{
1430 return (iNum != 0 && !g_eSettings[USE_COMBINED_EVENTS])
1431}
1432
1433bool:should_send_kill_message(const iXP)
1434{
1435 return (g_eSettings[NOTIFY_ON_KILL] && iXP != 0)
1436}
1437
1438send_chat_message(const id, const bool:bLog, const szInput[], any:...)
1439{
1440 static szMessage[192]
1441 vformat(szMessage, charsmax(szMessage), szInput, 4)
1442
1443 if(g_bIsCstrike)
1444 {
1445 if(bLog)
1446 {
1447 CC_LogMessage(id, _, szMessage)
1448 }
1449 else
1450 {
1451 CC_SendMessage(id, szMessage)
1452 }
1453 }
1454 else
1455 {
1456 format(szMessage, charsmax(szMessage), "%s %s", CC_PREFIX, szMessage)
1457 client_print(id, print_chat, szMessage)
1458
1459 if(bLog)
1460 {
1461 log_amx(szMessage)
1462 }
1463 }
1464}
1465
1466update_hudinfo(const id)
1467{
1468 if(!g_eSettings[HUDINFO_ENABLED])
1469 {
1470 return
1471 }
1472
1473 static szMessage[CRXRANKS_MAX_HUDINFO_LENGTH], szPlaceHolder[MAX_NAME_LENGTH], bool:bIsOnFinal
1474
1475 bIsOnFinal = g_ePlayerData[id][IsOnFinalLevel]
1476 copy(szMessage, charsmax(szMessage), g_eSettings[bIsOnFinal ? HUDINFO_FORMAT_FINAL : HUDINFO_FORMAT])
1477
1478 if(has_argument(szMessage, ARG_CURRENT_XP))
1479 {
1480 num_to_str(g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
1481 replace_string(szMessage, charsmax(szMessage), ARG_CURRENT_XP, szPlaceHolder)
1482 }
1483
1484 if(has_argument(szMessage, ARG_NEXT_XP))
1485 {
1486 num_to_str(g_ePlayerData[id][NextXP], szPlaceHolder, charsmax(szPlaceHolder))
1487 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_XP, szPlaceHolder)
1488 }
1489
1490 if(has_argument(szMessage, ARG_XP_NEEDED))
1491 {
1492 num_to_str(g_ePlayerData[id][NextXP] - g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
1493 replace_string(szMessage, charsmax(szMessage), ARG_XP_NEEDED, szPlaceHolder)
1494 }
1495
1496 if(has_argument(szMessage, ARG_LEVEL))
1497 {
1498 num_to_str(g_ePlayerData[id][Level], szPlaceHolder, charsmax(szPlaceHolder))
1499 replace_string(szMessage, charsmax(szMessage), ARG_LEVEL, szPlaceHolder)
1500 }
1501
1502 if(has_argument(szMessage, ARG_NEXT_LEVEL))
1503 {
1504 num_to_str(g_ePlayerData[id][bIsOnFinal ? Level : Level + 1], szPlaceHolder, charsmax(szPlaceHolder))
1505 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_LEVEL, szPlaceHolder)
1506 }
1507
1508 replace_string(szMessage, charsmax(szMessage), ARG_MAX_LEVELS, g_szMaxLevels)
1509
1510 if(has_argument(szMessage, ARG_NAME))
1511 {
1512 get_user_name(id, szPlaceHolder, charsmax(szPlaceHolder))
1513 replace_string(szMessage, charsmax(szMessage), ARG_NAME, szPlaceHolder)
1514 }
1515
1516 replace_string(szMessage, charsmax(szMessage), ARG_RANK, g_ePlayerData[id][Rank])
1517 replace_string(szMessage, charsmax(szMessage), ARG_NEXT_RANK, g_ePlayerData[id][NextRank])
1518 replace_string(szMessage, charsmax(szMessage), ARG_LINE_BREAK, "^n")
1519 copy(g_ePlayerData[id][HUDInfo], charsmax(g_ePlayerData[][HUDInfo]), szMessage)
1520}
1521
1522check_level(const id, const bool:bNotify)
1523{
1524 static iLevel, i
1525 iLevel = 0
1526
1527 for(i = 1; i < g_iMaxLevels + 1; i++)
1528 {
1529 if(g_ePlayerData[id][XP] >= ArrayGetCell(g_aLevels, i))
1530 {
1531 iLevel++
1532 }
1533 }
1534
1535 if(iLevel != g_ePlayerData[id][Level])
1536 {
1537 static bool:bLevelUp, iReturn
1538 bLevelUp = iLevel > g_ePlayerData[id][Level]
1539 g_ePlayerData[id][Level] = iLevel
1540 ArrayGetString(g_aRankNames, iLevel, g_ePlayerData[id][Rank], charsmax(g_ePlayerData[][Rank]))
1541
1542 if(iLevel < g_iMaxLevels)
1543 {
1544 g_ePlayerData[id][IsOnFinalLevel] = false
1545 g_ePlayerData[id][NextXP] = ArrayGetCell(g_aLevels, iLevel + 1)
1546 ArrayGetString(g_aRankNames, iLevel + 1, g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]))
1547 }
1548 else
1549 {
1550 g_ePlayerData[id][IsOnFinalLevel] = true
1551 g_ePlayerData[id][NextXP] = ArrayGetCell(g_aLevels, iLevel)
1552 copy(g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]), g_eSettings[HUDINFO_INVALID_TEXT])
1553
1554 if(g_eSettings[FINAL_LEVEL_FLAGS])
1555 {
1556 set_user_flags(id, g_eSettings[FINAL_LEVEL_FLAGS_BIT])
1557 remove_user_flags(id, g_iFlagZ)
1558 }
1559 }
1560
1561 ExecuteForward(g_fwdUserLevelUpdated, iReturn, id, iLevel, bLevelUp)
1562
1563 if(bNotify && g_eSettings[LEVELUP_MESSAGE_TYPE])
1564 {
1565 static szName[MAX_NAME_LENGTH]
1566 get_user_name(id, szName, charsmax(szName))
1567
1568 if(g_eSettings[LEVELUP_MESSAGE_TYPE] == 2)
1569 {
1570 static iPlayers[MAX_PLAYERS], iPlayer, iPnum
1571 get_players(iPlayers, iPnum)
1572
1573 for(i = 0; i < iPnum; i++)
1574 {
1575 iPlayer = iPlayers[i]
1576 send_chat_message(iPlayer, false, "%L", iPlayer, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
1577 }
1578 }
1579 else
1580 {
1581 send_chat_message(id, false, "%L", id, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
1582 }
1583
1584 if(bLevelUp && g_eSettings[LEVELUP_SOUND][0])
1585 {
1586 emit_sound(id, CHAN_AUTO, g_eSettings[LEVELUP_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
1587 }
1588 else if(!bLevelUp && g_eSettings[LEVELDN_SOUND][0])
1589 {
1590 emit_sound(id, CHAN_AUTO, g_eSettings[LEVELDN_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
1591 }
1592
1593 if(g_eSettings[bLevelUp ? LEVELUP_SCREEN_FADE_ENABLED : LEVELDN_SCREEN_FADE_ENABLED])
1594 {
1595 message_begin(MSG_ONE, g_iScreenFade, {0, 0, 0}, id)
1596 write_short(1<<10)
1597 write_short(1<<10)
1598 write_short(0)
1599
1600 if(bLevelUp)
1601 {
1602 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][0]))
1603 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][1]))
1604 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][2]))
1605 write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][3]))
1606 }
1607 else
1608 {
1609 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][0]))
1610 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][1]))
1611 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][2]))
1612 write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][3]))
1613 }
1614
1615 message_end()
1616 }
1617 }
1618 }
1619
1620 update_hudinfo(id)
1621}
1622
1623public update_vip_status(id)
1624{
1625 if(is_user_connected(id) && g_eSettings[VIP_FLAGS_BIT] != ADMIN_ALL)
1626 {
1627 g_ePlayerData[id][IsVIP] = bool:((get_user_flags(id) & g_eSettings[VIP_FLAGS_BIT]) == g_eSettings[VIP_FLAGS_BIT])
1628 }
1629}
1630
1631public plugin_natives()
1632{
1633 register_library("crxranks")
1634 register_native("crxranks_get_chat_prefix", "_crxranks_get_chat_prefix")
1635 register_native("crxranks_get_final_flags", "_crxranks_get_final_flags")
1636 register_native("crxranks_get_hudinfo_format", "_crxranks_get_hudinfo_format")
1637 register_native("crxranks_get_max_levels", "_crxranks_get_max_levels")
1638 register_native("crxranks_get_rank_by_level", "_crxranks_get_rank_by_level")
1639 register_native("crxranks_get_save_type", "_crxranks_get_save_type")
1640 register_native("crxranks_get_setting", "_crxranks_get_setting")
1641 register_native("crxranks_get_user_hudinfo", "_crxranks_get_user_hudinfo")
1642 register_native("crxranks_get_user_level", "_crxranks_get_user_level")
1643 register_native("crxranks_get_user_next_rank", "_crxranks_get_user_next_rank")
1644 register_native("crxranks_get_user_next_xp", "_crxranks_get_user_next_xp")
1645 register_native("crxranks_get_user_rank", "_crxranks_get_user_rank")
1646 register_native("crxranks_get_user_xp", "_crxranks_get_user_xp")
1647 register_native("crxranks_get_vault_name", "_crxranks_get_vault_name")
1648 register_native("crxranks_get_vip_flags", "_crxranks_get_vip_flags")
1649 register_native("crxranks_get_xp_for_level", "_crxranks_get_xp_for_level")
1650 register_native("crxranks_get_xp_reward", "_crxranks_get_xp_reward")
1651 register_native("crxranks_give_user_xp", "_crxranks_give_user_xp")
1652 register_native("crxranks_has_user_hudinfo", "_crxranks_has_user_hudinfo")
1653 register_native("crxranks_is_hi_using_dhud", "_crxranks_is_hi_using_dhud")
1654 register_native("crxranks_is_hud_enabled", "_crxranks_is_hud_enabled")
1655 register_native("crxranks_is_sfdn_enabled", "_crxranks_is_sfdn_enabled")
1656 register_native("crxranks_is_sfup_enabled", "_crxranks_is_sfup_enabled")
1657 register_native("crxranks_is_user_on_final", "_crxranks_is_user_on_final")
1658 register_native("crxranks_is_user_vip", "_crxranks_is_user_vip")
1659 register_native("crxranks_is_using_mysql", "_crxranks_is_using_mysql")
1660 register_native("crxranks_is_xpn_enabled", "_crxranks_is_xpn_enabled")
1661 register_native("crxranks_is_xpn_using_dhud", "_crxranks_is_xpn_using_dhud")
1662 register_native("crxranks_set_user_xp", "_crxranks_set_user_xp")
1663 register_native("crxranks_using_comb_events", "_crxranks_using_comb_events")
1664}
1665
1666public _crxranks_get_chat_prefix(iPlugin, iParams)
1667{
1668 set_string(1, CC_PREFIX, get_param(2))
1669}
1670
1671public _crxranks_get_final_flags(iPlugin, iParams)
1672{
1673 set_string(1, g_eSettings[FINAL_LEVEL_FLAGS], get_param(2))
1674 return g_eSettings[FINAL_LEVEL_FLAGS_BIT]
1675}
1676
1677public _crxranks_get_hudinfo_format(iPlugin, iParams)
1678{
1679 set_string(2, g_eSettings[get_param(1) ? HUDINFO_FORMAT_FINAL : HUDINFO_FORMAT], get_param(3))
1680}
1681
1682public _crxranks_get_max_levels(iPlugin, iParams)
1683{
1684 return g_iMaxLevels
1685}
1686
1687public _crxranks_get_rank_by_level(iPlugin, iParams)
1688{
1689 static iLevel
1690 iLevel = get_param(1)
1691
1692 if(iLevel < 1 || iLevel > g_iMaxLevels)
1693 {
1694 return 0
1695 }
1696
1697 static 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 static 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 static iLevel
1762 iLevel = get_param(1)
1763
1764 if(iLevel < 1 || iLevel > g_iMaxLevels)
1765 {
1766 return -1
1767 }
1768
1769 return ArrayGetCell(g_aLevels, iLevel)
1770}
1771
1772public _crxranks_get_xp_reward(iPlugin, iParams)
1773{
1774 static szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
1775 get_string(2, szReward, charsmax(szReward))
1776 return get_xp_reward(get_param(1), szReward)
1777}
1778
1779public _crxranks_give_user_xp(iPlugin, iParams)
1780{
1781 static szReward[CRXRANKS_MAX_XP_REWARD_LENGTH], iReward, id
1782
1783 szReward[0] = EOS
1784 id = get_param(1)
1785 get_string(3, szReward, charsmax(szReward))
1786
1787 if(szReward[0])
1788 {
1789 iReward = get_xp_reward(id, szReward)
1790
1791 if(iReward)
1792 {
1793 give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
1794 }
1795
1796 return iReward
1797 }
1798
1799 iReward = get_param(2)
1800 give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
1801 return iReward
1802}
1803
1804public bool:_crxranks_has_user_hudinfo(iPlugin, iParams)
1805{
1806 return g_ePlayerData[get_param(1)][HudInfoEnabled]
1807}
1808
1809public bool:_crxranks_is_hi_using_dhud(iPlugin, iParams)
1810{
1811 return g_eSettings[HUDINFO_USE_DHUD]
1812}
1813
1814public bool:_crxranks_is_hud_enabled(iPlugin, iParams)
1815{
1816 return g_eSettings[HUDINFO_ENABLED]
1817}
1818
1819public bool:_crxranks_is_sfdn_enabled(iPlugin, iParams)
1820{
1821 return g_eSettings[LEVELDN_SCREEN_FADE_ENABLED]
1822}
1823
1824public bool:_crxranks_is_sfup_enabled(iPlugin, iParams)
1825{
1826 return g_eSettings[LEVELUP_SCREEN_FADE_ENABLED]
1827}
1828
1829public bool:_crxranks_is_user_on_final(iPlugin, iParams)
1830{
1831 return g_ePlayerData[get_param(1)][IsOnFinalLevel]
1832}
1833
1834public bool:_crxranks_is_user_vip(iPlugin, iParams)
1835{
1836 return g_ePlayerData[get_param(1)][IsVIP]
1837}
1838
1839public bool:_crxranks_is_using_mysql(iPlugin, iParams)
1840{
1841 return g_eSettings[USE_MYSQL]
1842}
1843
1844public bool:_crxranks_is_xpn_enabled(iPlugin, iParams)
1845{
1846 return g_eSettings[XP_NOTIFIER_ENABLED]
1847}
1848
1849public bool:_crxranks_set_user_xp(iPlugin, iParams)
1850{
1851 static id, iReturn, CRXRanks_XPSources:iSource
1852 id = get_param(1)
1853 iSource = CRXRanks_XPSources:get_param(3)
1854 g_ePlayerData[id][XP] = clamp(get_param(2), 0)
1855
1856 check_level(id, true)
1857 ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)
1858}
1859
1860public bool:_crxranks_using_comb_events(iPlugin, iParams)
1861{
1862 return g_eSettings[USE_COMBINED_EVENTS]
1863}
1864
1865public bool:_crxranks_is_xpn_using_dhud(iPlugin, iParams)
1866{
1867 return g_eSettings[XP_NOTIFIER_USE_DHUD]
1868}