AMXX-BG.INFO cromchat.inc Raw include

cromchat.inc

Original include source with line numbers.

Back Download .inc
1 #if defined _cromchat_included
2 #endinput
3 #endif
4
5 #define _cromchat_included
6
7 #include <amxmodx>
8 #include <fakemeta>
9
10 #if !defined replace_string
11 #define replace_string replace_all
12 #endif
13
14 #if !defined CC_DONT_OVERWRITE_183_PRINT
15 #define client_print_color CC_SendMatched
16 #define print_team_default CC_COLOR_TEAM
17 #define print_team_grey CC_COLOR_GREY
18 #define print_team_blue CC_COLOR_BLUE
19 #define print_team_red CC_COLOR_RED
20 #endif
21
22 #if !defined CC_DONT_OVERWRITE_COLORCHAT
23 #define ColorChat CC_SendMatched
24 #define NORMAL CC_COLOR_TEAM
25 #define TEAM_COLOR CC_COLOR_TEAM
26 #define GREEN CC_COLOR_TEAM
27 #define GREY CC_COLOR_GREY
28 #define BLUE CC_COLOR_BLUE
29 #define RED CC_COLOR_RED
30 #endif
31
32 #if !defined CC_DONT_OVERWRITE_ACTIVITY
33 #define show_activity CC_ShowActivity
34 #define show_activity_id CC_ShowActivityId
35 #define show_activity_key CC_ShowActivityKey
36 #endif
37
38 #if !defined CC_DONT_OVERWRITE_WPMG
39 #define PrintChatColor CC_SendMatched
40 #define PRINT_COLOR_GREY CC_COLOR_GREY
41 #define PRINT_COLOR_RED CC_COLOR_RED
42 #define PRINT_COLOR_BLUE CC_COLOR_BLUE
43 #define PRINT_COLOR_PLAYERTEAM CC_COLOR_TEAM
44 #endif
45
46 #if !defined CC_DONT_OVERWRITE_CHATPRINT
47 #define ChatPrint CC_SendMessage
48 #endif
49
50 #if !defined CC_PERCENT_REPLACE
51 #define CC_PERCENT_REPLACE "%"
52 #endif
53
54 #define CromChat CC_SendMessage
55
56 const Float:CC_VERSION = 3.3
57 const CC_MAX_ACT_PREFIX_SIZE = 10
58 const CC_MAX_PLAYERS = 32
59 const CC_MAX_PREFIX_SIZE = 64
60 const CC_MAX_MESSAGE_SIZE = 177
61 new const CC_LIBRARY_NAME[] = "cromchat"
62 static const CC_FILTERING_FLAGS[] = "ch"
63
64 #if !defined CC_COLORS_TYPE
65 #define CC_COLORS_TYPE CC_COLORS_CROMCHAT
66 #endif
67
68 #if !defined CC_ACTIVITY_FLAG
69 #define CC_ACTIVITY_FLAG -1
70 #endif
71
72 #if !defined CC_ACTIVITY_PREFIX_PLAYER
73 #define CC_ACTIVITY_PREFIX_PLAYER "PLAYER"
74 #endif
75
76 #if !defined CC_ACTIVITY_PREFIX_ADMIN
77 #define CC_ACTIVITY_PREFIX_ADMIN "ADMIN"
78 #endif
79
80 enum
81 {
82 CC_COLOR_TEAM = CC_MAX_PLAYERS + 25,
83 CC_COLOR_GREY,
84 CC_COLOR_BLUE,
85 CC_COLOR_RED
86 }
87
88 const CC_COLOR_WHITE = CC_COLOR_GREY
89
90 enum
91 {
92 CC_COLORS_CROMCHAT,
93 CC_COLORS_SHORT,
94 CC_COLORS_NAMED,
95 CC_COLORS_NAMED_SHORT,
96 CC_COLORS_STANDARD,
97 CC_COLORS_CUSTOM
98 }
99
100 #define CC_SYM_MENU_YELLOW "\y"
101 #define CC_SYM_MENU_WHITE "\w"
102 #define CC_SYM_MENU_GREY "\d"
103 #define CC_SYM_MENU_RIGHT "\R"
104
105 #define CC_SYM_CHAT_DEF_NORMAL "^x01"
106 #define CC_SYM_CHAT_DEF_TEAM "^x03"
107 #define CC_SYM_CHAT_DEF_GREEN "^x04"
108
109 static bool:CC_FIRST_TIME_ACTIVITY = true, bool:CC_IS_CSCZ, bool:CC_COLOR_FORCE
110 static CC_ACTIVITY_POINTER, CC_COLOR_PLAYER_INDEX
111
112 new CC_PREFIX[CC_MAX_PREFIX_SIZE]
113
114 #if CC_COLORS_TYPE == CC_COLORS_CUSTOM
115 #if !defined CC_SYM_CHAT_NORMAL
116 #define CC_SYM_CHAT_NORMAL "&x01"
117 #endif
118
119 #if !defined CC_SYM_CHAT_TEAM
120 #define CC_SYM_CHAT_TEAM "&x03"
121 #endif
122
123 #if !defined CC_SYM_CHAT_GREEN
124 #define CC_SYM_CHAT_GREEN "&x04"
125 #endif
126
127 #if !defined CC_SYM_CHAT_WHITE
128 #define CC_SYM_CHAT_WHITE "&x05"
129 #endif
130
131 #if !defined CC_SYM_CHAT_BLUE
132 #define CC_SYM_CHAT_BLUE "&x06"
133 #endif
134
135 #if !defined CC_SYM_CHAT_RED
136 #define CC_SYM_CHAT_RED "&x07"
137 #endif
138
139 #if !defined CC_SYM_CHAT_NOPREF
140 #define CC_SYM_CHAT_NOPREF "&x00"
141 #endif
142 #else
143 #if CC_COLORS_TYPE == CC_COLORS_CROMCHAT
144 #define CC_SYM_CHAT_NORMAL "&x01"
145 #define CC_SYM_CHAT_TEAM "&x03"
146 #define CC_SYM_CHAT_GREEN "&x04"
147 #define CC_SYM_CHAT_WHITE "&x05"
148 #define CC_SYM_CHAT_BLUE "&x06"
149 #define CC_SYM_CHAT_RED "&x07"
150 #define CC_SYM_CHAT_NOPREF "&x00"
151 #endif
152
153 #if CC_COLORS_TYPE == CC_COLORS_SHORT
154 #define CC_SYM_CHAT_NORMAL "!n"
155 #define CC_SYM_CHAT_TEAM "!t"
156 #define CC_SYM_CHAT_GREEN "!g"
157 #define CC_SYM_CHAT_WHITE "!w"
158 #define CC_SYM_CHAT_BLUE "!b"
159 #define CC_SYM_CHAT_RED "!r"
160 #define CC_SYM_CHAT_NOPREF "!p"
161 #endif
162
163 #if CC_COLORS_TYPE == CC_COLORS_NAMED
164 #define CC_SYM_CHAT_NORMAL "{normal}"
165 #define CC_SYM_CHAT_TEAM "{team}"
166 #define CC_SYM_CHAT_GREEN "{green}"
167 #define CC_SYM_CHAT_WHITE "{white}"
168 #define CC_SYM_CHAT_BLUE "{blue}"
169 #define CC_SYM_CHAT_RED "{red}"
170 #define CC_SYM_CHAT_NOPREF "{nopref}"
171 #endif
172
173 #if CC_COLORS_TYPE == CC_COLORS_NAMED_SHORT
174 #define CC_SYM_CHAT_NORMAL "{n}"
175 #define CC_SYM_CHAT_TEAM "{t}"
176 #define CC_SYM_CHAT_GREEN "{g}"
177 #define CC_SYM_CHAT_WHITE "{w}"
178 #define CC_SYM_CHAT_BLUE "{b}"
179 #define CC_SYM_CHAT_RED "{r}"
180 #define CC_SYM_CHAT_NOPREF "{p}"
181 #endif
182
183 #if CC_COLORS_TYPE == CC_COLORS_STANDARD
184 #define CC_SYM_CHAT_NORMAL "^1"
185 #define CC_SYM_CHAT_TEAM "^3"
186 #define CC_SYM_CHAT_GREEN "^4"
187 #define CC_SYM_CHAT_WHITE "^5"
188 #define CC_SYM_CHAT_BLUE "^6"
189 #define CC_SYM_CHAT_RED "^7"
190 #define CC_SYM_CHAT_NOPREF "^0"
191 #endif
192 #endif
193
194 static const CC_NO_PREFIX[] = CC_SYM_CHAT_NOPREF
195 static const CC_MENU_COLORS[][] = { CC_SYM_MENU_YELLOW, CC_SYM_MENU_WHITE, CC_SYM_MENU_GREY, CC_SYM_MENU_RIGHT }
196 static const CC_REPLACE_COLORS[][] = { CC_SYM_CHAT_GREEN, CC_SYM_CHAT_DEF_GREEN, CC_SYM_CHAT_TEAM, CC_SYM_CHAT_DEF_TEAM, CC_SYM_CHAT_NORMAL, CC_SYM_CHAT_DEF_NORMAL }
197 static const CC_PLUS_COLORS_STR[][] = { CC_SYM_CHAT_RED, CC_SYM_CHAT_BLUE, CC_SYM_CHAT_WHITE }
198 static const CC_PLUS_COLORS_INT[] = { CC_COLOR_RED, CC_COLOR_BLUE, CC_COLOR_WHITE }
199 static const CC_COLORS_LIST[][] = { CC_SYM_CHAT_RED, CC_SYM_CHAT_BLUE, CC_SYM_CHAT_WHITE, CC_SYM_CHAT_GREEN, CC_SYM_CHAT_TEAM, CC_SYM_CHAT_NORMAL, CC_SYM_CHAT_NOPREF }
200
201 /**
202 * Sends a colored chat message.
203 *
204 * @param id Client index (use 0 to send to all players)
205 * @param input The message to send
206 * @param ... Variable number of formatting parameters
207 *
208 * @return Length of the printed message
209 */
210 stock CC_SendMessage(id, const input[], any:...)
211 {
212 _CC_ModInit()
213 static iPlayers[CC_MAX_PLAYERS], iPnum
214
215 if(id)
216 {
217 if(!is_user_connected(id))
218 {
219 return 0
220 }
221 }
222 else
223 {
224 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
225
226 if(!iPnum)
227 {
228 return 0
229 }
230 }
231
232 static szMessage[CC_MAX_MESSAGE_SIZE], bool:bNoPrefix, i
233 vformat(szMessage[1], charsmax(szMessage), input, 3)
234 szMessage[0] = 0x01
235
236 bNoPrefix = bool:(equal(szMessage[1], CC_NO_PREFIX, charsmax(CC_NO_PREFIX)) || equal(szMessage[2], CC_NO_PREFIX, charsmax(CC_NO_PREFIX)))
237
238 if(bNoPrefix)
239 {
240 replace(szMessage, charsmax(szMessage), CC_NO_PREFIX, "")
241 }
242 else if(CC_PREFIX[0])
243 {
244 if(CC_IS_CSCZ)
245 {
246 format(szMessage, charsmax(szMessage), "%s%s %s%s", CC_SYM_CHAT_DEF_NORMAL, CC_PREFIX, CC_SYM_CHAT_DEF_NORMAL, szMessage)
247 }
248 else
249 {
250 format(szMessage, charsmax(szMessage), "%s%s %s", CC_SYM_CHAT_DEF_NORMAL, CC_PREFIX, szMessage)
251 }
252 }
253
254 for(i = 0; i < sizeof(CC_REPLACE_COLORS) - 1; i += 2)
255 {
256 if(CC_IS_CSCZ)
257 {
258 replace_string(szMessage, charsmax(szMessage), CC_REPLACE_COLORS[i], CC_REPLACE_COLORS[i + 1])
259 }
260 else
261 {
262 replace_string(szMessage, charsmax(szMessage), CC_REPLACE_COLORS[i], "")
263 }
264 }
265
266 for(i = 0; i < sizeof(CC_PLUS_COLORS_STR); i++)
267 {
268 if(contain(szMessage, CC_PLUS_COLORS_STR[i]) != -1)
269 {
270 if(!CC_COLOR_FORCE)
271 {
272 CC_COLOR_PLAYER_INDEX = CC_PLUS_COLORS_INT[i]
273 }
274
275 for(i = 0; i < 3; i++)
276 {
277 if(CC_IS_CSCZ)
278 {
279 replace_string(szMessage, charsmax(szMessage), CC_COLORS_LIST[i], CC_SYM_CHAT_DEF_TEAM)
280 }
281 else
282 {
283 replace_string(szMessage, charsmax(szMessage), CC_COLORS_LIST[i], "")
284 }
285 }
286
287 break
288 }
289 }
290
291 if(id)
292 {
293 _CC_WriteMessage(id, szMessage)
294 }
295 else
296 {
297 for(i = 0; i < iPnum; i++)
298 {
299 _CC_WriteMessage(iPlayers[i], szMessage)
300 }
301 }
302
303 CC_COLOR_FORCE = false
304 CC_COLOR_PLAYER_INDEX = 0
305
306 return strlen(szMessage)
307 }
308
309 /**
310 * Sends a colored chat message matching a specific player's color.
311 *
312 * @note You can use the "player" argument to set a specific color instead of matching
313 * it automtaically. To do this, you can use one of the following color arguments:
314 * CC_COLOR_TEAM, CC_COLOR_GREY (or CC_COLOR_WHITE), CC_COLOR_BLUE, CC_COLOR_RED.
315 *
316 * @param id Client index (use 0 to send to all players)
317 * @param player Matching player's index
318 * @param input The message to send
319 * @param ... Variable number of formatting parameters
320 *
321 * @return Length of the printed message
322 */
323 stock CC_SendMatched(id, player, const input[], any:...)
324 {
325 static szMessage[CC_MAX_MESSAGE_SIZE]
326 vformat(szMessage[1], charsmax(szMessage), input, 4)
327 szMessage[0] = 0x01
328 CC_COLOR_PLAYER_INDEX = player
329 return CC_SendMessage(id, szMessage)
330 }
331
332 /**
333 * Sends a colored chat message to a group of players matching the flags from the get_players() function.
334 *
335 * @note The filtering flags are the same that are used by the get_players() function
336 *
337 * @param flags Filtering flags
338 * @param params String to match against if the flags require it
339 * @param input The message to send
340 * @param ... Variable number of formatting parameters
341 *
342 * @return Length of the printed message or 0 if no players were matched
343 */
344 stock CC_GroupMessage(const flags[] = "", const params[] = "", const input[], any:...)
345 {
346 static szMessage[CC_MAX_MESSAGE_SIZE], iPlayers[CC_MAX_PLAYERS], iPnum
347 vformat(szMessage, charsmax(szMessage), input, 4)
348 get_players(iPlayers, iPnum, flags, params)
349
350 if(!iPnum)
351 {
352 return 0
353 }
354
355 static bool:bForce, iColor, i
356
357 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
358 {
359 CC_SetColor(iColor, bForce)
360 CC_SendMessage(iPlayers[i], szMessage)
361 }
362
363 return strlen(szMessage)
364 }
365
366 /**
367 * Sends a colored chat message to all players who have the specified admin flags.
368 *
369 * @param flags Admin flags
370 * @param allflags If set to true it will match players who have ALL of the specified admin flags, otherwise it will match players with ANY of the flags
371 * @param input The message to send
372 * @param ... Variable number of formatting parameters
373 *
374 * @return Length of the printed message or 0 if no players were matched
375 */
376 stock CC_SendAdminMessage(const flags[] = "", bool:allflags = true, const input[], any:...)
377 {
378 static szMessage[CC_MAX_MESSAGE_SIZE], iPlayers[CC_MAX_PLAYERS], iPnum
379 vformat(szMessage, charsmax(szMessage), input, 4)
380 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
381
382 if(!iPnum)
383 {
384 return 0
385 }
386
387 static bool:bForce, iColor, iCount, iFlags, iPlayer, i
388 iFlags = read_flags(flags)
389 iCount = 0
390
391 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
392 {
393 iPlayer = iPlayers[i]
394
395 switch(allflags)
396 {
397 case true:
398 {
399 if(get_user_flags(iPlayer) & iFlags != iFlags)
400 {
401 continue
402 }
403 }
404 case false:
405 {
406 if(!(get_user_flags(iPlayer) & iFlags))
407 {
408 continue
409 }
410 }
411 }
412
413 iCount++
414
415 CC_SetColor(iColor, bForce)
416 CC_SendMessage(iPlayer, szMessage)
417 }
418
419 if(!iCount)
420 {
421 return 0
422 }
423
424 return strlen(szMessage)
425 }
426
427 /**
428 * Sends a colored chat message and logs it at the same time.
429 *
430 * @note If the file name is not set, the default log file will be used instead.
431 *
432 * @param id Client index (use 0 to send to all players)
433 * @param file The log file that will be used
434 * @param input The message to send
435 * @param ... Variable number of formatting parameters
436 *
437 * @return Length of the printed message
438 */
439 stock CC_LogMessage(id, const file[] = "", const input[], any:...)
440 {
441 static szMessage[CC_MAX_MESSAGE_SIZE]
442 vformat(szMessage, charsmax(szMessage), input, 4)
443
444 if(!CC_SendMessage(id, szMessage))
445 {
446 return 0
447 }
448
449 CC_RemoveColors(szMessage, charsmax(szMessage))
450 file[0] ? log_to_file(file, szMessage) : log_amx(szMessage)
451 return strlen(szMessage)
452 }
453
454 /**
455 * Sends a colored chat message to all players that obeys the amx_show_activity cvar.
456 *
457 * @note This function is made to mimic the show_activity() function, but sends a
458 * colored chat message instead using the CC_SendMessage() function. This means
459 * that the default AMXX function can directly be replaced with this one in order
460 * for it to display a colored chat message rather than a default one.
461 * @note By default, cromchat.inc will replace all show_activity() functions in the file
462 * with the CC_ShowActivity() function. You can disable this feature by adding
463 * #define CC_DONT_OVERWRITE_ACTIVITY before #include <cromchat> in your plugin.
464 *
465 * @param id Client index performing the action
466 * @param name Name of client performing the action
467 * @param input Formatting rules
468 * @param ... Variable number of formatting parameters
469 *
470 * @noreturn
471 */
472 stock CC_ShowActivity(id, const name[], const input[], any:...)
473 {
474 if(CC_FIRST_TIME_ACTIVITY)
475 {
476 _CC_ActivityInit()
477 }
478
479 static szMessage[CC_MAX_MESSAGE_SIZE], szPrefix[CC_MAX_ACT_PREFIX_SIZE], iPlayers[CC_MAX_PLAYERS], bool:bForce, iPlayer, iPnum, iColor, i
480 vformat(szMessage, charsmax(szMessage), input, 4)
481 _CC_GetActivityPrefix(id, szPrefix, charsmax(szPrefix))
482
483 switch(get_pcvar_num(CC_ACTIVITY_POINTER))
484 {
485 case 1: CC_SendMessage(0, "%L: %s", LANG_PLAYER, szPrefix, szMessage)
486 case 2: CC_SendMessage(0, "%L %s: %s", LANG_PLAYER, szPrefix, name, szMessage)
487 case 3:
488 {
489 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
490
491 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
492 {
493 iPlayer = iPlayers[i]
494 CC_SetColor(iColor, bForce)
495
496 if(_CC_IsActivityAdmin(iPlayer))
497 {
498 CC_SendMessage(iPlayer, "%L %s: %s", iPlayer, szPrefix, name, szMessage)
499 }
500 else
501 {
502 CC_SendMessage(iPlayer, "%L: %s", iPlayer, szPrefix, szMessage)
503 }
504 }
505 }
506 case 4:
507 {
508 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
509
510 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
511 {
512 iPlayer = iPlayers[i]
513
514 if(_CC_IsActivityAdmin(iPlayer))
515 {
516 CC_SetColor(iColor, bForce)
517 CC_SendMessage(iPlayer, "%L %s: %s", iPlayer, szPrefix, name, szMessage)
518 }
519 }
520 }
521 case 5:
522 {
523 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
524
525 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
526 {
527 iPlayer = iPlayers[i]
528
529 if(_CC_IsActivityAdmin(iPlayer))
530 {
531 CC_SetColor(iColor, bForce)
532 CC_SendMessage(iPlayer, "%L: %s", iPlayer, szPrefix, szMessage)
533 }
534 }
535 }
536 }
537 }
538
539 /**
540 * Sends a colored chat message to a single client that obeys the amx_show_activity cvar.
541 *
542 * @note This function is made to mimic the show_activity_id() function, but sends a
543 * colored chat message instead using the CC_SendMessage() function. This means
544 * that the default AMXX function can directly be replaced with this one in order
545 * for it to display a colored chat message rather than a default one.
546 * @note By default, cromchat.inc will replace all show_activity_id() functions in the file
547 * with the CC_ShowActivityId() function. You can disable this feature by adding
548 * #define CC_DONT_OVERWRITE_ACTIVITY before #include <cromchat> in your plugin.
549 *
550 * @param target Client index to display message to
551 * @param id Client index performing the action
552 * @param name Name of client performing the action
553 * @param input Formatting rules
554 * @param ... Variable number of formatting parameters
555 *
556 * @noreturn
557 */
558 stock CC_ShowActivityId(target, id, const name[], const input[], any:...)
559 {
560 if(!is_user_connected(target))
561 {
562 return
563 }
564
565 if(CC_FIRST_TIME_ACTIVITY)
566 {
567 _CC_ActivityInit()
568 }
569
570 static szMessage[CC_MAX_MESSAGE_SIZE], szPrefix[CC_MAX_ACT_PREFIX_SIZE]
571 vformat(szMessage, charsmax(szMessage), input, 5)
572 _CC_GetActivityPrefix(id, szPrefix, charsmax(szPrefix))
573
574 switch(get_pcvar_num(CC_ACTIVITY_POINTER))
575 {
576 case 1: CC_SendMessage(target, "%L: %s", target, szPrefix, szMessage)
577 case 2: CC_SendMessage(target, "%L %s: %s", target, szPrefix, name, szMessage)
578 case 3:
579 {
580 if(_CC_IsActivityAdmin(target))
581 {
582 CC_SendMessage(target, "%L %s: %s", target, szPrefix, name, szMessage)
583 }
584 else
585 {
586 CC_SendMessage(target, "%L: %s", target, szPrefix, szMessage)
587 }
588 }
589 case 4:
590 {
591 if(_CC_IsActivityAdmin(target))
592 {
593 CC_SendMessage(target, "%L %s: %s", target, szPrefix, name, szMessage)
594 }
595 }
596 case 5:
597 {
598 if(_CC_IsActivityAdmin(target))
599 {
600 CC_SendMessage(target, "%L: %s", target, szPrefix, szMessage)
601 }
602 }
603 }
604 }
605
606 /**
607 * Sends a colored chat message to all clients using nromal language keys that obeys the amx_show_activity cvar.
608 *
609 * @note This function is made to mimic the show_activity_key() function, but sends a
610 * colored chat message instead using the CC_SendMessage() function. This means
611 * that the default AMXX function can directly be replaced with this one in order
612 * for it to display a colored chat message rather than a default one.
613 * @note By default, cromchat.inc will replace all show_activity_key() functions in the file
614 * with the CC_ShowActivityKey() function. You can disable this feature by adding
615 * #define CC_DONT_OVERWRITE_ACTIVITY before #include <cromchat> in your plugin.
616 *
617 * @param without The language key that does not have the name field
618 * @param with The language key that does have the name field
619 * @param name The name of the person doing the action
620 * @param ... Pass any extra format arguments for the language key in the variable arguments list
621 *
622 * @noreturn
623 */
624 stock CC_ShowActivityKey(const without[], const with[], const name[], any:...)
625 {
626 #pragma unused name
627
628 if(CC_FIRST_TIME_ACTIVITY)
629 {
630 _CC_ActivityInit()
631 }
632
633 static szMessage[CC_MAX_MESSAGE_SIZE], szKey[CC_MAX_MESSAGE_SIZE], iPlayers[CC_MAX_PLAYERS], bool:bForce, iPnum, iPlayer, iColor, i
634
635 switch(get_pcvar_num(CC_ACTIVITY_POINTER))
636 {
637 case 1:
638 {
639 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
640
641 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
642 {
643 iPlayer = iPlayers[i]
644 CC_SetColor(iColor, bForce)
645
646 LookupLangKey(szKey, charsmax(szKey), without, iPlayer)
647 vformat(szMessage, charsmax(szMessage), szKey, 4)
648 CC_SendMessage(iPlayer, szMessage)
649 }
650 }
651 case 2:
652 {
653 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
654
655 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
656 {
657 iPlayer = iPlayers[i]
658 CC_SetColor(iColor, bForce)
659
660 LookupLangKey(szKey, charsmax(szKey), with, iPlayer)
661 vformat(szMessage, charsmax(szMessage), szKey, 3)
662 CC_SendMessage(iPlayer, szMessage)
663 }
664 }
665 case 3:
666 {
667 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
668
669 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
670 {
671 iPlayer = iPlayers[i]
672 CC_SetColor(iColor, bForce)
673
674 if(_CC_IsActivityAdmin(iPlayer))
675 {
676 LookupLangKey(szKey, charsmax(szKey), with, iPlayer)
677 vformat(szMessage, charsmax(szMessage), szKey, 3)
678 }
679 else
680 {
681 LookupLangKey(szKey, charsmax(szKey), without, iPlayer)
682 vformat(szMessage, charsmax(szMessage), szKey, 4)
683 }
684
685 CC_SendMessage(iPlayer, szMessage)
686 }
687 }
688 case 4:
689 {
690 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
691
692 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
693 {
694 iPlayer = iPlayers[i]
695
696 if(_CC_IsActivityAdmin(iPlayer))
697 {
698 CC_SetColor(iColor, bForce)
699 LookupLangKey(szKey, charsmax(szKey), with, iPlayer)
700 vformat(szMessage, charsmax(szMessage), szKey, 3)
701 CC_SendMessage(iPlayer, szMessage)
702 }
703 }
704 }
705 case 5:
706 {
707 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
708
709 for(bForce = CC_COLOR_FORCE, iColor = CC_COLOR_PLAYER_INDEX, i = 0; i < iPnum; i++)
710 {
711 iPlayer = iPlayers[i]
712
713 if(_CC_IsActivityAdmin(iPlayer))
714 {
715 CC_SetColor(iColor, bForce)
716 LookupLangKey(szKey, charsmax(szKey), without, iPlayer)
717 vformat(szMessage, charsmax(szMessage), szKey, 4)
718 CC_SendMessage(iPlayer, szMessage)
719 }
720 }
721 }
722 }
723 }
724
725 /**
726 * Removes the color codes from a message.
727 *
728 * @param message The message to remove colors from
729 * @param len Maximum message length
730 * @param chat If set to true, it will remove the chat color codes
731 * @param menu If set to true, it will remove the menu color codes
732 *
733 * @noreturn
734 */
735 stock CC_RemoveColors(message[], len, bool:chat = true, bool:menu = false)
736 {
737 static i
738
739 if(chat)
740 {
741 for(i = 0; i < sizeof(CC_COLORS_LIST); i++)
742 {
743 replace_string(message, len, CC_COLORS_LIST[i], "")
744 }
745 }
746
747 if(menu)
748 {
749 for(i = 0; i < sizeof(CC_MENU_COLORS); i++)
750 {
751 replace_string(message, len, CC_MENU_COLORS[i], "")
752 }
753 }
754 }
755
756 /**
757 * Removes exploits from the message.
758 *
759 * @note You can change the '%' replacement symbol by adding #define CC_PERCENT_REPLACE "symbol here" before #include <cromchat>
760 * @note It is strongly advised to use this function whenever you're sending messages based on hooking "say" or "say_team"
761 *
762 * @param message The message to remove exploits from
763 * @param len Maximum message length
764 * @param colors If set to true, it will remove the ETX, EOT & SOH chat color codes;
765 * this prevents player from manually changing their chat color when they have the chance to
766 * @param percent If set to true, it will replace the '%' symbol with '%'
767 *
768 * @noreturn
769 */
770 stock CC_RemoveExploits(message[], len, bool:colors = true, bool:percent = true)
771 {
772 static i
773
774 if(colors)
775 {
776 static const CC_COLOR_EXPLOITS[][] = { "", "", "" }
777
778 for(i = 0; i < sizeof(CC_COLOR_EXPLOITS); i++)
779 {
780 replace_string(message, len, CC_COLOR_EXPLOITS[i], "")
781 }
782 }
783
784 if(percent)
785 {
786 static const CC_PERCENT_FIND[] = "%"
787 replace_string(message, len, CC_PERCENT_FIND, CC_PERCENT_REPLACE)
788 }
789 }
790
791 /**
792 * Sets a global prefix that will be used for all sent messages.
793 *
794 * @note The prefix can be removed in a given message if the prefix-removing symbol is
795 * used in the beginning of the message. By default, this symbol is equal to &x00.
796 *
797 * @param prefix Prefix to set
798 *
799 * @noreturn
800 */
801 stock CC_SetPrefix(const prefix[])
802 {
803 _CC_ModInit()
804 copy(CC_PREFIX, charsmax(CC_PREFIX), prefix)
805
806 if(!CC_IS_CSCZ)
807 {
808 CC_RemoveColors(CC_PREFIX, charsmax(CC_PREFIX))
809 }
810 }
811
812 /**
813 * Removes the global message prefix.
814 *
815 * @noreturn
816 */
817 stock CC_RemovePrefix()
818 {
819 CC_PREFIX[0] = EOS
820 }
821
822 /**
823 * Sets the team color for the next message that's going to be sent.
824 *
825 * @param index CC_COLOR_* or player index to get color from
826 * @param force If set to true, custom colors in the code will be ignored
827 * and the message will be forced to use the color set here
828 *
829 * @noreturn
830 */
831 stock CC_SetColor(index, bool:force = false)
832 {
833 CC_COLOR_PLAYER_INDEX = index
834 CC_COLOR_FORCE = force
835 }
836
837 /**
838 * This function is used by the other stocks in order to send a raw message.
839 *
840 * @param id Client index
841 * @param message The message to send
842 *
843 * @noreturn
844 */
845 stock _CC_WriteMessage(id, const message[])
846 {
847 static CC_INIT, CC_MSG_SAYTEXT
848
849 if(!CC_INIT)
850 {
851 CC_INIT = true
852 CC_MSG_SAYTEXT = get_user_msgid("SayText")
853
854 // Credits to WPMGPRoSToTeMa
855 if(!LibraryExists(CC_LIBRARY_NAME, LibType_Library))
856 {
857 register_library(CC_LIBRARY_NAME)
858
859 if(CC_IS_CSCZ)
860 {
861 new iCacheList[] = { CC_COLOR_GREY, CC_COLOR_BLUE, CC_COLOR_RED }
862 new szCacheList[][] = { "", "CT", "TERRORIST" }
863 new CC_MSG_TEAMINFO = get_user_msgid("TeamInfo")
864
865 for(new i; i < sizeof(iCacheList); i++)
866 {
867 engfunc(EngFunc_MessageBegin, MSG_INIT, CC_MSG_TEAMINFO, 0, 0)
868 write_byte(iCacheList[i])
869 write_string(szCacheList[i])
870 message_end()
871 }
872
873 new iPlayers[CC_MAX_PLAYERS], iPnum
874 get_players(iPlayers, iPnum, CC_FILTERING_FLAGS)
875
876 for(new iPlayer, i, j; i < iPnum; i++)
877 {
878 iPlayer = iPlayers[i]
879
880 for(j = 0; j < sizeof(iCacheList); j++)
881 {
882 message_begin(MSG_ONE, CC_MSG_TEAMINFO, _, iPlayer)
883 write_byte(iCacheList[j])
884 write_string(szCacheList[j])
885 message_end()
886 }
887 }
888 }
889 }
890 }
891
892 static const CC_PLAYER_ITEM_PHRASE[] = "#Spec_PlayerItem" // Credits to WPMGPRoSToTeMa
893
894 message_begin(MSG_ONE, CC_MSG_SAYTEXT, _, id)
895
896 if(CC_IS_CSCZ)
897 {
898 write_byte(CC_COLOR_PLAYER_INDEX && CC_COLOR_PLAYER_INDEX != CC_COLOR_TEAM ? CC_COLOR_PLAYER_INDEX : id)
899 }
900 else
901 {
902 write_byte(id)
903 }
904
905 write_string(CC_PLAYER_ITEM_PHRASE)
906 write_string(message)
907 message_end()
908 }
909
910 /**
911 * Checks if the server is running Counter-Strike.
912 *
913 * @noreturn
914 */
915 stock _CC_ModInit()
916 {
917 static bool:CC_MOD_INIT
918
919 if(!CC_MOD_INIT)
920 {
921 CC_MOD_INIT = true
922
923 static const CC_CSTRIKE_MODNAME[] = "cstrike"
924 static const CC_CZERO_MODNAME[] = "czero"
925
926 new szModName[sizeof(CC_CSTRIKE_MODNAME)]
927 get_modname(szModName, charsmax(szModName))
928
929 if(equal(szModName, CC_CSTRIKE_MODNAME) || equal(szModName, CC_CZERO_MODNAME))
930 {
931 CC_IS_CSCZ = true
932 }
933 }
934 }
935
936 /**
937 * Stores the amx_show_activity pointer for use with "ShowActivity" functions.
938 *
939 * @noreturn
940 */
941 stock _CC_ActivityInit()
942 {
943 CC_FIRST_TIME_ACTIVITY = false
944 CC_ACTIVITY_POINTER = get_cvar_pointer("amx_show_activity")
945
946 if(!CC_ACTIVITY_POINTER)
947 {
948 CC_ACTIVITY_POINTER = register_cvar("amx_show_activity", "2", FCVAR_PROTECTED)
949 }
950 }
951
952 /**
953 * Returns the player prefix used with "ShowActivity" functions.
954 *
955 * @param id Client index
956 * @param buffer Buffer to store the prefix in
957 * @param len Maximum buffer length
958 *
959 * @noreturn
960 */
961 stock _CC_GetActivityPrefix(id, buffer[CC_MAX_ACT_PREFIX_SIZE], len)
962 {
963 copy(buffer, len, _CC_IsActivityAdmin(id) ? CC_ACTIVITY_PREFIX_ADMIN : CC_ACTIVITY_PREFIX_PLAYER)
964 }
965
966 /**
967 * Checks whether the client has the required flag to be marked as an admin for the "ShowActivity" functions.
968 *
969 * @param id Client index
970 *
971 * @return True if he has, false otherwise
972 */
973 stock bool:_CC_IsActivityAdmin(const id)
974 {
975 #if CC_ACTIVITY_FLAG == -1
976 static iFlags
977 iFlags = get_user_flags(id)
978 return (iFlags > 0 && !(iFlags & ADMIN_USER))
979 #else
980 return bool:(get_user_flags(id) & CC_ACTIVITY_FLAG)
981 #endif
982 }