This commit is contained in:
xen
2020-03-25 20:09:12 +02:00
committed by xen
commit 527e7ec05e
420 changed files with 68682 additions and 0 deletions
+923
View File
@@ -0,0 +1,923 @@
/**************************************************************************
* *
* Colored Chat Functions *
* Author: exvel, Editor: Popoklopsi, Powerlord, Bara *
* Version: 2.0.0-MC *
* *
**************************************************************************/
#if defined _colors_included
#endinput
#endif
#define _colors_included
#define MAX_MESSAGE_LENGTH 250
#define MAX_COLORS 19
#define SERVER_INDEX 0
#define NO_INDEX -1
#define NO_PLAYER -2
#define CSGO_TEAM_T 2
#define CSGO_TEAM_CT 3
#define CSGO_TAG_T "{t}"
#define CSGO_TAG_CT "{ct}"
enum C_Colors {
Color_Default = 0,
Color_Darkred,
Color_Green,
Color_Lightgreen,
Color_Red,
Color_Blue,
Color_Olive,
Color_Lime,
Color_Lightred,
Color_Purple,
Color_Grey,
Color_Yellow,
Color_Orange,
Color_Bluegrey,
Color_Lightblue,
Color_Darkblue,
Color_Grey2,
Color_Orchid,
Color_Lightred2
}
/* C_Colors' properties */
char C_Tag[][] = {"{default}", "{darkred}", "{green}", "{lightgreen}", "{red}", "{blue}", "{olive}", "{lime}", "{lightred}", "{purple}", "{grey}", "{yellow}", "{orange}", "{bluegrey}", "{lightblue}", "{darkblue}", "{grey2}", "{orchid}", "{lightred2}"};
char C_TagCode[][] = {"\x01", "\x02", "\x04", "\x03", "\x03", "\x03", "\x05", "\x06", "\x07", "\x03", "\x08", "\x09", "\x10", "\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F"};
bool C_TagReqSayText2[] = {false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false};
bool C_EventIsHooked;
bool C_SkipList[MAXPLAYERS+1];
/* Game default profile */
bool C_Profile_Colors[] = {true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
int C_Profile_TeamIndex[] = {NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX};
bool C_Profile_SayText2;
static ConVar sm_show_activity;
/**
* Prints a message to a specific client in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock void C_PrintToChat(int client, const char[] szMessage, any ...) {
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
if (!IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
}
char szBuffer[MAX_MESSAGE_LENGTH];
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 3);
int index = C_Format(szCMessage, sizeof(szCMessage));
if (index == NO_INDEX) {
PrintToChat(client, "%s", szCMessage);
}
else {
C_SayText2(client, index, szCMessage);
}
}
/**
* 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 szMessage Formatting rules.
* @param ... Variable number of format parameters.
* @return No return
*
* On error/Errors: If the client is not connected or invalid.
*/
stock void C_ReplyToCommand(int client, const char[] szMessage, any ...) {
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
VFormat(szCMessage, sizeof(szCMessage), szMessage, 3);
if (client == 0) {
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToServer("%s", szCMessage);
}
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToConsole(client, "%s", szCMessage);
}
else {
C_PrintToChat(client, "%s", szCMessage);
}
}
/**
* 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 szMessage Formatting rules.
* @param ... Variable number of format parameters.
* @return No return
*
* On error/Errors: If the client is not connected or invalid.
*/
stock void C_ReplyToCommandEx(int client, int author, const char[] szMessage, any ...) {
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
VFormat(szCMessage, sizeof(szCMessage), szMessage, 4);
if (client == 0) {
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToServer("%s", szCMessage);
}
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToConsole(client, "%s", szCMessage);
}
else {
C_PrintToChatEx(client, author, "%s", szCMessage);
}
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules)
* @return No return
*/
stock void C_PrintToChatAll(const char[] szMessage, any ...) {
char szBuffer[MAX_MESSAGE_LENGTH];
for (int i = 1; i <= MaxClients; ++i) {
if (IsClientInGame(i) && !IsFakeClient(i) && !C_SkipList[i]) {
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 2);
C_PrintToChat(i, "%s", szBuffer);
}
C_SkipList[i] = false;
}
}
/**
* Prints a message to a specific client in the chat area.
* Supports color tags and teamcolor tag.
*
* @param client Client index.
* @param author Author index whose color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client or author are not connected an error will be thrown.
*/
stock void C_PrintToChatEx(int client, int author, const char[] szMessage, any ...) {
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
if (!IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
}
if (author < 0 || author > MaxClients) {
ThrowError("Invalid client index %d", author);
}
char szBuffer[MAX_MESSAGE_LENGTH];
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 4);
int index = C_Format(szCMessage, sizeof(szCMessage), author);
if (index == NO_INDEX) {
PrintToChat(client, "%s", szCMessage);
}
else {
C_SayText2(client, author, szCMessage);
}
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags and teamcolor tag.
*
* @param author Author index whos color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock void C_PrintToChatAllEx(int author, const char[] szMessage, any ...) {
if (author < 0 || author > MaxClients) {
ThrowError("Invalid client index %d", author);
}
if (!IsClientInGame(author)) {
ThrowError("Client %d is not in game", author);
}
char szBuffer[MAX_MESSAGE_LENGTH];
for (int i = 1; i <= MaxClients; ++i) {
if (IsClientInGame(i) && !IsFakeClient(i) && !C_SkipList[i]) {
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 3);
C_PrintToChatEx(i, author, "%s", szBuffer);
}
C_SkipList[i] = false;
}
}
/**
* Removes color tags from the string.
*
* @param szMessage String.
* @return No return
*/
stock void C_RemoveTags(char[] szMessage, int maxlength) {
for (int i = 0; i < MAX_COLORS; i++) {
ReplaceString(szMessage, maxlength, C_Tag[i], "", false);
}
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
}
/**
* Checks whether a color is allowed or not
*
* @param tag Color Tag.
* @return True when color is supported, otherwise false
*/
stock bool C_ColorAllowed(C_Colors color) {
if (!C_EventIsHooked) {
C_SetupProfile();
C_EventIsHooked = true;
}
return C_Profile_Colors[color];
}
/**
* Replace the color with another color
* Handle with care!
*
* @param color color to replace.
* @param newColor color to replace with.
* @noreturn
*/
stock void C_ReplaceColor(C_Colors color, C_Colors newColor) {
if (!C_EventIsHooked) {
C_SetupProfile();
C_EventIsHooked = true;
}
C_Profile_Colors[color] = C_Profile_Colors[newColor];
C_Profile_TeamIndex[color] = C_Profile_TeamIndex[newColor];
C_TagReqSayText2[color] = C_TagReqSayText2[newColor];
Format(C_TagCode[color], sizeof(C_TagCode[]), C_TagCode[newColor]);
}
/**
* 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 C_SkipNextClient(int client) {
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
C_SkipList[client] = true;
}
/**
* Replaces color tags in a string with color codes
*
* @param szMessage String.
* @param maxlength Maximum length of the string 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 int C_Format(char[] szMessage, int maxlength, int author = NO_INDEX, bool csgofix = true) {
/* Hook event for auto profile setup on map start */
if (!C_EventIsHooked) {
C_SetupProfile();
HookEvent("server_spawn", C_Event_MapStart, EventHookMode_PostNoCopy);
C_EventIsHooked = true;
}
int iRandomPlayer = NO_INDEX;
EngineVersion engine = GetEngineVersion();
// On CS:GO set invisible precolor
if (csgofix && engine == Engine_CSGO) {
Format(szMessage, maxlength, " %s", szMessage);
}
/* If author was specified replace {teamcolor} tag */
if (author != NO_INDEX) {
if (C_Profile_SayText2) {
ReplaceString(szMessage, maxlength, "{teamcolor}", "\x03", false);
iRandomPlayer = author;
}
/* If saytext2 is not supported by game replace {teamcolor} with green tag */
else {
ReplaceString(szMessage, maxlength, "{teamcolor}", C_TagCode[Color_Green], false);
}
}
else {
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
}
/* For other color tags we need a loop */
for (int i = 0; i < MAX_COLORS; i++) {
int iTagStatus = -1;
if (StrContains(szMessage, C_Tag[i], false) != -1) {
iTagStatus = 0;
}
/* On CS:GO {red} and {blue} name is so strange for team colors. */
if (engine == Engine_CSGO) {
if ((C_Profile_TeamIndex[i] == CSGO_TEAM_T && StrContains(szMessage, CSGO_TAG_T, false) != -1) ||
(C_Profile_TeamIndex[i] == CSGO_TEAM_CT && StrContains(szMessage, CSGO_TAG_CT, false) != -1)) {
iTagStatus = 1;
}
}
/* If tag not found - skip */
if (iTagStatus == -1) {
continue;
}
/* If tag is not supported by game replace it with green tag */
else if (!C_Profile_Colors[i]) {
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
}
/* If tag doesn't need saytext2 simply replace */
else if (!C_TagReqSayText2[i]) {
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[i], false);
}
/* Tag needs saytext2 */
else {
/* If saytext2 is not supported by game replace tag with green tag */
if (!C_Profile_SayText2) {
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
}
/* Game supports saytext2 */
else {
/* If random player for tag wasn't specified replace tag and find player */
if (iRandomPlayer == NO_INDEX) {
/* Searching for valid client for tag */
iRandomPlayer = C_FindRandomPlayerByTeam(C_Profile_TeamIndex[i]);
/* If player not found replace tag with green color tag */
if (iRandomPlayer == NO_PLAYER) {
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
if (iTagStatus == 1)
ReplaceString(szMessage, maxlength, C_Profile_TeamIndex[i] == CSGO_TEAM_T ? CSGO_TAG_T : CSGO_TAG_CT, C_TagCode[Color_Green], false);
}
/* If player was found simply replace */
else {
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[i], false);
if (iTagStatus == 1)
ReplaceString(szMessage, maxlength, C_Profile_TeamIndex[i] == CSGO_TEAM_T ? CSGO_TAG_T : CSGO_TAG_CT, C_TagCode[i], false);
}
}
/* If found another team color tag throw error */
else {
//ReplaceString(szMessage, maxlength, C_Tag[i], "");
ThrowError("Using two team colors in one message is not allowed");
}
}
}
}
return iRandomPlayer;
}
/**
* Finds a random player with specified team
*
* @param color_team Client team.
* @return Client index or NO_PLAYER if no player found
*/
stock int C_FindRandomPlayerByTeam(int color_team) {
if (color_team == SERVER_INDEX) {
return 0;
}
int[] players = new int[MaxClients];
int num;
for (int i = 1; i <= MaxClients; ++i) {
if (IsClientInGame(i) && GetClientTeam(i) == color_team) {
players[num++] = i;
}
}
if (num) {
return players[GetRandomInt(0, num-1)];
}
return NO_PLAYER;
}
/**
* Sends a SayText2 usermessage to a client
*
* @param szMessage Client index
* @param maxlength Author index
* @param szMessage Message
* @return No return.
*/
stock void C_SayText2(int client, int author, const char[] szMessage) {
Handle hBuffer = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
if (GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) {
Protobuf pb = UserMessageToProtobuf(hBuffer);
pb.SetInt("ent_idx", author);
pb.SetBool("chat", true);
pb.SetString("msg_name", szMessage);
pb.AddString("params", "");
pb.AddString("params", "");
pb.AddString("params", "");
pb.AddString("params", "");
}
else {
BfWrite bf = UserMessageToBfWrite(hBuffer);
bf.WriteByte(author);
bf.WriteByte(true);
bf.WriteString(szMessage);
}
EndMessage();
}
/**
* Creates game color profile
* This function must be edited if you want to add more games support
*
* @return No return.
*/
stock void C_SetupProfile() {
EngineVersion engine = GetEngineVersion();
if (engine == Engine_CSS) {
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_CSGO) {
C_Profile_Colors[Color_Red] = true; // \x03 (T Color via SayText2)
C_Profile_Colors[Color_Blue] = true; // \x03 (CT Color via SayText2)
// Color_Default // \x01
C_Profile_Colors[Color_Darkred] = true; // \x02
C_Profile_Colors[Color_Purple] = true; // \x03
// Color_Green // \x04
C_Profile_Colors[Color_Olive] = true; // \x05
C_Profile_Colors[Color_Lime] = true; // \x06
C_Profile_Colors[Color_Lightred] = true; // \x07
C_Profile_Colors[Color_Grey] = true; // \x08
C_Profile_Colors[Color_Yellow] = true; // \x09
C_Profile_Colors[Color_Bluegrey] = true; // \x0A
C_Profile_Colors[Color_Lightblue] = true; // \x0B
C_Profile_Colors[Color_Darkblue] = true; // \x0C
C_Profile_Colors[Color_Grey2] = true; // \x0D
C_Profile_Colors[Color_Orchid] = true; // \x0E
C_Profile_Colors[Color_Lightred2] = true; // \x0F
C_Profile_Colors[Color_Orange] = true; // \x10
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_TF2) {
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_Left4Dead || engine == Engine_Left4Dead2) {
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 3;
C_Profile_TeamIndex[Color_Blue] = 2;
C_Profile_SayText2 = true;
}
else if (engine == Engine_HL2DM) {
/* hl2mp profile is based on mp_teamplay convar */
if (GetConVarBool(FindConVar("mp_teamplay"))) {
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Red] = 3;
C_Profile_TeamIndex[Color_Blue] = 2;
C_Profile_SayText2 = true;
}
else {
C_Profile_SayText2 = false;
C_Profile_Colors[Color_Olive] = true;
}
}
else if (engine == Engine_DODS) {
C_Profile_Colors[Color_Olive] = true;
C_Profile_SayText2 = false;
}
/* Profile for other games */
else {
if (GetUserMessageId("SayText2") == INVALID_MESSAGE_ID) {
C_Profile_SayText2 = false;
}
else {
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
}
}
public Action C_Event_MapStart(Event event, const char[] name, bool dontBroadcast) {
C_SetupProfile();
for (int i = 1; i <= MaxClients; ++i) {
C_SkipList[i] = false;
}
}
/**
* 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,
* C_ShowActivity2() is slightly more useful.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivity(int client, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char tag[] = "[SM] ";
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client)) {
ThrowError("Client index %d is invalid", client);
}
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE) {
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || (display_in_chat && i == client)) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID || !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Same as C_ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing).
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to display with.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivityEx(int client, const char[] tag, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client)) {
ThrowError("Client index %d is invalid", client);
}
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE) {
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || (display_in_chat && i == client)) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID || !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* 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 doing the action, or 0 for server.
* @param tags Tag to prepend to the message.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivity2(int client, const char[] tag, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
// ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client)) {
ThrowError("Client index %d is invalid", client);
}
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
/* We don't display directly to the console because the chat text
* simply gets added to the console, so we don't want it to print
* twice.
*/
C_PrintToChatEx(client, client, "%s%s", tag, szBuffer);
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || i == client) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
+992
View File
@@ -0,0 +1,992 @@
// MOAR COLORS
// By Dr. McKay
// Inspired by: https://forums.alliedmods.net/showthread.php?t=96831
#if defined _more_colors_included
#endinput
#endif
#define _more_colors_included
#pragma newdecls optional
#include <regex>
#define MORE_COLORS_VERSION "2.0.0-MC"
#define MC_MAX_MESSAGE_LENGTH 256
#define MAX_BUFFER_LENGTH (MC_MAX_MESSAGE_LENGTH * 4)
#define MCOLOR_RED 0xFF4040
#define MCOLOR_BLUE 0x99CCFF
#define MCOLOR_GRAY 0xCCCCCC
#define MCOLOR_GREEN 0x3EFF3E
#define MC_GAME_DODS 0
bool MC_SkipList[MAXPLAYERS+1];
StringMap MC_Trie;
int MC_TeamColors[][] = {{0xCCCCCC, 0x4D7942, 0xFF4040}}; // Multi-dimensional array for games that don't support SayText2. First index is the game index (as defined by the GAME_ defines), second index is team. 0 = spectator, 1 = team1, 2 = team2
static ConVar sm_show_activity;
/**
* Prints a message to a specific client in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param message Message (formatting rules).
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock void MC_PrintToChat(int client, const char[] message, any ...) {
MC_CheckTrie();
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if (!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
char buffer[MAX_BUFFER_LENGTH];
char buffer2[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
MC_ReplaceColorCodes(buffer2);
MC_SendMessage(client, buffer2);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param message Message (formatting rules).
*/
stock void MC_PrintToChatAll(const char[] message, any ...) {
MC_CheckTrie();
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || MC_SkipList[i]) {
MC_SkipList[i] = false;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 2);
MC_ReplaceColorCodes(buffer2);
MC_SendMessage(i, buffer2);
}
}
/**
* Prints a message to a specific client in the chat area.
* Supports color tags and teamcolor tag.
*
* @param client Client index.
* @param author Author index whose color will be used for teamcolor tag.
* @param message Message (formatting rules).
*
* On error/Errors: If the client or author are not connected an error will be thrown
*/
stock void MC_PrintToChatEx(int client, int author, const char[] message, any ...) {
MC_CheckTrie();
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if (!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
if (author <= 0 || author > MaxClients) {
ThrowError("Invalid client index %i", author);
}
if (!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 4);
MC_ReplaceColorCodes(buffer2, author);
MC_SendMessage(client, buffer2, author);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags and teamcolor tag.
*
* @param author Author index whose color will be used for teamcolor tag.
* @param message Message (formatting rules).
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock void MC_PrintToChatAllEx(int author, const char[] message, any ...) {
MC_CheckTrie();
if (author <= 0 || author > MaxClients) {
ThrowError("Invalid client index %i", author);
}
if (!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
char buffer[MAX_BUFFER_LENGTH];
char buffer2[MAX_BUFFER_LENGTH];
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || MC_SkipList[i]) {
MC_SkipList[i] = false;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
MC_ReplaceColorCodes(buffer2, author);
MC_SendMessage(i, buffer2, author);
}
}
/**
* Sends a SayText2 usermessage
*
* @param client Client to send usermessage to
* @param message Message to send
*/
stock void MC_SendMessage(int client, const char[] message, int author = 0) {
if (author == 0) {
author = client;
}
char buffer[MC_MAX_MESSAGE_LENGTH];
strcopy(buffer, sizeof(buffer), message);
UserMsg index = GetUserMessageId("SayText2");
if (index == INVALID_MESSAGE_ID) {
if (GetEngineVersion() == Engine_DODS) {
int team = GetClientTeam(author);
if (team == 0) {
ReplaceString(buffer, sizeof(buffer), "\x03", "\x04", false); // Unassigned gets green
}
else {
char temp[16];
Format(temp, sizeof(temp), "\x07%06X", MC_TeamColors[MC_GAME_DODS][team - 1]);
ReplaceString(buffer, sizeof(buffer), "\x03", temp, false);
}
}
PrintToChat(client, "%s", buffer);
return;
}
Handle buf = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
if (GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) {
Protobuf pb = UserMessageToProtobuf(buf);
pb.SetInt("ent_idx", author);
pb.SetBool("chat", true);
pb.SetString("msg_name", buffer);
pb.AddString("params", "");
pb.AddString("params", "");
pb.AddString("params", "");
pb.AddString("params", "");
}
else {
BfWrite bf = UserMessageToBfWrite(buf);
bf.WriteByte(author); // Message author
bf.WriteByte(true); // Chat message
bf.WriteString(buffer); // Message text
}
EndMessage();
}
/**
* This function should only be used right in front of
* MC_PrintToChatAll or MC_PrintToChatAllEx. It causes those functions
* to skip the specified client when printing the message.
* After printing the message, the client will no longer be skipped.
*
* @param client Client index
*/
stock void MC_SkipNextClient(int client) {
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
MC_SkipList[client] = true;
}
/**
* Checks if the colors trie is initialized and initializes it if it's not (used internally)
*
* @return No return
*/
stock void MC_CheckTrie() {
if (MC_Trie == null) {
MC_Trie = MC_InitColorTrie();
}
}
/**
* Replaces color tags in a string with color codes (used internally by MC_PrintToChat, MC_PrintToChatAll, MC_PrintToChatEx, and MC_PrintToChatAllEx
*
* @param buffer String.
* @param author Optional client index to use for {teamcolor} tags, or 0 for none
* @param removeTags Optional boolean value to determine whether we're replacing tags with colors, or just removing tags, used by MC_RemoveTags
* @param maxlen Optional value for max buffer length, used by MC_RemoveTags
*
* On error/Errors: If the client index passed for author is invalid or not in game.
*/
stock void MC_ReplaceColorCodes(char[] buffer, int author = 0, bool removeTags = false, int maxlen = MAX_BUFFER_LENGTH) {
MC_CheckTrie();
if (!removeTags) {
ReplaceString(buffer, maxlen, "{default}", "\x01", false);
}
else {
ReplaceString(buffer, maxlen, "{default}", "", false);
ReplaceString(buffer, maxlen, "{teamcolor}", "", false);
}
if (author != 0 && !removeTags) {
if (author < 0 || author > MaxClients) {
ThrowError("Invalid client index %i", author);
}
if (!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
}
int cursor = 0;
int value;
char tag[32], buff[32];
char[] output = new char[maxlen];
strcopy(output, maxlen, buffer);
// Since the string's size is going to be changing, output will hold the replaced string and we'll search buffer
Regex regex = new Regex("{[#a-zA-Z0-9]+}");
for (int i = 0; i < 1000; i++) { // The RegEx extension is quite flaky, so we have to loop here :/. This loop is supposed to be infinite and broken by return, but conditions have been added to be safe.
if (regex.Match(buffer[cursor]) < 1) {
delete regex;
strcopy(buffer, maxlen, output);
return;
}
regex.GetSubString(0, tag, sizeof(tag));
MC_StrToLower(tag);
cursor = StrContains(buffer[cursor], tag, false) + cursor + 1;
strcopy(buff, sizeof(buff), tag);
ReplaceString(buff, sizeof(buff), "{", "");
ReplaceString(buff, sizeof(buff), "}", "");
if (buff[0] == '#') {
if (strlen(buff) == 7) {
Format(buff, sizeof(buff), "\x07%s", buff[1]);
}
else if (strlen(buff) == 9) {
Format(buff, sizeof(buff), "\x08%s", buff[1]);
}
else {
continue;
}
if (removeTags) {
ReplaceString(output, maxlen, tag, "", false);
}
else {
ReplaceString(output, maxlen, tag, buff, false);
}
}
else if (!MC_Trie.GetValue(buff, value)) {
continue;
}
if (removeTags) {
ReplaceString(output, maxlen, tag, "", false);
}
else {
Format(buff, sizeof(buff), "\x07%06X", value);
ReplaceString(output, maxlen, tag, buff, false);
}
}
LogError("[MORE COLORS] Infinite loop broken.");
}
/**
* Gets a part of a string
*
* @param input String to get the part from
* @param output Buffer to write to
* @param maxlen Max length of output buffer
* @param start Position to start at
* @param numChars Number of characters to return, or 0 for the end of the string
*/
stock void CSubString(const char[] input, char[] output, int maxlen, int start, int numChars = 0) {
int i = 0;
for (;;) {
if (i == maxlen - 1 || i >= numChars || input[start + i] == '\0') {
output[i] = '\0';
return;
}
output[i] = input[start + i];
i++;
}
}
/**
* Converts a string to lowercase
*
* @param buffer String to convert
*/
stock void MC_StrToLower(char[] buffer) {
int len = strlen(buffer);
for (int i = 0; i < len; i++) {
buffer[i] = CharToLower(buffer[i]);
}
}
/**
* Adds a color to the colors trie
*
* @param name Color name, without braces
* @param color Hexadecimal representation of the color (0xRRGGBB)
* @return True if color was added successfully, false if a color already exists with that name
*/
stock bool MC_AddColor(const char[] name, int color) {
MC_CheckTrie();
int value;
if (MC_Trie.GetValue(name, value)) {
return false;
}
char newName[64];
strcopy(newName, sizeof(newName), name);
MC_StrToLower(newName);
MC_Trie.SetValue(newName, color);
return true;
}
/**
* Removes color tags from a message
*
* @param message Message to remove tags from
* @param maxlen Maximum buffer length
*/
stock void MC_RemoveTags(char[] message, int maxlen) {
MC_ReplaceColorCodes(message, 0, true, maxlen);
}
/**
* Replies to a command with colors
*
* @param client Client to reply to
* @param message Message (formatting rules)
*/
stock void MC_ReplyToCommand(int client, const char[] message, any ...) {
char buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 3);
if (client == 0) {
MC_RemoveTags(buffer, sizeof(buffer));
PrintToServer("%s", buffer);
}
if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
MC_RemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
}
else {
MC_PrintToChat(client, "%s", buffer);
}
}
/**
* Replies to a command with colors
*
* @param client Client to reply to
* @param author Client to use for {teamcolor}
* @param message Message (formatting rules)
*/
stock void MC_ReplyToCommandEx(int client, int author, const char[] message, any ...) {
char buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 4);
if (client == 0) {
MC_RemoveTags(buffer, sizeof(buffer));
PrintToServer("%s", buffer);
}
if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
MC_RemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
}
else {
MC_PrintToChatEx(client, author, "%s", 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,
* MC_ShowActivity2() is slightly more useful.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @error
*/
stock int MC_ShowActivity(int client, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char tag[] = "[SM] ";
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE) {
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || (display_in_chat && i == client)) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = id.HasFlag(Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Same as MC_ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing).
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to display with.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @error
*/
stock int MC_ShowActivityEx(int client, const char[] tag, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client)) {
ThrowError("Client index %d is invalid", client);
}
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE) {
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || (display_in_chat && i == client)) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = id.HasFlag(Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root) || (i == client)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* 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 doing the action, or 0 for server.
* @param tags Tag to prepend to the message.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @error
*/
stock int MC_ShowActivity2(int client, const char[] tag, const char[] format, any ...) {
if (sm_show_activity == null) {
sm_show_activity = FindConVar("sm_show_activity");
}
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = sm_show_activity.IntValue;
// ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
if (client != 0) {
if (client < 0 || client > MaxClients || !IsClientConnected(client)) {
ThrowError("Client index %d is invalid", client);
}
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
sign = "PLAYER";
}
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
/* We don't display directly to the console because the chat text
* simply gets added to the console, so we don't want it to print
* twice.
*/
MC_PrintToChatEx(client, client, "%s%s", tag, szBuffer);
}
else {
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value) {
return 1;
}
for (int i = 1; i <= MaxClients; ++i) {
if (!IsClientInGame(i) || IsFakeClient(i) || i == client) {
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID || !id.HasFlag(Admin_Generic, Access_Effective)) {
/* Treat this as a normal user. */
if ((value & 1) | (value & 2)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 2)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else {
/* Treat this as an admin user */
bool is_root = id.HasFlag(Admin_Root, Access_Effective);
if ((value & 4) || (value & 8) || ((value & 16) && is_root)) {
char newsign[MAX_NAME_LENGTH];
if ((value & 8) || ((value & 16) && is_root)) {
newsign = name;
}
else {
newsign = sign;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Determines whether a color name exists
*
* @param color The color name to check
* @return True if the color exists, false otherwise
*/
stock bool CColorExists(const char[] color) {
MC_CheckTrie();
int temp;
return MC_Trie.GetValue(color, temp);
}
/**
* Returns the hexadecimal representation of a client's team color (will NOT initialize the trie)
*
* @param client Client to get the team color for
* @return Client's team color in hexadecimal, or green if unknown
* On error/Errors: If the client index passed is invalid or not in game.
*/
stock int CGetTeamColor(int client) {
if (client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if (!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
int value;
switch(GetClientTeam(client)) {
case 1: {
value = MCOLOR_GRAY;
}
case 2: {
value = MCOLOR_RED;
}
case 3: {
value = MCOLOR_BLUE;
}
default: {
value = MCOLOR_GREEN;
}
}
return value;
}
stock StringMap MC_InitColorTrie() {
StringMap hTrie = new StringMap();
hTrie.SetValue("aliceblue", 0xF0F8FF);
hTrie.SetValue("allies", 0x4D7942); // same as Allies team in DoD:S
hTrie.SetValue("ancient", 0xEB4B4B); // same as Ancient item rarity in Dota 2
hTrie.SetValue("antiquewhite", 0xFAEBD7);
hTrie.SetValue("aqua", 0x00FFFF);
hTrie.SetValue("aquamarine", 0x7FFFD4);
hTrie.SetValue("arcana", 0xADE55C); // same as Arcana item rarity in Dota 2
hTrie.SetValue("axis", 0xFF4040); // same as Axis team in DoD:S
hTrie.SetValue("azure", 0x007FFF);
hTrie.SetValue("beige", 0xF5F5DC);
hTrie.SetValue("bisque", 0xFFE4C4);
hTrie.SetValue("black", 0x000000);
hTrie.SetValue("blanchedalmond", 0xFFEBCD);
hTrie.SetValue("blue", 0x99CCFF); // same as BLU/Counter-Terrorist team color
hTrie.SetValue("blueviolet", 0x8A2BE2);
hTrie.SetValue("brown", 0xA52A2A);
hTrie.SetValue("burlywood", 0xDEB887);
hTrie.SetValue("cadetblue", 0x5F9EA0);
hTrie.SetValue("chartreuse", 0x7FFF00);
hTrie.SetValue("chocolate", 0xD2691E);
hTrie.SetValue("collectors", 0xAA0000); // same as Collector's item quality in TF2
hTrie.SetValue("common", 0xB0C3D9); // same as Common item rarity in Dota 2
hTrie.SetValue("community", 0x70B04A); // same as Community item quality in TF2
hTrie.SetValue("coral", 0xFF7F50);
hTrie.SetValue("cornflowerblue", 0x6495ED);
hTrie.SetValue("cornsilk", 0xFFF8DC);
hTrie.SetValue("corrupted", 0xA32C2E); // same as Corrupted item quality in Dota 2
hTrie.SetValue("crimson", 0xDC143C);
hTrie.SetValue("cyan", 0x00FFFF);
hTrie.SetValue("darkblue", 0x00008B);
hTrie.SetValue("darkcyan", 0x008B8B);
hTrie.SetValue("darkgoldenrod", 0xB8860B);
hTrie.SetValue("darkgray", 0xA9A9A9);
hTrie.SetValue("darkgrey", 0xA9A9A9);
hTrie.SetValue("darkgreen", 0x006400);
hTrie.SetValue("darkkhaki", 0xBDB76B);
hTrie.SetValue("darkmagenta", 0x8B008B);
hTrie.SetValue("darkolivegreen", 0x556B2F);
hTrie.SetValue("darkorange", 0xFF8C00);
hTrie.SetValue("darkorchid", 0x9932CC);
hTrie.SetValue("darkred", 0x8B0000);
hTrie.SetValue("darksalmon", 0xE9967A);
hTrie.SetValue("darkseagreen", 0x8FBC8F);
hTrie.SetValue("darkslateblue", 0x483D8B);
hTrie.SetValue("darkslategray", 0x2F4F4F);
hTrie.SetValue("darkslategrey", 0x2F4F4F);
hTrie.SetValue("darkturquoise", 0x00CED1);
hTrie.SetValue("darkviolet", 0x9400D3);
hTrie.SetValue("deeppink", 0xFF1493);
hTrie.SetValue("deepskyblue", 0x00BFFF);
hTrie.SetValue("dimgray", 0x696969);
hTrie.SetValue("dimgrey", 0x696969);
hTrie.SetValue("dodgerblue", 0x1E90FF);
hTrie.SetValue("exalted", 0xCCCCCD); // same as Exalted item quality in Dota 2
hTrie.SetValue("firebrick", 0xB22222);
hTrie.SetValue("floralwhite", 0xFFFAF0);
hTrie.SetValue("forestgreen", 0x228B22);
hTrie.SetValue("frozen", 0x4983B3); // same as Frozen item quality in Dota 2
hTrie.SetValue("fuchsia", 0xFF00FF);
hTrie.SetValue("fullblue", 0x0000FF);
hTrie.SetValue("fullred", 0xFF0000);
hTrie.SetValue("gainsboro", 0xDCDCDC);
hTrie.SetValue("genuine", 0x4D7455); // same as Genuine item quality in TF2
hTrie.SetValue("ghostwhite", 0xF8F8FF);
hTrie.SetValue("gold", 0xFFD700);
hTrie.SetValue("goldenrod", 0xDAA520);
hTrie.SetValue("gray", 0xCCCCCC); // same as spectator team color
hTrie.SetValue("grey", 0xCCCCCC);
hTrie.SetValue("green", 0x3EFF3E);
hTrie.SetValue("greenyellow", 0xADFF2F);
hTrie.SetValue("haunted", 0x38F3AB); // same as Haunted item quality in TF2
hTrie.SetValue("honeydew", 0xF0FFF0);
hTrie.SetValue("hotpink", 0xFF69B4);
hTrie.SetValue("immortal", 0xE4AE33); // same as Immortal item rarity in Dota 2
hTrie.SetValue("indianred", 0xCD5C5C);
hTrie.SetValue("indigo", 0x4B0082);
hTrie.SetValue("ivory", 0xFFFFF0);
hTrie.SetValue("khaki", 0xF0E68C);
hTrie.SetValue("lavender", 0xE6E6FA);
hTrie.SetValue("lavenderblush", 0xFFF0F5);
hTrie.SetValue("lawngreen", 0x7CFC00);
hTrie.SetValue("legendary", 0xD32CE6); // same as Legendary item rarity in Dota 2
hTrie.SetValue("lemonchiffon", 0xFFFACD);
hTrie.SetValue("lightblue", 0xADD8E6);
hTrie.SetValue("lightcoral", 0xF08080);
hTrie.SetValue("lightcyan", 0xE0FFFF);
hTrie.SetValue("lightgoldenrodyellow", 0xFAFAD2);
hTrie.SetValue("lightgray", 0xD3D3D3);
hTrie.SetValue("lightgrey", 0xD3D3D3);
hTrie.SetValue("lightgreen", 0x99FF99);
hTrie.SetValue("lightpink", 0xFFB6C1);
hTrie.SetValue("lightsalmon", 0xFFA07A);
hTrie.SetValue("lightseagreen", 0x20B2AA);
hTrie.SetValue("lightskyblue", 0x87CEFA);
hTrie.SetValue("lightslategray", 0x778899);
hTrie.SetValue("lightslategrey", 0x778899);
hTrie.SetValue("lightsteelblue", 0xB0C4DE);
hTrie.SetValue("lightyellow", 0xFFFFE0);
hTrie.SetValue("lime", 0x00FF00);
hTrie.SetValue("limegreen", 0x32CD32);
hTrie.SetValue("linen", 0xFAF0E6);
hTrie.SetValue("magenta", 0xFF00FF);
hTrie.SetValue("maroon", 0x800000);
hTrie.SetValue("mediumaquamarine", 0x66CDAA);
hTrie.SetValue("mediumblue", 0x0000CD);
hTrie.SetValue("mediumorchid", 0xBA55D3);
hTrie.SetValue("mediumpurple", 0x9370D8);
hTrie.SetValue("mediumseagreen", 0x3CB371);
hTrie.SetValue("mediumslateblue", 0x7B68EE);
hTrie.SetValue("mediumspringgreen", 0x00FA9A);
hTrie.SetValue("mediumturquoise", 0x48D1CC);
hTrie.SetValue("mediumvioletred", 0xC71585);
hTrie.SetValue("midnightblue", 0x191970);
hTrie.SetValue("mintcream", 0xF5FFFA);
hTrie.SetValue("mistyrose", 0xFFE4E1);
hTrie.SetValue("moccasin", 0xFFE4B5);
hTrie.SetValue("mythical", 0x8847FF); // same as Mythical item rarity in Dota 2
hTrie.SetValue("navajowhite", 0xFFDEAD);
hTrie.SetValue("navy", 0x000080);
hTrie.SetValue("normal", 0xB2B2B2); // same as Normal item quality in TF2
hTrie.SetValue("oldlace", 0xFDF5E6);
hTrie.SetValue("olive", 0x9EC34F);
hTrie.SetValue("olivedrab", 0x6B8E23);
hTrie.SetValue("orange", 0xFFA500);
hTrie.SetValue("orangered", 0xFF4500);
hTrie.SetValue("orchid", 0xDA70D6);
hTrie.SetValue("palegoldenrod", 0xEEE8AA);
hTrie.SetValue("palegreen", 0x98FB98);
hTrie.SetValue("paleturquoise", 0xAFEEEE);
hTrie.SetValue("palevioletred", 0xD87093);
hTrie.SetValue("papayawhip", 0xFFEFD5);
hTrie.SetValue("peachpuff", 0xFFDAB9);
hTrie.SetValue("peru", 0xCD853F);
hTrie.SetValue("pink", 0xFFC0CB);
hTrie.SetValue("plum", 0xDDA0DD);
hTrie.SetValue("powderblue", 0xB0E0E6);
hTrie.SetValue("purple", 0x800080);
hTrie.SetValue("rare", 0x4B69FF); // same as Rare item rarity in Dota 2
hTrie.SetValue("red", 0xFF4040); // same as RED/Terrorist team color
hTrie.SetValue("rosybrown", 0xBC8F8F);
hTrie.SetValue("royalblue", 0x4169E1);
hTrie.SetValue("saddlebrown", 0x8B4513);
hTrie.SetValue("salmon", 0xFA8072);
hTrie.SetValue("sandybrown", 0xF4A460);
hTrie.SetValue("seagreen", 0x2E8B57);
hTrie.SetValue("seashell", 0xFFF5EE);
hTrie.SetValue("selfmade", 0x70B04A); // same as Self-Made item quality in TF2
hTrie.SetValue("sienna", 0xA0522D);
hTrie.SetValue("silver", 0xC0C0C0);
hTrie.SetValue("skyblue", 0x87CEEB);
hTrie.SetValue("slateblue", 0x6A5ACD);
hTrie.SetValue("slategray", 0x708090);
hTrie.SetValue("slategrey", 0x708090);
hTrie.SetValue("snow", 0xFFFAFA);
hTrie.SetValue("springgreen", 0x00FF7F);
hTrie.SetValue("steelblue", 0x4682B4);
hTrie.SetValue("strange", 0xCF6A32); // same as Strange item quality in TF2
hTrie.SetValue("tan", 0xD2B48C);
hTrie.SetValue("teal", 0x008080);
hTrie.SetValue("thistle", 0xD8BFD8);
hTrie.SetValue("tomato", 0xFF6347);
hTrie.SetValue("turquoise", 0x40E0D0);
hTrie.SetValue("uncommon", 0xB0C3D9); // same as Uncommon item rarity in Dota 2
hTrie.SetValue("unique", 0xFFD700); // same as Unique item quality in TF2
hTrie.SetValue("unusual", 0x8650AC); // same as Unusual item quality in TF2
hTrie.SetValue("valve", 0xA50F79); // same as Valve item quality in TF2
hTrie.SetValue("vintage", 0x476291); // same as Vintage item quality in TF2
hTrie.SetValue("violet", 0xEE82EE);
hTrie.SetValue("wheat", 0xF5DEB3);
hTrie.SetValue("white", 0xFFFFFF);
hTrie.SetValue("whitesmoke", 0xF5F5F5);
hTrie.SetValue("yellow", 0xFFFF00);
hTrie.SetValue("yellowgreen", 0x9ACD32);
return hTrie;
}