/** * HLstatsX Community Edition - SourceMod plugin to display ingame messages * http://www.hlxcommunity.com/ * Copyright (C) 2008-2009 Nicholas Hastings * Copyright (C) 2007-2009 TTS Oetzel & Goerz GmbH * Modified by Nicholas Hastings (psychonic) for use with HLstatsX Community Edition * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma semicolon 1 #define REQUIRE_EXTENSIONS #include #include #include #undef REQUIRE_EXTENSIONS #include #include #define VERSION "1.6.19" #define HLXTAG "HLstatsX:CE" enum GameType { Game_Unknown = -1, Game_CSS, Game_DODS, Game_L4D, Game_TF, Game_HL2MP, Game_INSMOD, Game_FF, Game_ZPS, Game_AOC, Game_FOF, Game_GES, Game_PVKII, Game_CSP, Game_ND, Game_DDD, Game_CSGO, }; new GameType:gamemod = Game_Unknown; new Handle: hlx_block_chat_commands; new Handle: hlx_message_prefix; new Handle: hlx_protect_address; new Handle: hlx_server_tag; new Handle: sv_tags; new Handle: message_recipients; new const String: blocked_commands[][] = { "rank", "skill", "points", "place", "session", "session_data", "kpd", "kdratio", "kdeath", "next", "load", "status", "servers", "top20", "top10", "top5", "clans", "bans", "cheaters", "statsme", "weapons", "weapon", "action", "actions", "accuracy", "targets", "target", "kills", "kill", "player_kills", "cmd", "cmds", "command", "hlx_display 0", "hlx_display 1", "hlx_teams 0", "hlx_teams 1", "hlx_hideranking", "hlx_chat 0", "hlx_chat 1", "hlx_menu", "servers 1", "servers 2", "servers 3", "hlx", "hlstatsx", "help" }; new Handle:HLstatsXMenuMain; new Handle:HLstatsXMenuAuto; new Handle:HLstatsXMenuEvents; new Handle: PlayerColorArray; new ColorSlotArray[] = { -1, -1, -1, -1, -1, -1 }; new const String:ct_models[][] = { "models/player/ct_urban.mdl", "models/player/ct_gsg9.mdl", "models/player/ct_sas.mdl", "models/player/ct_gign.mdl" }; new const String:ts_models[][] = { "models/player/t_phoenix.mdl", "models/player/t_leet.mdl", "models/player/t_arctic.mdl", "models/player/t_guerilla.mdl" }; new const String: modnamelist[][] = { "Counter-Strike: Source", "Day of Defeat: Source", "Left 4 Dead (1 or 2)", "Team Fortress 2", "Half-Life 2 Deathmatch", "Insurgency", "Fortress Forever", "Zombie Panic: Source", "Age of Chivalry", "Fistful of Frags", "GoldenEye: Source", "Pirates, Vikings, and Knights", "CSPromod", "Nuclear Dawn", "Dino D-Day", "Counter-Strike: Global Offensive" }; new String: message_prefix[32]; new bool:g_bPlyrCanDoMotd[MAXPLAYERS+1]; new bool:g_bGameCanDoMotd = true; new bool:g_bTrackColors4Chat; new g_iSDKVersion = SOURCE_SDK_UNKNOWN; new Handle:g_cvarTeamPlay = INVALID_HANDLE; new bool:g_bTeamPlay; new bool:g_bLateLoad = false; new bool:g_bIgnoreNextTagChange = false; new Handle:g_hCustomTags; #define SVTAGSIZE 128 public Plugin:myinfo = { name = "HLstatsX CE Ingame Plugin", author = "psychonic", description = "Provides ingame functionality for interaction from an HLstatsX CE installation", version = VERSION, url = "http://www.hlxcommunity.com" }; public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) { g_bLateLoad = late; MarkNativeAsOptional("CS_SwitchTeam"); MarkNativeAsOptional("CS_RespawnPlayer"); MarkNativeAsOptional("SetCookieMenuItem"); return APLRes_Success; } public OnPluginStart() { get_server_mod(); CreateHLstatsXMenuMain(HLstatsXMenuMain); CreateHLstatsXMenuAuto(HLstatsXMenuAuto); CreateHLstatsXMenuEvents(HLstatsXMenuEvents); RegServerCmd("hlx_sm_psay", hlx_sm_psay); RegServerCmd("hlx_sm_psay2", hlx_sm_psay2); RegServerCmd("hlx_sm_bulkpsay", hlx_sm_psay); RegServerCmd("hlx_sm_csay", hlx_sm_csay); RegServerCmd("hlx_sm_msay", hlx_sm_msay); RegServerCmd("hlx_sm_tsay", hlx_sm_tsay); RegServerCmd("hlx_sm_hint", hlx_sm_hint); RegServerCmd("hlx_sm_browse", hlx_sm_browse); RegServerCmd("hlx_sm_swap", hlx_sm_swap); RegServerCmd("hlx_sm_redirect", hlx_sm_redirect); RegServerCmd("hlx_sm_player_action", hlx_sm_player_action); RegServerCmd("hlx_sm_team_action", hlx_sm_team_action); RegServerCmd("hlx_sm_world_action", hlx_sm_world_action); if (gamemod == Game_INSMOD) { AddCommandListener(hlx_block_commands, "say2"); } else if (gamemod == Game_ND) { AddCommandListener(hlx_block_commands, "say_squad"); } AddCommandListener(hlx_block_commands, "say"); AddCommandListener(hlx_block_commands, "say_team"); switch (gamemod) { case Game_CSS, Game_L4D, Game_TF, Game_HL2MP, Game_AOC, Game_FOF, Game_PVKII, Game_ND, Game_DDD, Game_CSGO: { g_bTrackColors4Chat = true; HookEvent("player_team", HLstatsX_Event_PlyTeamChange, EventHookMode_Pre); } } switch (gamemod) { case Game_L4D, Game_INSMOD, Game_GES: { g_bGameCanDoMotd = false; } } if (gamemod == Game_HL2MP) { g_cvarTeamPlay = FindConVar("mp_teamplay"); if (g_cvarTeamPlay != INVALID_HANDLE) { g_bTeamPlay = GetConVarBool(g_cvarTeamPlay); HookConVarChange(g_cvarTeamPlay, OnTeamPlayChange); } } CreateConVar("hlxce_plugin_version", VERSION, "HLstatsX:CE Ingame Plugin", FCVAR_PLUGIN|FCVAR_NOTIFY); CreateConVar("hlxce_version", "", "HLstatsX:CE", FCVAR_PLUGIN|FCVAR_NOTIFY); CreateConVar("hlxce_webpage", "http://www.hlxcommunity.com", "http://www.hlxcommunity.com", FCVAR_PLUGIN|FCVAR_NOTIFY); hlx_block_chat_commands = CreateConVar("hlx_block_commands", "1", "If activated HLstatsX commands are blocked from the chat area", FCVAR_PLUGIN); hlx_message_prefix = CreateConVar("hlx_message_prefix", "", "Define the prefix displayed on every HLstatsX ingame message", FCVAR_PLUGIN); hlx_protect_address = CreateConVar("hlx_protect_address", "", "Address to be protected for logging/forwarding", FCVAR_PLUGIN); hlx_server_tag = CreateConVar("hlx_server_tag", "1", "If enabled, adds \"HLstatsX:CE\" to server tags on supported games. 1 = Enabled (default), 0 = Disabled", FCVAR_PLUGIN, true, 0.0, true, 1.0); g_hCustomTags = CreateArray(SVTAGSIZE); sv_tags = FindConVar("sv_tags"); g_iSDKVersion = GuessSDKVersion(); if (g_bLateLoad) { GetConVarString(hlx_message_prefix, message_prefix, sizeof(message_prefix)); decl String:protaddr[24]; GetConVarString(hlx_protect_address, protaddr, sizeof(protaddr)); OnProtectAddressChange(hlx_protect_address, "", protaddr); } MyAddServerTag(HLXTAG); HookConVarChange(hlx_message_prefix, OnMessagePrefixChange); HookConVarChange(hlx_protect_address, OnProtectAddressChange); HookConVarChange(hlx_server_tag, OnServerTagChange); if (sv_tags != INVALID_HANDLE) { HookConVarChange(sv_tags, OnSVTagsChange); } RegServerCmd("log", ProtectLoggingChange); RegServerCmd("logaddress_del", ProtectForwardingChange); RegServerCmd("logaddress_delall", ProtectForwardingDelallChange); RegServerCmd("hlx_message_prefix_clear", MessagePrefixClear); PlayerColorArray = CreateArray(); message_recipients = CreateStack(); GetTeams(gamemod == Game_INSMOD); } public OnAllPluginsLoaded() { if (LibraryExists("clientprefs")) { SetCookieMenuItem(HLXSettingsMenu, 0, "HLstatsX:CE Settings"); } } public HLXSettingsMenu(client, CookieMenuAction:action, any:info, String:buffer[], maxlen) { if (action == CookieMenuAction_SelectOption) { DisplayMenu(HLstatsXMenuMain, client, MENU_TIME_FOREVER); } } public OnMapStart() { GetTeams(gamemod == Game_INSMOD); if (g_bTrackColors4Chat) { find_player_team_slot(2); find_player_team_slot(3); if (gamemod == Game_PVKII) { find_player_team_slot(4); } } } bool:BTagsSupported() { return (sv_tags != INVALID_HANDLE && (g_iSDKVersion == SOURCE_SDK_EPISODE2 || g_iSDKVersion == SOURCE_SDK_EPISODE2VALVE || gamemod == Game_ND)); } stock MyAddServerTag(const String:tag[]) { if (!BTagsSupported()) { // game doesn't support sv_tags return; } if (!GetConVarBool(hlx_server_tag)) { return; } if (FindStringInArray(g_hCustomTags, tag) == -1) { PushArrayString(g_hCustomTags, tag); } decl String:current_tags[SVTAGSIZE]; GetConVarString(sv_tags, current_tags, sizeof(current_tags)); if (StrContains(current_tags, tag) > -1) { // already have tag return; } decl String:new_tags[SVTAGSIZE]; Format(new_tags, sizeof(new_tags), "%s%s%s", current_tags, (current_tags[0]!=0)?",":"", tag); new flags = GetConVarFlags(sv_tags); SetConVarFlags(sv_tags, flags & ~FCVAR_NOTIFY); g_bIgnoreNextTagChange = true; SetConVarString(sv_tags, new_tags); g_bIgnoreNextTagChange = false; SetConVarFlags(sv_tags, flags); } stock MyRemoveServerTag(const String:tag[]) { if (!BTagsSupported()) { // game doesn't support sv_tags return; } new idx = FindStringInArray(g_hCustomTags, tag); if (idx > -1) { RemoveFromArray(g_hCustomTags, idx); } decl String:current_tags[SVTAGSIZE]; GetConVarString(sv_tags, current_tags, sizeof(current_tags)); if (StrContains(current_tags, tag) == -1) { // tag isn't on here, just bug out return; } ReplaceString(current_tags, sizeof(current_tags), tag, ""); ReplaceString(current_tags, sizeof(current_tags), ",,", ""); new flags = GetConVarFlags(sv_tags); SetConVarFlags(sv_tags, flags & ~FCVAR_NOTIFY); g_bIgnoreNextTagChange = true; SetConVarString(sv_tags, current_tags); g_bIgnoreNextTagChange = false; SetConVarFlags(sv_tags, flags); } get_server_mod() { new String: game_description[64]; GetGameDescription(game_description, sizeof(game_description), true); if (StrContains(game_description, "Counter-Strike", false) != -1) { gamemod = Game_CSS; } else if (StrContains(game_description, "Day of Defeat", false) != -1) { gamemod = Game_DODS; } else if (StrContains(game_description, "Half-Life 2 Deathmatch", false) != -1) { gamemod = Game_HL2MP; } else if (StrContains(game_description, "Team Fortress", false) != -1) { gamemod = Game_TF; } else if (StrContains(game_description, "L4D", false) != -1 || StrContains(game_description, "Left 4 D", false) != -1) { gamemod = Game_L4D; } else if (StrContains(game_description, "Insurgency", false) != -1) { gamemod = Game_INSMOD; //psychonic - added detection for more supported games } else if (StrContains(game_description, "Fortress Forever", false) != -1) { gamemod = Game_FF; } else if (StrContains(game_description, "ZPS", false) != -1) { gamemod = Game_ZPS; } else if (StrContains(game_description, "Age of Chivalry", false) != -1) { gamemod = Game_AOC; } else if (StrContains(game_description, "PVKII", false) != -1) { gamemod = Game_PVKII; } else if (StrContains(game_description, "CSPromod", false) != -1) { gamemod = Game_CSP; } else if (StrContains(game_description, "Nuclear Dawn", false) != -1) { gamemod = Game_ND; } // game mod could not detected, try further if (gamemod == Game_Unknown) { new String: game_folder[64]; GetGameFolderName(game_folder, sizeof(game_folder)); if (StrContains(game_folder, "cstrike", false) != -1) { gamemod = Game_CSS; } else if (strncmp(game_folder, "dod", 3, false) == 0) { gamemod = Game_DODS; } else if (StrContains(game_folder, "hl2mp", false) != -1 || StrContains(game_folder, "hl2ctf", false) != -1) { gamemod = Game_HL2MP; } else if (StrContains(game_folder, "fistful_of_frags", false) != -1) { gamemod = Game_FOF; } else if (strncmp(game_folder, "tf", 2, false) == 0) { gamemod = Game_TF; } else if (StrContains(game_folder, "left4dead", false) != -1) { gamemod = Game_L4D; } else if (StrContains(game_folder, "insurgency", false) != -1) { gamemod = Game_INSMOD; //psychonic - added detection for more supported games } else if (StrContains(game_folder, "FortressForever", false) != -1) { gamemod = Game_FF; } else if (StrContains(game_folder, "zps", false) != -1) { gamemod = Game_ZPS; } else if (StrContains(game_folder, "ageofchivalry", false) != -1) { gamemod = Game_AOC; } else if (StrContains(game_folder, "gesource", false) != -1) { gamemod = Game_GES; } else if (StrContains(game_folder, "pvkii", false) != -1) { gamemod = Game_PVKII; } else if (StrContains(game_folder, "cspromod", false) != -1) { gamemod = Game_CSP; } else if (StrContains(game_folder, "nucleardawn", false) != -1) { gamemod = Game_ND; } else if (StrContains(game_folder, "dinodday", false) != -1) { gamemod = Game_DDD; } else if (StrContains(game_folder, "csgo", false) != -1) { gamemod = Game_CSGO; } else { LogToGame("HLX:CE Mod Not In Detected List, Using Defaults (%s, %s)", game_description, game_folder); LogToGame("HLX:CE If this is incorrect, please file a bug at hlxcommunity.com"); } } if (gamemod > Game_Unknown) { LogToGame("HLX:CE Mod Detection: %s", modnamelist[_:gamemod]); LogToGame("HLX:CE If this is incorrect, please file a bug at hlxcommunity.com"); } } public OnClientPostAdminCheck(client) { if (g_bGameCanDoMotd && !IsFakeClient(client)) { QueryClientConVar(client, "cl_disablehtmlmotd", motdQuery); } } public motdQuery(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[]) { if (result == ConVarQuery_Okay && StringToInt(cvarValue) == 0 || result != ConVarQuery_Okay) { g_bPlyrCanDoMotd[client] = true; } } public OnServerTagChange(Handle:cvar, const String:oldVal[], const String:newVal[]) { if (GetConVarBool(hlx_server_tag)) { MyAddServerTag(HLXTAG); } else { MyRemoveServerTag(HLXTAG); } } public OnSVTagsChange(Handle:cvar, const String:oldVal[], const String:newVal[]) { if (g_bIgnoreNextTagChange) { // we fired this callback, no need to reapply tags return; } // reapply each custom tag new cnt = GetArraySize(g_hCustomTags); for (new i = 0; i < cnt; i++) { decl String:tag[SVTAGSIZE]; GetArrayString(g_hCustomTags, i, tag, sizeof(tag)); MyAddServerTag(tag); } } public OnProtectAddressChange(Handle:cvar, const String:oldVal[], const String:newVal[]) { if (newVal[0] > 0) { decl String: log_command[192]; Format(log_command, sizeof(log_command), "logaddress_add %s", newVal); LogToGame("Command: %s", log_command); ServerCommand(log_command); } } public OnTeamPlayChange(Handle:cvar, const String:oldVal[], const String:newVal[]) { g_bTeamPlay = GetConVarBool(g_cvarTeamPlay); } public Action:ProtectLoggingChange(args) { if (hlx_protect_address != INVALID_HANDLE) { decl String: protect_address[192]; GetConVarString(hlx_protect_address, protect_address, sizeof(protect_address)); if (strcmp(protect_address, "") != 0) { if (args >= 1) { decl String: log_action[192]; GetCmdArg(1, log_action, sizeof(log_action)); if ((strcmp(log_action, "off") == 0) || (strcmp(log_action, "0") == 0)) { LogToGame("HLstatsX address protection active, logging reenabled!"); ServerCommand("log 1"); } } } } return Plugin_Continue; } public Action:ProtectForwardingChange(args) { if (hlx_protect_address != INVALID_HANDLE) { decl String: protect_address[192]; GetConVarString(hlx_protect_address, protect_address, sizeof(protect_address)); if (strcmp(protect_address, "") != 0) { if (args == 1) { decl String: log_action[192]; GetCmdArg(1, log_action, sizeof(log_action)); if (strcmp(log_action, protect_address) == 0) { decl String: log_command[192]; Format(log_command, sizeof(log_command), "logaddress_add %s", protect_address); LogToGame("HLstatsX address protection active, logaddress readded!"); ServerCommand(log_command); } } else if (args > 1) { new String: log_action[192]; for(new i = 1; i <= args; i++) { decl String: temp_argument[192]; GetCmdArg(i, temp_argument, sizeof(temp_argument)); strcopy(log_action[strlen(log_action)], sizeof(log_action), temp_argument); } if (strcmp(log_action, protect_address) == 0) { decl String: log_command[192]; Format(log_command, sizeof(log_command), "logaddress_add %s", protect_address); LogToGame("HLstatsX address protection active, logaddress readded!"); ServerCommand(log_command); } } } } return Plugin_Continue; } public Action:ProtectForwardingDelallChange(args) { if (hlx_protect_address != INVALID_HANDLE) { decl String: protect_address[192]; GetConVarString(hlx_protect_address, protect_address, sizeof(protect_address)); if (strcmp(protect_address, "") != 0) { decl String: log_command[192]; Format(log_command, sizeof(log_command), "logaddress_add %s", protect_address); LogToGame("HLstatsX address protection active, logaddress readded!"); ServerCommand(log_command); } } return Plugin_Continue; } public OnMessagePrefixChange(Handle:cvar, const String:oldVal[], const String:newVal[]) { strcopy(message_prefix, sizeof(message_prefix), newVal); } public Action:MessagePrefixClear(args) { message_prefix = ""; } find_player_team_slot(team_index) { if (team_index > -1) { ColorSlotArray[team_index] = -1; for(new i = 1; i <= MaxClients; i++) { if (IsClientInGame(i) && GetClientTeam(i) == team_index) { ColorSlotArray[team_index] = i; break; } } } } stock validate_team_colors() { for (new i = 0; i < sizeof(ColorSlotArray); i++) { new color_client = ColorSlotArray[i]; if (color_client > 0) { if (IsClientInGame(color_client) && GetClientTeam(color_client) != color_client) { find_player_team_slot(i); } } else { if (i == 2 || i == 3 || (i == 4 && gamemod == Game_PVKII)) { find_player_team_slot(i); } } } } public OnClientDisconnect(client) { if (g_bTrackColors4Chat && client > 0 && IsClientInGame(client)) { new team_index = GetClientTeam(client); if (client == ColorSlotArray[team_index]) { ColorSlotArray[team_index] = -1; } } g_bPlyrCanDoMotd[client] = false; } color_player(color_type, player_index, String: client_message[192]) { new color_player_index = -1; if (g_bTrackColors4Chat || (gamemod == Game_DODS) || (gamemod == Game_ZPS) || (gamemod == Game_GES) || (gamemod == Game_CSP)) { decl String: client_name[192]; GetClientName(player_index, client_name, sizeof(client_name)); if ((strcmp(client_message, "") != 0) && (strcmp(client_name, "") != 0)) { if (color_type == 1) { decl String: search_client_name[192]; Format(search_client_name, sizeof(search_client_name), "%s ", client_name); decl String: colored_player_name[192]; switch (gamemod) { case Game_DODS, Game_GES, Game_CSP: Format(colored_player_name, sizeof(colored_player_name), "\x04%s\x01 ", client_name); case Game_HL2MP: Format(colored_player_name, sizeof(colored_player_name), "%c%s\x01 ", g_bTeamPlay?3:4, client_name); case Game_ZPS: Format(colored_player_name, sizeof(colored_player_name), "\x05%s\x01 ", client_name); default: Format(colored_player_name, sizeof(colored_player_name), "\x03%s\x01 ", client_name); } if (ReplaceString(client_message, sizeof(client_message), search_client_name, colored_player_name) > 0) { return player_index; } } else { decl String: search_client_name[192]; Format(search_client_name, sizeof(search_client_name), " %s ", client_name); decl String: colored_player_name[192]; switch (gamemod) { case Game_ZPS: Format(colored_player_name, sizeof(colored_player_name), " \x05%s\x01 ", client_name); case Game_GES: Format(colored_player_name, sizeof(colored_player_name), " \x05%s\x01 ", client_name); default: Format(colored_player_name, sizeof(colored_player_name), " \x04%s\x01 ", client_name); } ReplaceString(client_message, sizeof(client_message), search_client_name, colored_player_name); } } } else if (gamemod == Game_FF) { decl String: client_name[192]; GetClientName(player_index, client_name, sizeof(client_name)); new team = GetClientTeam(player_index); if (team > 1 && team < 6) { decl String: colored_player_name[192]; Format(colored_player_name, sizeof(colored_player_name), "^%d%s^0", (team-1), client_name); if (ReplaceString(client_message, sizeof(client_message), client_name, colored_player_name) > 0) { return player_index; } } } return color_player_index; } color_all_players(String: message[192]) { new color_index = -1; if ((g_bTrackColors4Chat || (gamemod == Game_DODS) || (gamemod == Game_ZPS) || (gamemod == Game_FF) || (gamemod == Game_GES) || (gamemod == Game_CSP)) && (PlayerColorArray != INVALID_HANDLE)) { if (strcmp(message, "") != 0) { ClearArray(PlayerColorArray); new lowest_matching_pos = 192; new lowest_matching_pos_client = -1; for(new i = 1; i <= MaxClients; i++) { new client = i; if (IsClientInGame(client)) { decl String: client_name[32]; GetClientName(client, client_name, sizeof(client_name)); if (strcmp(client_name, "") != 0) { new message_pos = StrContains(message, client_name); if (message_pos > -1) { if (lowest_matching_pos > message_pos) { lowest_matching_pos = message_pos; lowest_matching_pos_client = client; } new TempPlayerColorArray[1]; TempPlayerColorArray[0] = client; PushArrayArray(PlayerColorArray, TempPlayerColorArray); } } } } new size = GetArraySize(PlayerColorArray); for (new i = 0; i < size; i++) { new temp_player_array[1]; GetArrayArray(PlayerColorArray, i, temp_player_array); new temp_client = temp_player_array[0]; if (temp_client == lowest_matching_pos_client) { new temp_color_index = color_player(1, temp_client, message); color_index = temp_color_index; } else { color_player(0, temp_client, message); } } ClearArray(PlayerColorArray); } } return color_index; } color_team_entities(String:message[192]) { switch(gamemod) { case Game_CSS, Game_CSGO: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "TERRORIST ", "\x03TERRORIST\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "CT ", "\x03CT\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_L4D: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Survivors ", "\x03Survivors\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Infected ", "\x03Infected\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_TF: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Red ", "\x03Red\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Blue ", "\x03Blue\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_FF: { if (strcmp(message, "") != 0) { if (ReplaceString(message, sizeof(message), "Red Team", "^2Red Team^0") > 0) { return 0; } if (ReplaceString(message, sizeof(message), "Blue Team", "^1Blue Team^0") > 0) { return 0; } if (ReplaceString(message, sizeof(message), "Yellow Team", "^3Yellow Team^0") > 0) { return 0; } if (ReplaceString(message, sizeof(message), "Green Team", "^4Green Team^0") > 0) { return 0; } } } case Game_AOC: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Agathia Knights ", "\x03Agathia Knights\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "The Mason Order ", "\x03The Mason Order\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_FOF: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Desperados ", "\x03Desperados\x01 ") > 0 || ReplaceString(message, sizeof(message), "Desparados ", "\x03Desperados\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Vigilantes ", "\x03Vigilantes\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_HL2MP: { if (g_bTeamPlay && strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "The Combine ", "\x03The Combine\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Rebel Forces ", "\x03Rebel Forces\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_PVKII: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Pirates ", "\x03Pirates\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Vikings ", "\x03Vikings\x01 ") > 0) { return ColorSlotArray[3]; } } if (ColorSlotArray[4] > -1) { if (ReplaceString(message, sizeof(message), "Knights ", "\x03Knights\x01 ") > 0) { return ColorSlotArray[4]; } } } } case Game_ND: { if (strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "EMPIRE ", "\x03Empire\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "CONSORTIUM ", "\x03Consortium\x01 ") > 0) { return ColorSlotArray[3]; } } } } case Game_DDD: { if (g_bTeamPlay && strcmp(message, "") != 0) { if (ColorSlotArray[2] > -1) { if (ReplaceString(message, sizeof(message), "Allies ", "\x03Allies\x01 ") > 0) { return ColorSlotArray[2]; } } if (ColorSlotArray[3] > -1) { if (ReplaceString(message, sizeof(message), "Axis ", "\x03Axis\x01 ") > 0) { return ColorSlotArray[3]; } } } } } return -1; } display_menu(player_index, time, String: full_message[1024], need_handler = 0) { ReplaceString(full_message, sizeof(full_message), "\\n", "\10"); if (need_handler == 0) { InternalShowMenu(player_index, full_message, time); } else { InternalShowMenu(player_index, full_message, time, (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9), InternalMenuHandler); } } public InternalMenuHandler(Handle:menu, MenuAction:action, param1, param2) { new client = param1; if (IsClientInGame(client)) { if (action == MenuAction_Select) { decl String: player_event[192]; IntToString(param2, player_event, sizeof(player_event)); LogPlayerEvent(client, "selected", player_event); } else if (action == MenuAction_Cancel) { LogPlayerEvent(client, "selected", "cancel"); } } } public Action:hlx_sm_psay(args) { if (args < 2) { PrintToServer("Usage: hlx_sm_psay - sends private message"); return Plugin_Handled; } decl String: client_list[192]; GetCmdArg(1, client_list, sizeof(client_list)); BuildClientList(client_list); decl String: colored_param[32]; GetCmdArg(2, colored_param, sizeof(colored_param)); new is_colored = 0; new ignore_param = 0; if (strcmp(colored_param, "1") == 0) { is_colored = 1; ignore_param = 1; } else if (strcmp(colored_param, "2") == 0) { is_colored = 2; ignore_param = 1; } else if (strcmp(colored_param, "0") == 0) { ignore_param = 1; } new String: client_message[192]; GetCmdArg((ignore_param + 2), client_message, sizeof(client_message)); if (IsStackEmpty(message_recipients)) { return Plugin_Handled; } new color_index = -1; decl String: display_message[192]; switch (gamemod) { case Game_CSS, Game_DODS, Game_L4D, Game_TF, Game_HL2MP, Game_ZPS, Game_AOC, Game_FOF, Game_GES, Game_PVKII, Game_CSP, Game_ND, Game_DDD, Game_CSGO: { if (is_colored > 0) { if (is_colored == 1) { new player_color_index = color_all_players(client_message); if (player_color_index > -1) { color_index = player_color_index; } else { if (g_bTrackColors4Chat) { validate_team_colors(); } color_index = color_team_entities(client_message); } } } if (strcmp(message_prefix, "") == 0) { Format(display_message, sizeof(display_message), "\x01%s", client_message); } else { Format(display_message, sizeof(display_message), "%c%s\x01 %s", ((gamemod == Game_ZPS || gamemod == Game_GES)?5:4), message_prefix, client_message); } new bool: setupColorForRecipients = false; if (color_index == -1) { setupColorForRecipients = true; } if (g_bTrackColors4Chat && is_colored != 2) { while (IsStackEmpty(message_recipients) == false) { new recipient_client = -1; PopStackCell(message_recipients, recipient_client); new player_index = GetClientOfUserId(recipient_client); if (player_index > 0 && !IsFakeClient(player_index) && IsClientInGame(player_index)) { if (setupColorForRecipients == true) { color_index = player_index; } new Handle:hBf; hBf = StartMessageOne("SayText2", player_index); if (hBf != INVALID_HANDLE) { BfWriteByte(hBf, color_index); BfWriteByte(hBf, 0); if (gamemod == Game_CSGO) { // hackhackhack... // CS:GO won't print any colors unless you not only start with standard color (1) // like in other games, but also have a 'printable' character following it. We will just // use an unused control code BfWriteByte(hBf, 1); BfWriteByte(hBf, 11); } BfWriteString(hBf, display_message); EndMessage(); } } } } else { PrintToChatRecipients(display_message); } } case Game_FF: { // thanks to hlstriker for help with this decl String: client_message_backup[192]; strcopy(client_message_backup, sizeof(client_message_backup), client_message); if (is_colored == 1) { color_index = color_all_players(client_message); if (color_index == -1) { color_team_entities(client_message); } } if (strcmp(message_prefix, "") == 0) { Format(display_message, sizeof(display_message), "Console: %s%s\n", ((is_colored == 2)?"^4":""), client_message); } else { Format(display_message, sizeof(display_message), "Console: ^4%s:%s %s\n", message_prefix, ((is_colored == 2)?"":"^"), client_message); } PrintToChatRecipientsFF(display_message); } default: { if (strcmp(message_prefix, "") != 0) { Format(display_message, sizeof(display_message), "%s %s", message_prefix, client_message); PrintToChatRecipients(display_message); return Plugin_Handled; } PrintToChatRecipients(client_message); } } return Plugin_Handled; } public Action:hlx_sm_psay2(args) { if (args < 2) { PrintToServer("Usage: hlx_sm_psay2 - sends green colored private message"); return Plugin_Handled; } decl String: client_list[192]; GetCmdArg(1, client_list, sizeof(client_list)); BuildClientList(client_list); decl String: colored_param[32]; GetCmdArg(2, colored_param, sizeof(colored_param)); new ignore_param = 0; if (strcmp(colored_param, "2") == 0 || strcmp(colored_param, "1") == 0 || strcmp(colored_param, "0") == 0) { ignore_param = 1; } new String: client_message[192]; GetCmdArg((ignore_param + 2), client_message, sizeof(client_message)); if (IsStackEmpty(message_recipients)) { return Plugin_Handled; } // Strip color control codes decl String:buffer_message[192]; new j = 0; for (new i = 0; i < sizeof(client_message); i++) { new char = client_message[i]; if (char < 5 && char > 0) { continue; } buffer_message[j] = client_message[i]; if (char == 0) { break; } j++; } switch(gamemod) { case Game_INSMOD: { new prefix = 0; if (strcmp(message_prefix, "") != 0) { prefix = 1; Format(client_message, sizeof(client_message), "%s: %s", message_prefix, buffer_message); } while (IsStackEmpty(message_recipients) == false) { new recipient_client = -1; PopStackCell(message_recipients, recipient_client); new player_index = GetClientOfUserId(recipient_client); if (player_index > 0 && !IsFakeClient(player_index) && IsClientInGame(player_index)) { // thanks to Fyren and IceMatrix for help with this new Handle:hBf; hBf = StartMessageOne("SayText", player_index); if (hBf != INVALID_HANDLE) { BfWriteByte(hBf, 1); BfWriteBool(hBf, true); BfWriteByte(hBf, player_index); if (prefix == 0) { BfWriteString(hBf, buffer_message); } else { BfWriteString(hBf, client_message); } EndMessage(); } } } } case Game_FF: { if (strcmp(message_prefix, "") == 0) { Format(client_message, sizeof(client_message), "Console: \x02^4%s\n", buffer_message); } else { Format(client_message, sizeof(client_message), "Console: \x02^4%s: %s\n", message_prefix, buffer_message); } PrintToChatRecipientsFF(client_message); } case Game_ZPS, Game_GES: { if (strcmp(message_prefix, "") == 0) { Format(client_message, sizeof(client_message), "\x05%s", buffer_message); } else { Format(client_message, sizeof(client_message), "\x05%s %s", message_prefix, buffer_message); } PrintToChatRecipients(client_message); } default: { if (strcmp(message_prefix, "") == 0) { Format(client_message, sizeof(client_message), "\x04%s", buffer_message); } else { Format(client_message, sizeof(client_message), "\x04%s %s", message_prefix, buffer_message); } PrintToChatRecipients(client_message); } } return Plugin_Handled; } public Action:hlx_sm_csay(args) { if (args < 1) { PrintToServer("Usage: hlx_sm_csay - display center message"); return Plugin_Handled; } new String: display_message[192]; GetCmdArg(1, display_message, sizeof(display_message)); if (strcmp(display_message, "") != 0) { if (gamemod == Game_L4D) { PrintToChatAll("\x03%s", display_message); } else { PrintCenterTextAll("%s", display_message); } } return Plugin_Handled; } public Action:hlx_sm_msay(args) { if (args < 3) { PrintToServer("Usage: hlx_sm_msay