#define PLUGIN "Server Messages"
#define AUTHOR "Leon McVeran"
#define VERSION "v1.4"
#define PDATE "22nd September 2009"
#include <amxmodx>
#include <amxmisc>
#include <vault>
new const g_szFileName[] = "server_messages.txt"
#define ACCESS_PRINT_MSG ADMIN_CHAT
#define ACCESS_LIST_MSG ADMIN_ALL
#define TASK_REMOVE_TUTOR 8000
#define TASK_SHOW_MESSAGE 8033
// Don't modify any defines under this line, otherwise it could lead to an error
#define SM_MESSAGES (1<<0)
#define SM_RULES (1<<1)
#define SM_INFOS (1<<2)
#define SKIP_NOTHING 0
#define SKIP_DEAD (1<<0)
#define SKIP_ALIVE (1<<1)
#define SKIP_BOTS (1<<2)
#define SKIP_REAL (1<<3)
new bool:g_bMsgEnabled[33]
new g_iActivity[33]
new g_iMsgCount
new g_iRuleCount
new g_iInfoCount
new g_szFilePath[64]
new g_szLastMsg[3][16]
new CVAR_msg_mode
new CVAR_msg_show
new CVAR_msg_style
new CVAR_rule_mode
new CVAR_rule_show
new CVAR_rule_style
new CVAR_rule_prefix
new CVAR_info_mode
new CVAR_info_show
new CVAR_info_style
new CVAR_min_activity
new CVAR_show_frequency
new CVAR_show_skip
new CVAR_show_time
new CVAR_tutor_sound
new CVAR_tutor_warn
new gMsgTutorClose
new gMsgTutorText
new gMsgSayText
public plugin_init(){
register_plugin(PLUGIN, VERSION, AUTHOR)
register_dictionary(g_szFileName)
if (is_running("czero") || is_running("cstrike")){
register_event("HLTV", "event_freezetime_start", "a", "1=0", "2=0")
register_concmd("amx_print_custom", "cmd_custom_print", ACCESS_PRINT_MSG, "<authid, nick, @group or #userid> <your message> [optional: <mode> <style>]")
register_concmd("amx_print_msg", "cmd_server_print", ACCESS_PRINT_MSG, "<authid, nick, @group or #userid> <msg number> [optional: <mode> <style>]")
register_concmd("amx_print_rule", "cmd_server_print", ACCESS_PRINT_MSG, "<authid, nick, @group or #userid> <rule number> [optional: <mode> <style>]")
register_concmd("amx_print_info", "cmd_server_print", ACCESS_PRINT_MSG, "<authid, nick, @group or #userid> <info number> [optional: <mode> <style>]")
register_concmd("amx_list_msg", "cmd_server_list", ACCESS_LIST_MSG, "- shows a list of all server messages")
register_concmd("amx_list_rule", "cmd_server_list", ACCESS_LIST_MSG, "- shows a list of all server rules")
register_concmd("amx_list_info", "cmd_server_list", ACCESS_LIST_MSG, "- shows a list of all server informations")
register_clcmd("joinclass", "cmd_joinclass") // New VGUI Menu
register_menucmd(register_menuid("Terrorist_Select", 1), 511, "cmd_joinclass") // Old Style Menu
register_menucmd(register_menuid("CT_Select", 1), 511, "cmd_joinclass") // Old Style Menu
CVAR_msg_mode = register_cvar("sm_msg_mode", "3")
CVAR_msg_show = register_cvar("sm_msg_show", "1")
CVAR_msg_style = register_cvar("sm_msg_style", "0")
CVAR_rule_mode = register_cvar("sm_rule_mode", "4")
CVAR_rule_show = register_cvar("sm_rule_show", "1")
CVAR_rule_style = register_cvar("sm_rule_style", "3")
CVAR_rule_prefix = register_cvar("sm_rule_prefix", "1")
CVAR_info_mode = register_cvar("sm_info_mode", "4")
CVAR_info_show = register_cvar("sm_info_show", "1")
CVAR_info_style = register_cvar("sm_info_style", "0")
CVAR_min_activity = register_cvar("sm_min_activity", "4320")
CVAR_show_frequency = register_cvar("sm_show_frequency", "15")
CVAR_show_skip = register_cvar("sm_show_skip", "2")
CVAR_show_time = register_cvar("sm_show_time", "8")
CVAR_tutor_sound = register_cvar("sm_tutor_sound", "0")
CVAR_tutor_warn = register_cvar("sm_tutor_warn", "1")
}
else{
new ErrMsg[256]
format(ErrMsg, 255, "[AMXX] Nem sikerult betolteni a %s fajlt.", PLUGIN)
set_fail_state(ErrMsg)
}
}
public plugin_precache(){
precache_generic("gfx/career/icon_!.tga")
precache_generic("gfx/career/icon_!-bigger.tga")
precache_generic("gfx/career/icon_i.tga")
precache_generic("gfx/career/icon_i-bigger.tga")
precache_generic("gfx/career/icon_skulls.tga")
precache_generic("gfx/career/round_corner_ne.tga")
precache_generic("gfx/career/round_corner_nw.tga")
precache_generic("gfx/career/round_corner_se.tga")
precache_generic("gfx/career/round_corner_sw.tga")
precache_generic("resource/TutorScheme.res")
precache_generic("resource/UI/TutorTextWindow.res")
precache_sound("events/enemy_died.wav")
precache_sound("events/friend_died.wav")
precache_sound("events/task_complete.wav")
precache_sound("events/tutor_msg.wav")
}
public plugin_cfg(){
gMsgTutorClose = get_user_msgid("TutorClose")
gMsgTutorText = get_user_msgid("TutorText")
gMsgSayText = get_user_msgid("SayText")
// Store the path to our used txt-file
get_datadir(g_szFilePath, 63)
format(g_szFilePath, 63, "%s/lang/%s", g_szFilePath, g_szFileName)
new iLanguages
if (file_exists(g_szFilePath)){
new szMsg[32], szBuffer[128], szLastMsg[32], fp=fopen(g_szFilePath, "r")
while (!feof(fp) && iLanguages < 2){
szBuffer[0]='^0'
fgets(fp, szBuffer, 127)
parse(szBuffer, szMsg, 31)
if (!equali(szMsg, szLastMsg)){
// Saves the current message for blocking duplicative messages
copy(szLastMsg, 31, szMsg)
if (equali(szMsg, "SERVER_MSG_", 11)){
g_iMsgCount+=1
}
else if (equali(szMsg, "SERVER_RULE_", 12)){
g_iRuleCount+=1
}
else if (equali(szMsg, "SERVER_INFO_", 12)){
g_iInfoCount+=1
}
// Stop loop if we reached the second language
else if (szMsg[0] == '[' && szMsg[3] == ']'){
iLanguages+=1
}
}
}
fclose(fp)
}
else{
server_print("%L", LANG_SERVER, "SM_ERROR_FILE")
}
}
/* == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
EVENTS
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==*/
public client_authorized(id){
if (!is_user_bot(id)){
LoadData(id)
}
}
public client_disconnect(id){
if (!is_user_bot(id)){
SaveData(id)
Remove_TutorMsg(id)
}
}
public event_freezetime_start(){
// Without this event, we can not change the frequency or duration of messages
remove_task(TASK_SHOW_MESSAGE)
set_task(get_pcvar_num(CVAR_show_frequency) < get_pcvar_num(CVAR_show_time) ? get_pcvar_float(CVAR_show_time) + 1.0 : get_pcvar_float(CVAR_show_frequency), "func_show_message", TASK_SHOW_MESSAGE, _, _, "b")
}
/* == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
COMMANDS
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==*/
public cmd_joinclass(id){
if (get_pcvar_num(CVAR_tutor_warn) && !is_user_bot(id)){
new szMsg[256]
if (g_iActivity[id] == 0) format(szMsg, 255, "%L", id, "SM_RESTART_THE_GAME")
if (g_iActivity[id] <= 60) format(szMsg, 255, "%L", id, "SM_CAN_NOT_READ")
if (strlen(szMsg)){
replace_all(szMsg, 254, "\n", "^n")
set_hudmessage(240, 0, 0, -1.0, 0.65, 2, 0.1, 16.0, 0.02, 0.02, 8)
show_hudmessage(id, szMsg)
}
}
}
public cmd_custom_print(id, level, cid){
if (!cmd_access(id, level, cid, 3)){
return PLUGIN_HANDLED
}
new szTarget[32], szMsg[256], szMode[4], szStyle[4], szAdminName[32], szTargetName[32]
read_argv(1, szTarget, 31)
read_argv(2, szMsg, 255)
read_argv(3, szMode, 3)
read_argv(4, szStyle, 3)
get_user_name(id, szAdminName, 31)
// Check if the third parameter a number or not
if (strlen(szMode)){
if (!is_str_num(szMode)){
client_print(id, print_console, "%L", LANG_PLAYER, "SM_CUSTOM_USAGE")
return PLUGIN_HANDLED
}
}
// Define mode and style of the message (defaults: mode 4 and style 0)
new iMode = strlen(szMode) ? str_to_num(szMode) : 4
new iStyle = strlen(szStyle) ? str_to_num(szStyle) : 0
// Let's go, print the messages on clients
if (szTarget[0] == '@'){
new iPlayers[32], pNum
if (get_cmd_targets(id, szTarget, iPlayers, pNum, szTargetName, SKIP_BOTS)){
for (new p = 0; p < pNum; p++){
func_print_message(iPlayers[p], szMsg, iMode, iStyle, true)
}
}
}
else{
new iPlayer = cmd_target(id, szTarget, 8)
if (!iPlayer) return PLUGIN_HANDLED
get_user_name(iPlayer, szTargetName, 31)
func_print_message(iPlayer, szMsg, iMode, iStyle, true)
}
if (strlen(szTargetName)){
log_amx("%L", LANG_SERVER, "SM_PRINT_LOG", szAdminName, szTargetName, szMsg, iMode, iStyle)
}
return PLUGIN_HANDLED
}
public cmd_server_print(id, level, cid){
if (!cmd_access(id, level, cid, 3)){
return PLUGIN_HANDLED
}
new szCommand[32], szTarget[32], szNumber[4], szMode[4], szStyle[4], szAdminName[32], szTargetName[32]
read_argv(0, szCommand, 31)
read_argv(1, szTarget, 31)
read_argv(2, szNumber, 3)
read_argv(3, szMode, 3)
read_argv(4, szStyle, 3)
get_user_name(id, szAdminName, 31)
// Define which type of message are used
new szSearchedMsg[20], iMode, iStyle, bool:bPrefix
if (equal(szCommand, "amx_print_msg")){
copy(szSearchedMsg, 19, "SERVER_MSG_")
iMode = strlen(szMode) ? str_to_num(szMode) : get_pcvar_num(CVAR_msg_mode)
iStyle = strlen(szStyle) ? str_to_num(szStyle) : get_pcvar_num(CVAR_msg_style)
}
else if (equal(szCommand, "amx_print_rule")){
copy(szSearchedMsg, 19, "SERVER_RULE_")
iMode = strlen(szMode) ? str_to_num(szMode) : get_pcvar_num(CVAR_rule_mode)
iStyle = strlen(szStyle) ? str_to_num(szStyle) : get_pcvar_num(CVAR_rule_style)
bPrefix = get_pcvar_num(CVAR_rule_prefix) ? true : false
}
else if (equal(szCommand, "amx_print_info")){
copy(szSearchedMsg, 19, "SERVER_INFO_")
iMode = strlen(szMode) ? str_to_num(szMode) : get_pcvar_num(CVAR_info_mode)
iStyle = strlen(szStyle) ? str_to_num(szStyle) : get_pcvar_num(CVAR_info_style)
}
// Technically we should never get here
if (!strlen(szSearchedMsg)){
client_print(id, print_console, "%L", LANG_PLAYER, "SM_ERROR_SEARCH")
return PLUGIN_HANDLED
}
// Check if the second parameter a number or not
if (!is_str_num(szNumber)){
client_print(id, print_console, "%L", LANG_PLAYER, "SM_ERROR_NUMBER")
return PLUGIN_HANDLED
}
// Merge the different parameters to define and check the message.
add(szSearchedMsg, 19, szNumber)
if (!is_msg_valid(szSearchedMsg)){
client_print(id, print_console, "%L", LANG_PLAYER, "SM_ERROR_MESSAGE")
return PLUGIN_HANDLED
}
// Let's go, print the messages on clients
if (szTarget[0] == '@'){
new iPlayers[32], pNum
if (get_cmd_targets(id, szTarget, iPlayers, pNum, szTargetName, SKIP_BOTS)){
for (new p = 0; p < pNum; p++){
new szMsg[256]
if (bPrefix){
format(szMsg, 255, "%L^n%L", iPlayers[p], "SM_RULE_PREFIX", str_to_num(szSearchedMsg[12]), iPlayers[p], szSearchedMsg)
}
else{
format(szMsg, 255, "%L", iPlayers[p], szSearchedMsg)
}
func_print_message(iPlayers[p], szMsg, iMode, iStyle, true)
}
}
}
else{
new iPlayer = cmd_target(id, szTarget, 8)
if (!iPlayer) return PLUGIN_HANDLED
get_user_name(iPlayer, szTargetName, 31)
new szMsg[256]
if (bPrefix){
format(szMsg, 255, "%L^n%L", iPlayer, "SM_RULE_PREFIX", str_to_num(szSearchedMsg[12]), iPlayer, szSearchedMsg)
}
else{
format(szMsg, 255, "%L", iPlayer, szSearchedMsg)
}
func_print_message(iPlayer, szMsg, iMode, iStyle, true)
}
if (strlen(szTargetName)){
log_amx("%L", LANG_SERVER, "SM_PRINT_LOG", szAdminName, szTargetName, szSearchedMsg, iMode, iStyle)
}
return PLUGIN_HANDLED
}
public cmd_server_list(id, level, cid){
if (!cmd_access(id, level, cid, 1)){
return PLUGIN_HANDLED
}
new szCommand[32]
read_argv(0, szCommand, 31)
new iType, iTotalMsg
if (equal(szCommand, "amx_list_msg")){
iType = SM_MESSAGES
iTotalMsg = g_iMsgCount
}
else if (equal(szCommand, "amx_list_rule")){
iType = SM_RULES
iTotalMsg = g_iRuleCount
}
else if (equal(szCommand, "amx_list_info")){
iType = SM_INFOS
iTotalMsg = g_iInfoCount
}
// Technically we should never get here
if (!iType){
client_print(id, print_console, "%L", LANG_PLAYER, "SM_ERROR_SEARCH")
return PLUGIN_HANDLED
}
new param[5]
param[0] = id //player id
param[1] = iType //msg type
param[2] = iTotalMsg //total msg
param[3] = 0 //current msg
param[4] = 0 //printed msg
func_list_messages(param)
return PLUGIN_HANDLED
}
/* == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
FUNCTIONS
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==*/
public func_print_message(id, szMsg[], iMode, iStyle, bool:bSound){
if (is_user_connected(id) && g_bMsgEnabled[id]){
// Check if we can use the tutor, otherwise we send a hudmessage
if (iMode == 4 && g_iActivity[id] == 0){
iMode = 3
}
// Store Messages into a Buffer to replace all placeholders
new szBuffer[384]
copy(szBuffer, 383, szMsg)
// Replace all \n with ^n because it is difficult to type "^" in the console. So you can use \n for a word wrap.
replace_all(szBuffer, 383, "\n", "^n")
// Replace placeholders with their expressions
new szReplacement[64], iSeconds, iMinutes, iHours
get_cvar_string("hostname", szReplacement, 63)
replace(szBuffer, 383, "#hostname#", szReplacement)
get_user_name(id, szReplacement, 63)
replace(szBuffer, 383, "#playername#", szReplacement)
get_cvar_string("amx_nextmap", szReplacement, 63)
replace(szBuffer, 383, "#nextmap#", szReplacement)
get_mapname(szReplacement, 63)
replace(szBuffer, 383, "#currentmap#", szReplacement)
get_time("%m/%d/%Y - %H:%M:%S", szReplacement, 63)
replace(szBuffer, 383, "#time#", szReplacement)
iSeconds = get_timeleft()
format(szReplacement, 63, "%d:%02d", (iSeconds / 60), (iSeconds % 60))
replace(szBuffer, 383, "#timeleft#", szReplacement)
iSeconds = get_user_time(id)
iHours = iSeconds / 3600
iMinutes = (iSeconds - (iHours * 3600)) / 60
iSeconds -= ((iHours * 3600) + (iMinutes * 60))
format(szReplacement, 63, "%d:%02d:%02d", iHours, iMinutes, iSeconds)
replace(szBuffer, 383, "#playtime#", szReplacement)
// Create messages and cut all chars over 256
copy(szMsg, 255, szBuffer)
switch(iMode){
case 1: {
replace_all(szMsg, 255, "^n", " ")
Create_ChatMsg(id, szMsg)
}
case 2: {
replace_all(szMsg, 255, "^n", " ")
client_print(id, print_center, szMsg)
}
case 3: {
set_hudmessage(0, 200, 0, 0.05, 0.35, 2, 0.1, get_pcvar_num(CVAR_show_time) < 5 ? 5.0 : get_pcvar_float(CVAR_show_time), 0.02, 0.02, 8)
show_hudmessage(id, szMsg)
}
case 4: {
// We can use only 192 chars for a tutor msg
format(szMsg, 192, szMsg)
Create_TutorMsg(id, szMsg, iStyle, bSound)
}
default: client_print(id, print_console, szMsg)
}
}
}
public func_list_messages(param[]){
new id = param[0]
if (param[3] < param[2]){
new szPrint[20], iLen
if (param[1] == SM_MESSAGES){
iLen += format(szPrint, 19, "SERVER_MSG_")
}
else if (param[1] == SM_RULES){
iLen += format(szPrint, 19, "SERVER_RULE_")
}
else if (param[1] == SM_INFOS){
iLen += format(szPrint, 19, "SERVER_INFO_")
}
for(new i=param[3];i<=param[2];i++){
new szArg[4]
num_to_str(i, szArg, 3)
format(szPrint[iLen], 19 - iLen, szArg)
if (is_msg_valid(szPrint)){
if (param[4] == 0){
if (param[1] == SM_MESSAGES){
client_print(id, print_console, "^n%L", LANG_PLAYER, "SM_START_MSG_LISTING")
}
else if (param[1] == SM_RULES){
client_print(id, print_console, "^n%L", LANG_PLAYER, "SM_START_RULE_LISTING")
}
else if (param[1] == SM_INFOS){
client_print(id, print_console, "^n%L", LANG_PLAYER, "SM_START_INFO_LISTING")
}
}
param[4]+=1
new szMsg[256]
format(szMsg, 255, "%L", id, szPrint)
replace_all(szMsg, 255, "\n", i > 9 ? "^n " : "^n ")
client_print(id, print_console, "%i: %s", i, szMsg)
if (param[4] % 10 == 0){
param[3]+=1
break
}
}
param[3]+=1
}
set_task(0.1, "func_list_messages", id, param, 5)
}
else{
console_print(id,"^n +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+^n")
}
}
public func_show_message(taskid){
// Define the next message
new iTypes, iTotalMsg
if (get_pcvar_num(CVAR_msg_show)){
iTypes += SM_MESSAGES
iTotalMsg += g_iMsgCount
}
if (get_pcvar_num(CVAR_rule_show)){
iTypes += SM_RULES
iTotalMsg += g_iRuleCount
}
if (get_pcvar_num(CVAR_info_show)){
iTypes += SM_INFOS
iTotalMsg += g_iInfoCount
}
if (!iTypes || !iTotalMsg){
return PLUGIN_HANDLED
}
new bool:bFound, iTryFind
while (!bFound && iTryFind < 3){
iTryFind+=1
new szNextMsg[16], iNextMsg = random_num(1, iTotalMsg)
switch(iTypes){
case SM_MESSAGES + SM_RULES + SM_INFOS: {
if (iNextMsg <= g_iMsgCount){
format(szNextMsg, 15, "SERVER_MSG_%i", iNextMsg)
}
else if (iNextMsg <= g_iMsgCount + g_iRuleCount){
format(szNextMsg, 15, "SERVER_RULE_%i", iNextMsg - g_iMsgCount)
}
else{
format(szNextMsg, 15, "SERVER_INFO_%i", iNextMsg - g_iMsgCount - g_iRuleCount)
}
}
case SM_MESSAGES + SM_RULES: {
if (iNextMsg <= g_iMsgCount){
format(szNextMsg, 15, "SERVER_MSG_%i", iNextMsg)
}
else{
format(szNextMsg, 15, "SERVER_RULE_%i", iNextMsg - g_iMsgCount)
}
}
case SM_MESSAGES + SM_INFOS: {
if (iNextMsg <= g_iMsgCount){
format(szNextMsg, 15, "SERVER_MSG_%i", iNextMsg)
}
else{
format(szNextMsg, 15, "SERVER_INFO_%i", iNextMsg - g_iMsgCount)
}
}
case SM_RULES + SM_INFOS: {
if (iNextMsg <= g_iRuleCount){
format(szNextMsg, 15, "SERVER_RULE_%i", iNextMsg)
}
else{
format(szNextMsg, 15, "SERVER_INFO_%i", iNextMsg - g_iRuleCount)
}
}
case SM_MESSAGES: {
format(szNextMsg, 15, "SERVER_MSG_%i", iNextMsg)
}
case SM_RULES: {
format(szNextMsg, 15, "SERVER_RULE_%i", iNextMsg)
}
case SM_INFOS: {
format(szNextMsg, 15, "SERVER_INFO_%i", iNextMsg)
}
}
if ((!equali(g_szLastMsg[0], szNextMsg) && !equali(g_szLastMsg[1], szNextMsg) && !equali(g_szLastMsg[2], szNextMsg)) || iTryFind == 3){
if (is_msg_valid(szNextMsg)){
bFound = true
// Store the last messages to minimize the chance of duplicate messages
if (iTotalMsg > 3) copy(g_szLastMsg[2], 15, g_szLastMsg[1])
if (iTotalMsg > 2) copy(g_szLastMsg[1], 15, g_szLastMsg[0])
if (iTotalMsg > 1) copy(g_szLastMsg[0], 15, szNextMsg)
new iMode, iStyle, bool:bPrefix
if (equal(szNextMsg, "SERVER_MSG_", 11)){
iMode = get_pcvar_num(CVAR_msg_mode)
iStyle = get_pcvar_num(CVAR_msg_style)
}
else if (equal(szNextMsg, "SERVER_RULE_", 12)){
iMode = get_pcvar_num(CVAR_rule_mode)
iStyle = get_pcvar_num(CVAR_rule_style)
bPrefix = get_pcvar_num(CVAR_rule_prefix) ? true : false
}
else if (equal(szNextMsg, "SERVER_INFO_", 12)){
iMode = get_pcvar_num(CVAR_info_mode)
iStyle = get_pcvar_num(CVAR_info_style)
}
new szFlags[6], iPlayers[32], pNum, iSkip = get_pcvar_num(CVAR_show_skip)
if (iSkip) add(szFlags, 5, iSkip == 1 ? "a" : "b")
add(szFlags, 5, "c")
get_players(iPlayers, pNum, szFlags)
for (new p = 0; p < pNum; p++){
new szMsg[256]
if (bPrefix){
format(szMsg, 255, "%L^n%L", iPlayers[p], "SM_RULE_PREFIX", str_to_num(szNextMsg[12]), iPlayers[p], szNextMsg)
}
else{
format(szMsg, 255, "%L", iPlayers[p], szNextMsg)
}
func_print_message(iPlayers[p], szMsg, iMode, iStyle, false)
}
}
}
}
return PLUGIN_CONTINUE
}
/* == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
STOCKS
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==*/
// Diese Funktion ermittelt alle Zielpersonen (iPlayers), an denen ein Befehl ausgeführt werden soll.
// Dazu kann auch in der Variablen iSkip angegeben werden, welche Personen übersprungen werden sollen.
// Des Weiteren gibt die Funktion den Namen der Zielgruppe in der Variablen szTargetName zurück.
stock get_cmd_targets(id, szArg[], iPlayers[32], &pNum, szTargetName[32], iSkip = SKIP_NOTHING){
new szFlags[6]
if (iSkip & SKIP_DEAD) add(szFlags, 5, "a")
if (iSkip & SKIP_ALIVE) add(szFlags, 5, "b")
if (iSkip & SKIP_BOTS) add(szFlags, 5, "c")
if (iSkip & SKIP_REAL) add(szFlags, 5, "d")
if (equali(szArg[1], "A") || equali(szArg[1], "ALL")){
copy(szTargetName, 31, "everyone")
get_players(iPlayers, pNum, szFlags)
}
else if (equali(szArg[1], "C") || equali(szArg[1], "CT") || equali(szArg[1], "COUNTER")){
copy(szTargetName, 31, "all Counter-Terrorists")
add(szFlags, 5, "e")
get_players(iPlayers, pNum, szFlags, "CT")
}
else if (equali(szArg[1], "T") || equali(szArg[1], "TE") || equali(szArg[1], "TERROR") || equali(szArg[1], "TERRORIST")){
copy(szTargetName, 31, "all Terrorists")
add(szFlags, 5, "e")
get_players(iPlayers, pNum, szFlags, "TERRORIST")
}
if (pNum == 0){
client_print(id, print_console, "[AMXX] %L", LANG_PLAYER, "SM_NO_CLIENT")
return 0
}
return 1
}
stock bool:is_msg_valid(szSearchedMsg[]){
new bool:bFound, iLanguages
if (file_exists(g_szFilePath)){
new szMsg[32], szBuffer[128], szLastMsg[32], fp=fopen(g_szFilePath, "r")
while (!feof(fp) && !bFound && iLanguages < 2){
szBuffer[0]='^0'
fgets(fp, szBuffer, 127)
parse(szBuffer, szMsg, 31)
if (!equali(szMsg, szLastMsg)){
// Saves the current message for blocking duplicative messages
copy(szLastMsg, 31, szMsg)
if (equali(szMsg, szSearchedMsg, strlen(szSearchedMsg))){
bFound = true
}
// Stop loop if we reached the second language
else if (szMsg[0] == '[' && szMsg[3] == ']'){
iLanguages += 1
}
}
}
fclose(fp)
}
// Message or File not exists
if (!bFound){
return false
}
return true
}
stock SaveData(id){
new szAuthid[32], szKey[64], szData[16]
get_user_authid(id, szAuthid, 31)
format(szKey, 63, "SERV_MSG_%s", szAuthid)
new iMinutes = g_iActivity[id] + (get_user_time(id) / 60)
num_to_str(iMinutes, szData, 15)
set_vaultdata(szKey, szData)
}
stock LoadData(id){
new szAuthid[32], szKey[64], szData[16]
get_user_authid(id, szAuthid, 31)
format(szKey, 63, "SERV_MSG_%s", szAuthid)
if (vaultdata_exists(szKey)){
get_vaultdata(szKey, szData, 15)
g_iActivity[id] = strlen(szData) ? str_to_num(szData) : 0
g_bMsgEnabled[id] = (g_iActivity[id] < get_pcvar_num(CVAR_min_activity) || !get_pcvar_num(CVAR_min_activity)) ? true : false
}
else{
g_iActivity[id] = 0
g_bMsgEnabled[id] = true
}
}
/* == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
CREATES (Messages and Effects)
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==*/
stock Create_TutorMsg(id, szMsg[], iStyle, bool:bSound){
if (is_user_connected(id)){
// A user message must be smaller than 192 Bytes, otherwise the server crashs.
szMsg[182]='^0'
// Playback of a typical sound of the tutor
if (bSound || get_pcvar_num(CVAR_tutor_sound)){
switch(iStyle){
case 1: client_cmd(id, "spk events/friend_died.wav")
case 2: client_cmd(id, "spk events/enemy_died.wav")
case 5: client_cmd(id, "spk events/task_complete.wav")
default: client_cmd(id, "spk events/tutor_msg.wav")
}
}
// I think we can remove this but this is also called by the original tutor, so we emulate this too.
Remove_TutorMsg(TASK_REMOVE_TUTOR+id)
// Create a Tutor message
message_begin(MSG_ONE_UNRELIABLE , gMsgTutorText, {0, 0, 0}, id)
write_string(szMsg) // displayed message
write_byte(0) // ???
write_short(0) // ???
write_short(0) // ???
write_short(1<<iStyle) // class of a message
message_end()
// Hide Tutor in ... seconds
set_task(get_pcvar_num(CVAR_show_time) < 5 ? 5.0 : get_pcvar_float(CVAR_show_time), "Remove_TutorMsg", TASK_REMOVE_TUTOR+id)
}
}
public Remove_TutorMsg(taskid){
if(task_exists(taskid)) remove_task(taskid)
new id = taskid >= TASK_REMOVE_TUTOR ? taskid - TASK_REMOVE_TUTOR : taskid
message_begin(MSG_ONE_UNRELIABLE , gMsgTutorClose, {0, 0, 0}, id)
message_end()
}
stock Create_ChatMsg(id, szMsg[]){
format(szMsg, 255, "^x04%s", szMsg)
// A user message must be smaller than 192 Bytes, otherwise the server crashs.
szMsg[182]='^0'
message_begin(MSG_ONE_UNRELIABLE , gMsgSayText, {0, 0, 0}, id)
write_byte(id)
write_string(szMsg)
message_end()
}