From 45588831309f828178c88d46ccd7fac0a0eaf2ae Mon Sep 17 00:00:00 2001 From: Mattia Date: Wed, 12 Oct 2022 18:31:23 +0200 Subject: [PATCH 1/3] Test SCP support --- addons/sourcemod/scripting/hextags.sp | 29 +++++- addons/sourcemod/scripting/include/scp.inc | 115 +++++++++++++++++++++ 2 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 addons/sourcemod/scripting/include/scp.inc diff --git a/addons/sourcemod/scripting/hextags.sp b/addons/sourcemod/scripting/hextags.sp index 70cdba8..1df3186 100644 --- a/addons/sourcemod/scripting/hextags.sp +++ b/addons/sourcemod/scripting/hextags.sp @@ -21,15 +21,23 @@ */ #include #include -#include + + + #include #include #include -#include #include #undef REQUIRE_EXTENSIONS #undef REQUIRE_PLUGIN +#include + +#undef MAXLENGTH_NAME +#undef MAXLENGTH_MESSAGE + +#include + #include #include #include @@ -40,6 +48,9 @@ #define REQUIRE_EXTENSIONS #define REQUIRE_PLUGIN +#include + + #define PLUGIN_AUTHOR "Hexah" #define PLUGIN_VERSION "" @@ -547,7 +558,19 @@ public void warden_OnDeputyRemoved(int client) RequestFrame(Frame_LoadTag, client); } -public Action CP_OnChatMessage(int & author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool & processcolors, bool & removecolors) +public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool &processcolors, bool &removecolors) +{ + return OnChatMessageEx(author, name, message, processcolors, removecolors); +} + +public Action OnChatMessage(int &author, ArrayList recipients, char[] name, char[] message) +{ + bool dummy; + return OnChatMessageEx(author, name, message, dummy, dummy); +} + + +public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& processcolors, bool& removecolors) { if (bHideTag[author]) { diff --git a/addons/sourcemod/scripting/include/scp.inc b/addons/sourcemod/scripting/include/scp.inc new file mode 100644 index 0000000..f2186ff --- /dev/null +++ b/addons/sourcemod/scripting/include/scp.inc @@ -0,0 +1,115 @@ +/************************************************************************ +************************************************************************* +Simple Plugins +Description: + Included file for Simple Chat Processor in the Simple Plugins project +************************************************************************* +************************************************************************* +This file is part of Simple Plugins project. + +This plugin 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 3 of the License, or +later version. + +This plugin 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 plugin. If not, see . +************************************************************************* +************************************************************************* +File Information +$Id$ +$Author$ +$Revision$ +$Date$ +$LastChangedBy$ +$LastChangedDate$ +$URL$ +$Copyright: (c) Simple Plugins 2008-2009$ +************************************************************************* +*************************************************************************/ + +#if defined _scp_included + #endinput +#endif +#define _scp_included + +#define MAXLENGTH_INPUT 128 // Inclues \0 and is the size of the chat input box. +#define MAXLENGTH_NAME 64 // This is backwords math to get compability. Sourcemod has it set at 32, but there is room for more. +#define MAXLENGTH_MESSAGE 256 // This is based upon the SDK and the length of the entire message, including tags, name, : etc. + +#define CHATFLAGS_INVALID 0 +#define CHATFLAGS_ALL (1<<0) +#define CHATFLAGS_TEAM (1<<1) +#define CHATFLAGS_SPEC (1<<2) +#define CHATFLAGS_DEAD (1<<3) + + + +/********************************************************************** + * When a player types a chat message + * + * NOTES: + * Use MAXLENGTH_ constants above for formating the strings + * Do not rely on the recipients handle to exist beyond the forward + * Do not start another usermessage (PrintToChat) within this forward + * + * @param author The client index of the player who sent the chat message (Byref) + * @param recipients The handle to the client index adt array of the players who should recieve the chat message + * @param name The client's name of the player who sent the chat message (Byref) + * @param message The contents of the chat message (Byref) + * @return Action + **********************************************************************/ +forward Action OnChatMessage(int &author, ArrayList recipients, char[] name, char[] message); + + +/********************************************************************** + * Called after all OnChatMessage forwards have been fired and the message is being broadcast. + * + * NOTES: + * Use MAXLENGTH_ constants above for formating the strings + * Do not rely on the recipients handle to exist beyond the forward + * + * @param author The client index of the player who sent the chat message + * @param recipients The handle to the client index adt array of the players who are receiting the chat message + * @param name The client's name of the player who sent the chat message (after any replacements) + * @param message The contents of the chat message (after any replacements) + * @noreturn + **********************************************************************/ +forward void OnChatMessage_Post(int author, ArrayList recipients, const char[] name, const char[] message); + + +/********************************************************************** + * Gets the current flags for the chat message + * Should only be called within OnChatMessage() or OnChatMessage_Post() + * + * @return The current type of chat message (see constants) + **********************************************************************/ + native int GetMessageFlags(); + + + +/** +Shared plugin information +**/ +public SharedPlugin:_pl_scp = +{ + name = "scp", + file = "simple-chatprocessor.smx", +#if defined REQUIRE_PLUGIN + required = 1 +#else + required = 0 +#endif +}; + +#if !defined REQUIRE_PLUGIN +public _pl_scp_SetNTVOptional() +{ + MarkNativeAsOptional("GetMessageFlags"); +} +#endif \ No newline at end of file From 1a24be6f046254f19b41d06545cfb41cc6fd0e6c Mon Sep 17 00:00:00 2001 From: Mattia Date: Wed, 12 Oct 2022 20:09:16 +0200 Subject: [PATCH 2/3] Implement library check --- addons/sourcemod/scripting/hextags.sp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/hextags.sp b/addons/sourcemod/scripting/hextags.sp index 1df3186..4f76a38 100644 --- a/addons/sourcemod/scripting/hextags.sp +++ b/addons/sourcemod/scripting/hextags.sp @@ -211,7 +211,10 @@ public void ConVar_ForceTimerHook(ConVar convar, const char[] oldValue, const ch public void OnAllPluginsLoaded() { logger.debug("Called OnAllPlugins!"); - + + if (!LibraryExists("scp") && !LibraryExists("chat-processor")) + SetFailState("[HexTags] Either chat-processor or Simple Chat Processor is required to run this plugin."); + if (FindPluginByFile("custom-chatcolors-cp.smx") || LibraryExists("ccc")) LogMessage("[HexTags] Found Custom Chat Colors running!\n Please avoid running it with this plugin!"); From 5c2666d9ae0ef38f52e79c4b042dc22061387219 Mon Sep 17 00:00:00 2001 From: Mattia Date: Fri, 14 Oct 2022 14:12:39 +0200 Subject: [PATCH 3/3] Update scp support: fix double dot --- addons/sourcemod/scripting/hextags.sp | 32 +- .../sourcemod/scripting/include/colorlib.inc | 760 ++++++++++++++++++ .../scripting/include/colorlib_map.inc | 341 ++++++++ addons/sourcemod/scripting/include/scp.inc | 15 +- 4 files changed, 1129 insertions(+), 19 deletions(-) create mode 100644 addons/sourcemod/scripting/include/colorlib.inc create mode 100644 addons/sourcemod/scripting/include/colorlib_map.inc diff --git a/addons/sourcemod/scripting/hextags.sp b/addons/sourcemod/scripting/hextags.sp index 4f76a38..6d30ad7 100644 --- a/addons/sourcemod/scripting/hextags.sp +++ b/addons/sourcemod/scripting/hextags.sp @@ -19,6 +19,11 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ + +#pragma semicolon 1 +#pragma newdecls required + + #include #include @@ -28,6 +33,7 @@ #include #include #include +#include #undef REQUIRE_EXTENSIONS #undef REQUIRE_PLUGIN @@ -54,8 +60,6 @@ #define PLUGIN_AUTHOR "Hexah" #define PLUGIN_VERSION "" -#pragma semicolon 1 -#pragma newdecls required // EVENTS @@ -179,7 +183,6 @@ public void OnPluginStart() hSelTagCookie = RegClientCookie("HexTags_SelectedTag", "Selected Tag", CookieAccess_Private); hVibilityAdminsCookie = RegClientCookie("HexTags_Visibility_Admins", "Show or hide the admin tags.", CookieAccess_Private); hIsAnonymousCookie = RegClientCookie("HexTags_AnonymousCookie", "Plugin that defines wether or not an admin is anonymous.", CookieAccess_Protected); - } public void OnConfigsExecuted() { @@ -212,8 +215,8 @@ public void OnAllPluginsLoaded() { logger.debug("Called OnAllPlugins!"); - if (!LibraryExists("scp") && !LibraryExists("chat-processor")) - SetFailState("[HexTags] Either chat-processor or Simple Chat Processor is required to run this plugin."); + // if (!LibraryExists("scp") && !LibraryExists("chat-processor")) + // SetFailState("[HexTags] Either chat-processor or Simple Chat Processor is required to run this plugin."); if (FindPluginByFile("custom-chatcolors-cp.smx") || LibraryExists("ccc")) LogMessage("[HexTags] Found Custom Chat Colors running!\n Please avoid running it with this plugin!"); @@ -563,17 +566,17 @@ public void warden_OnDeputyRemoved(int client) public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool &processcolors, bool &removecolors) { - return OnChatMessageEx(author, name, message, processcolors, removecolors); + return OnChatMessageEx(author, name, message, processcolors, removecolors, false); } public Action OnChatMessage(int &author, ArrayList recipients, char[] name, char[] message) { bool dummy; - return OnChatMessageEx(author, name, message, dummy, dummy); + return OnChatMessageEx(author, name, message, dummy, dummy, true); } -public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& processcolors, bool& removecolors) +public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& processcolors, bool& removecolors, bool processvariables) { if (bHideTag[author]) { @@ -619,7 +622,7 @@ public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& pr if (IsCharMB(name[i])) i += bytes - 2; } - Format(sNewName, MAXLENGTH_NAME, "%s%s{default}", selectedTags[author].ChatTag, sTemp); + Format(sNewName, MAXLENGTH_NAME, " %s%s", selectedTags[author].ChatTag, sTemp); } else if (StrEqual(selectedTags[author].NameColor, "{random}")) //Random name { @@ -642,12 +645,12 @@ public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& pr if (IsCharMB(name[i])) i += bytes - 2; } - Format(sNewName, MAXLENGTH_NAME, "%s%s{default}", selectedTags[author].ChatTag, sTemp); + Format(sNewName, MAXLENGTH_NAME, " %s%s", selectedTags[author].ChatTag, sTemp); } else { logger.debug("Default name"); - Format(sNewName, MAXLENGTH_NAME, "%s%s%s{default}", selectedTags[author].ChatTag, selectedTags[author].NameColor, name); + Format(sNewName, MAXLENGTH_NAME, " %s%s%s", selectedTags[author].ChatTag, selectedTags[author].NameColor, name); // The first color won't work if there is not a space at the beginning } Format(sNewMessage, MAXLENGTH_MESSAGE, "%s%s", selectedTags[author].ChatColor, message); @@ -775,6 +778,13 @@ public Action OnChatMessageEx(int& author, char[] name, char[] message, bool& pr processcolors = true; removecolors = false; + + if (processvariables) + { + logger.debug("Message: %s --- %s", name, message); + CFormat(name, MAXLENGTH_NAME); + CFormat(message, MAXLENGTH_MESSAGE); + } //Call the (post)forward Call_StartForward(fMessageProcessed); diff --git a/addons/sourcemod/scripting/include/colorlib.inc b/addons/sourcemod/scripting/include/colorlib.inc new file mode 100644 index 0000000..d26bd9f --- /dev/null +++ b/addons/sourcemod/scripting/include/colorlib.inc @@ -0,0 +1,760 @@ +// +// Copyright (C) 2020-2022 Oliver John Hitchcock. Licensed under GNU GPLv3. +// + +#if defined _colorlib_included + #endinput +#endif +#define _colorlib_included + +#include + +#define MAX_MESSAGE_LENGTH 512 + +#define SERVER_INDEX 0 +#define NO_INDEX -1 +#define NO_PLAYER -2 + +/* CL_Colors' properties */ +char _CL_buffer[MAX_MESSAGE_LENGTH]; +int _CL_buffer_index = 0; +int _CL_buffer_size = sizeof(_CL_buffer); + +#if !defined CL_UNIT_TEST + +bool _CL_proto_buff_support; +char _CL_buffer_tag[MAX_MESSAGE_LENGTH]; +bool _CL_skip_list[MAXPLAYERS + 1] = { false, ... }; + +/** + * Prints a message to a specific client in the chat area. + * Supports color tags. + * + * @param client Client index. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the client is not connected an error will be thrown. + */ +stock void CPrintToChat(int client, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToChat(client, _CL_buffer); +} + +/** + * Prints a message to a specific client in the chat area. + * Supports color tags. + * + * @param client Client index. + * @param author Author index whose color will be used for teamcolor tag. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the client or author are not connected an error will be thrown. + */ +stock void CPrintToChatEx(int client, int author, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + _CL_SendChatMessage(client, author, _CL_buffer); +} + +/** + * Prints a message to all clients in the chat area. + * Supports color tags. + * + * @param client Client index. + * @param message Message (formatting rules) + * @return No return + */ +stock void CPrintToChatAll(const char[] message, any ...) +{ + for (int i = 1; i <= MaxClients; ++i) + { + if (IsClientInGame(i) && !IsFakeClient(i) && !_CL_skip_list[i]) + { + SetGlobalTransTarget(i); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 2); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToChat(i, _CL_buffer); + } + + _CL_skip_list[i] = false; + } +} + +/** + * Prints a message to all clients in the chat area. + * Supports color tags. + * + * @param author Author index whos color will be used for teamcolor tag. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the author is not connected an error will be thrown. + */ +stock void CPrintToChatAllEx(int author, const char[] message, any ...) +{ + for (int i = 1; i <= MaxClients; ++i) + { + if (IsClientInGame(i) && !IsFakeClient(i) && !_CL_skip_list[i]) + { + SetGlobalTransTarget(i); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + _CL_SendChatMessage(i, author, _CL_buffer); + } + + _CL_skip_list[i] = false; + } +} + +/** + * Prints a message to all clients on a specific team. + * Supports color tags. + * + * @param team Team index. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the client is not connected an error will be thrown. + */ +stock void CPrintToChatTeam(int team, const char[] message, any ...) +{ + for (int i = 1; i <= MaxClients; ++i) + { + if (IsClientInGame(i) && + !IsFakeClient(i) && + !_CL_skip_list[i] && + GetClientTeam(i) == team) + { + SetGlobalTransTarget(i); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToChat(i, _CL_buffer); + } + + _CL_skip_list[i] = false; + } +} + +/** + * Prints a message to all clients on a specific team. + * Supports color tags. + * + * @param team Team index. + * @param author Author index whos color will be used for teamcolor tag. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the client is not connected an error will be thrown. + */ +stock void CPrintToChatTeamEx(int team, int author, const char[] message, any ...) +{ + for (int i = 1; i <= MaxClients; ++i) + { + if (IsClientInGame(i) && + !IsFakeClient(i) && + !_CL_skip_list[i] && + GetClientTeam(i) == team) + { + SetGlobalTransTarget(i); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + _CL_SendChatMessage(i, author, _CL_buffer); + } + + _CL_skip_list[i] = false; + } +} + +/** + * Prints a message to all admins with the given access flags. + * Supports color tags. + * + * @param flags Admin flags. + * @param message Message (formatting rules). + * @return No return + * + * On error/Errors: If the client is not connected an error will be thrown. + */ +stock void CPrintToChatAdmins(int flags, const char[] message, any ...) +{ + for (int i = 1; i <= MaxClients; ++i) + { + if (IsClientInGame(i) && !IsFakeClient(i) && !_CL_skip_list[i]) + { + if (CheckCommandAccess(i, "colorlib_admin", flags, true)) + { + SetGlobalTransTarget(i); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToChat(i, _CL_buffer); + } + } + + _CL_skip_list[i] = false; + } +} + +/** + * Reples to a message in a command. A client index of 0 will use PrintToServer(). + * If the command was from the console, PrintToConsole() is used. If the command was from chat, C_PrintToChat() is used. + * Supports color tags. + * + * @param client Client index, or 0 for server. + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + * + * On error/Errors: If the client is not connected or invalid. + */ +stock void CReplyToCommand(int client, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + if (client == 0) + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CRemoveTags(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToServer(_CL_buffer[_CL_buffer_index]); + } + else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CRemoveTags(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToConsole(client, _CL_buffer[_CL_buffer_index]); + } + else + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToChat(client, _CL_buffer); + } +} + +/** + * Reples to a message in a command. A client index of 0 will use PrintToServer(). + * If the command was from the console, PrintToConsole() is used. If the command was from chat, C_PrintToChat() is used. + * Supports color tags. + * + * @param client Client index, or 0 for server. + * @param author Author index whose color will be used for teamcolor tag. + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + * + * On error/Errors: If the client is not connected or invalid. + */ +stock void CReplyToCommandEx(int client, int author, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + if (client == 0) + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CRemoveTags(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToServer(_CL_buffer[_CL_buffer_index]); + } + else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CRemoveTags(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToConsole(client, _CL_buffer[_CL_buffer_index]); + } + else + { + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + _CL_SendChatMessage(client, author, _CL_buffer); + } +} + +/** + * Displays usage of an admin command to users depending on the setting of the sm_show_activity cvar. + * This version does not display a message to the originating client if used from chat triggers or menus. If manual replies are used for these cases, then this function will suffice. Otherwise, ShowActivity2() is slightly more useful. + * Supports color tags. + * + * @param client Client index, or 0 for server. + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + * + * On error/Errors: If the client is not connected or invalid. + */ +stock void CShowActivity(int client, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 3); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + ShowActivity(client, _CL_buffer[_CL_buffer_index]); +} + +/** + * Displays usage of an admin command to users depending on the setting of the sm_show_activity cvar. All users receive a message in their chat text, except for the originating client, who receives the message based on the current ReplySource. + * Supports color tags. + * + * @param client Client index, or 0 for server. + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + * + * On error/Errors: If the client is not connected or invalid. + */ +stock void CShowActivity2(int client, const char[] tag, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + strcopy(_CL_buffer_tag, sizeof(_CL_buffer_tag), tag); + CFormat(_CL_buffer_tag, sizeof(_CL_buffer_tag)); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + + ShowActivity2(client, _CL_buffer_tag, _CL_buffer); +} + +/** + * Same as ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing). + * Supports color tags. + * + * @param client Client index, or 0 for server. + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + * + * On error/Errors: If the client is not connected or invalid. + */ +stock void CShowActivityEx(int client, const char[] tag, const char[] message, any ...) +{ + SetGlobalTransTarget(client); + + strcopy(_CL_buffer_tag, sizeof(_CL_buffer_tag), tag); + CFormat(_CL_buffer_tag, sizeof(_CL_buffer_tag)); + + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 4); + CFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + + ShowActivityEx(client, _CL_buffer_tag, _CL_buffer); +} + +/** + * Replaces PrintToServer. + * Removes color tags. + * + * @param message Formatting rules. + * @param ... Variable number of format parameters. + * @return No return + */ +stock void CPrintToServer(const char[] message, any ...) +{ + VFormat(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message, 2); + CRemoveTags(_CL_buffer[_CL_buffer_index], _CL_buffer_size); + PrintToServer(_CL_buffer[_CL_buffer_index]); +} + +/** + * Gets a clients name that is safe to use with Color Lib. + * + * @param client Client index. + * @param name Buffer to store the clients name. + * @param maxlength The size of the buffer. + * @return No return + */ +stock void CGetClientName(int client, char[] name, int maxlength, bool remove = true) +{ + GetClientName(client, name, maxlength); + if (remove) + { + CRemoveTags(name, maxlength); + } + else + { + CEscapeTags(name, maxlength); + } +} + +#endif // not CL_UNIT_TEST + +/** + * Removes color tags from the string. + * E.g. "{default}Hello {red}World" -> "Hello World". + * + * @param message String. + * @param maxlength Size of the message buffer. + * @return No return + */ +stock void CRemoveTags(char[] message, int maxlength) +{ + int index = 0; + for (int i = 0; i < maxlength; ++i) + { + if (message[i] == 0x00) + { + break; + } + + if (message[i] == '{') + { + ++i; + while (message[i] != '}') + { + ++i; + } + } + else if (message[i] == '\\') + { + ++i; + if (message[i] == '{') + { + message[index] = '{'; + } + else + { + message[index] = '\\'; + --i; + } + + ++index; + } + else + { + message[index] = message[i]; + ++index; + } + } + + message[index] = 0x00; +} + +/** + * Removes colors escape codes from the string. + * E.g. "\x01Hello \x02World" -> "Hello World". + * + * @param message String. + * @param maxlength Size of the message buffer. + * @return No return + */ +stock void CRemoveColors(char[] message, int maxlength) +{ + int index = 0; + for (int i = 0; i < maxlength; ++i) + { + if (message[i] == 0x00) + { + break; + } + + // if the current character is an escape code it should not be copied + if (message[i] >= 0x01 && message[i] <= 0x10) + { + continue; + } + + message[index] = message[i]; + ++index; + } + + message[index] = 0x00; +} + +/** + * Removes color tags and colors escape codes from the string. + * E.g. "\x01Hello \x02World" -> "Hello World". + * E.g. "{default}Hello {red}World" -> "Hello World". + * + * @param message String. + * @param maxlength Size of the message buffer. + * @return No return + */ +stock void CRemoveAllColors(char[] message, int maxlength) +{ + int index = 0; + for (int i = 0; i < maxlength; ++i) + { + if (message[i] == 0x00) + { + break; + } + + // if the current character is an escape code it should not be copied + if (message[i] >= 0x01 && message[i] <= 0x10) + { + continue; + } + + if (message[i] == '{') + { + ++i; + while (message[i] != '}') + { + ++i; + } + } + else if (message[i] == '\\') + { + ++i; + if (message[i] == '{') + { + message[index] = '{'; + } + else + { + message[index] = '\\'; + --i; + } + + ++index; + } + else + { + message[index] = message[i]; + ++index; + } + } + + message[index] = 0x00; +} + +/** + * Escapes colors escape codes from the string. + * E.g. "{red}Hello {blue}World" -> "\{red}Hello \{blue}World". + * This means they shal be ignored by CFormat, useful for sanitising player + * names for printing. + * + * @param message String. + * @param maxlength Size of the message buffer. + * @return No return + */ +stock void CEscapeTags(char[] message, int maxlength) +{ + strcopy(_CL_buffer[_CL_buffer_index], _CL_buffer_size, message); + + int i = _CL_buffer_index; + int index = 0; + for (; index < maxlength; ++i) + { + if (_CL_buffer[i] == 0x00) + { + break; + } + + if (_CL_buffer[i] == '{') + { + message[index] = '\\'; + ++index; + message[index] = '{'; + ++index; + } + else if (_CL_buffer[i] == '\\') + { + ++i; + if (_CL_buffer[i] == '{') + { + message[index] = '\\'; + ++index; + message[index] = '{'; + } + else + { + message[index] = '\\'; + --i; + } + + ++index; + } + else + { + message[index] = _CL_buffer[i]; + ++index; + } + } + + message[index] = 0x00; +} + +/** + * Replaces color tags in a string with color codes + * + * @param message String. + * @param maxlength Size of the message buffer. + * @return Client index that can be used for SayText2 author index + * + * On error/Errors: If there is more then one team color is used an error will be thrown. + */ +stock void CFormat(char[] message, int maxlength) +{ + int index = 0; + for (int i = 0; i < maxlength; ++i) + { + if (message[i] == 0x00) + { + break; + } + + if (message[i] == '{') + { + ++i; + int length = 0; + char cc = view_as(_CL_ColorMap(message[i], length)); + if (cc) + { + message[index] = cc; + i += length; + } + else + { + message[index] = '{'; + } + + /* we need to unpeek the increment for skipping over all of the + * color tag + so we dont skip a char for a bad tag */ + --i; + ++index; + } + else if (message[i] == '\\') + { + ++i; + if (message[i] == '{') + { + message[index] = '{'; + } + else + { + message[index] = '\\'; + --i; + } + + ++index; + } + else + { + message[index] = message[i]; + ++index; + } + } + + message[index] = 0x00; +} + +#if !defined CL_UNIT_TEST + +/** + * This function should only be used right in front of + * C_PrintToChatAll or C_PrintToChatAllEx and it tells + * to those funcions to skip specified client when printing + * message to all clients. After message is printed client will + * no more be skipped. + * + * @param client Client index + * @return No return + */ +stock void CSkipNextClient(int client) +{ + if (client < 1 || client > MaxClients) + ThrowError("Invalid client index %d", client); + + _CL_skip_list[client] = true; +} + +/** + * Initialises the _CL_buffer for color formatting + * + * @param message String. + * @return First free index in the array + */ +stock int CPreFormat(char[] message) +{ + int index = 0; + // If CS:GO set invisible precolor + if (GetEngineVersion() == Engine_CSGO) + { + message[0] = ' '; + ++index; + } + + message[index] = 0x01; + ++index; + + return index; +} + + + +/** + * Sends a SayText2 usermessage to a client + * + * @param message Client index + * @param author Author index + * @param message Message + * @return No return. + */ +stock void CSayText2(int client, int author, const char[] message) +{ + if (_CL_proto_buff_support) + { + Protobuf pbMessage = view_as(StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS)); + pbMessage.SetInt("ent_idx", author); + pbMessage.SetBool("chat", true); + pbMessage.SetString("msg_name", message); + pbMessage.AddString("params", ""); + pbMessage.AddString("params", ""); + pbMessage.AddString("params", ""); + pbMessage.AddString("params", ""); + } + else + { + Handle hMessage = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS); + BfWriteByte(hMessage, author); + BfWriteByte(hMessage, true); + BfWriteString(hMessage, message); + } + + EndMessage(); +} + +/** + * Sends a message to a client. + * + * @param message Client index + * @param author Author index + * @param message Message + * @return No return. + */ +stock void _CL_SendChatMessage(int client, int author, char[] message) +{ + if (author) + { + CSayText2(client, author, message); + } + else + { + PrintToChat(client, message); + } +} + +/* BADNESS BELOW THIS LINE DO NOT EDIT */ + +public void OnPluginStart() +{ + _CL_proto_buff_support = (GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available) && (GetUserMessageType() == UM_Protobuf); + _CL_buffer_index = CPreFormat(_CL_buffer); + _CL_buffer_size = sizeof(_CL_buffer) - _CL_buffer_index; + _CL_OnPluginStart(); +} + +#define OnPluginStart _CL_OnPluginStart + +#endif // not CL_UNIT_TEST diff --git a/addons/sourcemod/scripting/include/colorlib_map.inc b/addons/sourcemod/scripting/include/colorlib_map.inc new file mode 100644 index 0000000..c93c04c --- /dev/null +++ b/addons/sourcemod/scripting/include/colorlib_map.inc @@ -0,0 +1,341 @@ +// +// This file was generated with color_gen.py and should not be used outside of colorlib.inc +// +// Do not edit! Regenerate this file with color_gen.py (see https://github.com/c0rp3n/colorlib-gen) +// + +#if defined _colorlib_map_included + #endinput +#endif +#define _colorlib_map_included + +enum CL_Color +{ + CL_Color_Default = 0x01, + CL_Color_Prefix = 0x04, + CL_Color_Reply2cmd = 0x01, + CL_Color_Showactivity = 0x01, + CL_Color_Error = 0x07, + CL_Color_Highlight = 0x10, + CL_Color_Player = 0x09, + CL_Color_Settings = 0x02, + CL_Color_Command = 0x02, + CL_Color_Team_0 = 0x08, + CL_Color_Team_1 = 0x09, + CL_Color_Team_2 = 0x11, + CL_Color_Teamcolor = 0x03, + CL_Color_Red = 0x07, + CL_Color_Lightred = 0x0F, + CL_Color_Darkred = 0x02, + CL_Color_Bluegrey = 0x0A, + CL_Color_Blue = 0x0B, + CL_Color_Darkblue = 0x0C, + CL_Color_Purple = 0x03, + CL_Color_Orchid = 0x0E, + CL_Color_Orange = 0x10, + CL_Color_Yellow = 0x09, + CL_Color_Gold = 0x10, + CL_Color_Lightgreen = 0x05, + CL_Color_Green = 0x04, + CL_Color_Lime = 0x06, + CL_Color_Grey = 0x08, + CL_Color_Grey2 = 0x0D, + CL_Color_Engine_1 = 0x01, + CL_Color_Engine_2 = 0x02, + CL_Color_Engine_3 = 0x03, + CL_Color_Engine_4 = 0x04, + CL_Color_Engine_5 = 0x05, + CL_Color_Engine_6 = 0x06, + CL_Color_Engine_7 = 0x07, + CL_Color_Engine_8 = 0x08, + CL_Color_Engine_9 = 0x09, + CL_Color_Engine_10 = 0x0A, + CL_Color_Engine_11 = 0x0B, + CL_Color_Engine_12 = 0x0C, + CL_Color_Engine_13 = 0x0D, + CL_Color_Engine_14 = 0x0E, + CL_Color_Engine_15 = 0x0F, + CL_Color_Engine_16 = 0x10, +}; + +CL_Color _CL_ColorMap(const char[] color, int& length) +{ + if (color[0] == 'e') + { + if (color[1] == 'n') + { + if (color[7] == '1') + { + if (color[8] == '}') + { + length = 9; + return CL_Color_Engine_1; + } + else if (color[8] == '0') + { + length = 10; + return CL_Color_Engine_10; + } + else if (color[8] == '1') + { + length = 10; + return CL_Color_Engine_11; + } + else if (color[8] == '2') + { + length = 10; + return CL_Color_Engine_12; + } + else if (color[8] == '3') + { + length = 10; + return CL_Color_Engine_13; + } + else if (color[8] == '4') + { + length = 10; + return CL_Color_Engine_14; + } + else if (color[8] == '5') + { + length = 10; + return CL_Color_Engine_15; + } + else if (color[8] == '6') + { + length = 10; + return CL_Color_Engine_16; + } + } + else if (color[7] == '2') + { + length = 9; + return CL_Color_Engine_2; + } + else if (color[7] == '3') + { + length = 9; + return CL_Color_Engine_3; + } + else if (color[7] == '4') + { + length = 9; + return CL_Color_Engine_4; + } + else if (color[7] == '5') + { + length = 9; + return CL_Color_Engine_5; + } + else if (color[7] == '6') + { + length = 9; + return CL_Color_Engine_6; + } + else if (color[7] == '7') + { + length = 9; + return CL_Color_Engine_7; + } + else if (color[7] == '8') + { + length = 9; + return CL_Color_Engine_8; + } + else if (color[7] == '9') + { + length = 9; + return CL_Color_Engine_9; + } + } + else if (color[1] == 'r') + { + length = 6; + return CL_Color_Error; + } + } + else if (color[0] == 't') + { + if (color[4] == ' ') + { + if (color[5] == '0') + { + length = 7; + return CL_Color_Team_0; + } + else if (color[5] == '1') + { + length = 7; + return CL_Color_Team_1; + } + else if (color[5] == '2') + { + length = 7; + return CL_Color_Team_2; + } + } + else if (color[4] == 'c') + { + length = 10; + return CL_Color_Teamcolor; + } + } + else if (color[0] == 'g') + { + if (color[1] == 'r') + { + if (color[3] == 'y') + { + if (color[4] == '}') + { + length = 5; + return CL_Color_Grey; + } + else if (color[4] == '2') + { + length = 6; + return CL_Color_Grey2; + } + } + else if (color[3] == 'e') + { + length = 6; + return CL_Color_Green; + } + } + else if (color[1] == 'o') + { + length = 5; + return CL_Color_Gold; + } + } + else if (color[0] == 'd') + { + if (color[1] == 'a') + { + if (color[4] == 'r') + { + length = 8; + return CL_Color_Darkred; + } + else if (color[4] == 'b') + { + length = 9; + return CL_Color_Darkblue; + } + } + else if (color[1] == 'e') + { + length = 8; + return CL_Color_Default; + } + } + else if (color[0] == 'p') + { + if (color[1] == 'r') + { + length = 7; + return CL_Color_Prefix; + } + else if (color[1] == 'l') + { + length = 7; + return CL_Color_Player; + } + else if (color[1] == 'u') + { + length = 7; + return CL_Color_Purple; + } + } + else if (color[0] == 'l') + { + if (color[2] == 'g') + { + if (color[5] == 'r') + { + length = 9; + return CL_Color_Lightred; + } + else if (color[5] == 'g') + { + length = 11; + return CL_Color_Lightgreen; + } + } + else if (color[2] == 'm') + { + length = 5; + return CL_Color_Lime; + } + } + else if (color[0] == 'r') + { + if (color[2] == 'p') + { + length = 10; + return CL_Color_Reply2cmd; + } + else if (color[2] == 'd') + { + length = 4; + return CL_Color_Red; + } + } + else if (color[0] == 's') + { + if (color[1] == 'h') + { + length = 13; + return CL_Color_Showactivity; + } + else if (color[1] == 'e') + { + length = 9; + return CL_Color_Settings; + } + } + else if (color[0] == 'b') + { + if (color[4] == 'g') + { + length = 9; + return CL_Color_Bluegrey; + } + else if (color[4] == '}') + { + length = 5; + return CL_Color_Blue; + } + } + else if (color[0] == 'o') + { + if (color[2] == 'c') + { + length = 7; + return CL_Color_Orchid; + } + else if (color[2] == 'a') + { + length = 7; + return CL_Color_Orange; + } + } + else if (color[0] == 'h') + { + length = 10; + return CL_Color_Highlight; + } + else if (color[0] == 'c') + { + length = 8; + return CL_Color_Command; + } + else if (color[0] == 'y') + { + length = 7; + return CL_Color_Yellow; + } + + return view_as(0x00); +} diff --git a/addons/sourcemod/scripting/include/scp.inc b/addons/sourcemod/scripting/include/scp.inc index f2186ff..41c980b 100644 --- a/addons/sourcemod/scripting/include/scp.inc +++ b/addons/sourcemod/scripting/include/scp.inc @@ -38,11 +38,11 @@ $Copyright: (c) Simple Plugins 2008-2009$ #endif #define _scp_included -#define MAXLENGTH_INPUT 128 // Inclues \0 and is the size of the chat input box. +#define MAXLENGTH_INPUT 128 // Inclues \0 and is the size of the chat input box. #define MAXLENGTH_NAME 64 // This is backwords math to get compability. Sourcemod has it set at 32, but there is room for more. -#define MAXLENGTH_MESSAGE 256 // This is based upon the SDK and the length of the entire message, including tags, name, : etc. +#define MAXLENGTH_MESSAGE 256 // This is based upon the SDK and the length of the entire message, including tags, name, : etc. -#define CHATFLAGS_INVALID 0 +#define CHATFLAGS_INVALID 0 #define CHATFLAGS_ALL (1<<0) #define CHATFLAGS_TEAM (1<<1) #define CHATFLAGS_SPEC (1<<2) @@ -62,7 +62,7 @@ $Copyright: (c) Simple Plugins 2008-2009$ * @param recipients The handle to the client index adt array of the players who should recieve the chat message * @param name The client's name of the player who sent the chat message (Byref) * @param message The contents of the chat message (Byref) - * @return Action + * @noreturn **********************************************************************/ forward Action OnChatMessage(int &author, ArrayList recipients, char[] name, char[] message); @@ -89,15 +89,14 @@ forward void OnChatMessage_Post(int author, ArrayList recipients, const char[] n * * @return The current type of chat message (see constants) **********************************************************************/ - native int GetMessageFlags(); +native int GetMessageFlags(); /** Shared plugin information **/ -public SharedPlugin:_pl_scp = -{ +public SharedPlugin __pl_scp = { name = "scp", file = "simple-chatprocessor.smx", #if defined REQUIRE_PLUGIN @@ -108,7 +107,7 @@ public SharedPlugin:_pl_scp = }; #if !defined REQUIRE_PLUGIN -public _pl_scp_SetNTVOptional() +public void __pl_scp_SetNTVOptional() { MarkNativeAsOptional("GetMessageFlags"); }