Skip to content

Commit 028e680

Browse files
authored
Merge pull request #1 from DosMike/develop
Improved Color Formatting
2 parents 9994322 + a66af1f commit 028e680

5 files changed

Lines changed: 135 additions & 35 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ As mentioned above, MCP implements compatibility layers for Simple Chat-Processo
3535
I want to emphasise here that I am only implementing API compatibility, not feature pairity! In addition you can switch the transport method from using SayText2 packets to TextMsg packets (system/plugin messages).
3636
Simple Chat-Processor also had the quirk that the Post call was only called if the message was changed. I have an optional fix for that in place, that you can enable in the config as well.
3737
The compatibility options for `Custom-ChatColors` and `HexTags` will try to read the clients chat colors back into MCP for other plugins to access.
38+
In case you still encounter weird issues with external plugins that reliably format chat messages manually or through a compatibility layer, you can turn on the `External Formatting` option and check if things improve.
3839

3940
By Default MCP will also perform input sanitation that brings chat messages back in-line with vanilla behaviour. Native colors are not actually allowed by games by default, neither are empty messages.
4041
The `Trim All Whitespaces` option will catch unicode spaces as well, to properly block messages without content.
@@ -53,6 +54,7 @@ The config can be found at `addons/sourcemod/config/metachatprocessor.cfg`:
5354
"Custom-ChatColors" "1"
5455
"HexTags" "1"
5556
"Fix Post Calls" "0"
57+
"External Formatting" "0"
5658
}
5759
// Transport defines the message channel/type. You should probably keep it at SayText.
5860
// Possible values: [ PrintToChat , SayText ]

scripting/MetaChatProcessor.sp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
#pragma semicolon 1
2525
#pragma newdecls required
2626

27-
#define PLUGIN_VERSION "23w05a"
27+
#define PLUGIN_VERSION "23w29a"
2828

2929
public Plugin myinfo = {
3030
name = "Meta Chat Processor",
31-
author = "reBane, based on SCP Redux, Chat-Processor and Cider",
32-
description = "Process chat and allows other plugins to manipulate chat.",
31+
author = "reBane",
32+
description = "Process chat and allows other plugins to manipulate chat, based on SCP Redux, Chat-Processor and Cider",
3333
version = PLUGIN_VERSION,
3434
url = "https://forums.alliedmods.net/showthread.php?t=337455"
3535
};
@@ -50,12 +50,13 @@ char clientNamePrefix[MAXPLAYERS+1][MCP_MAXLENGTH_NAME];
5050
char clientChatColor[MAXPLAYERS+1][MCP_MAXLENGTH_COLORTAG];
5151

5252
enum mcpCompatibility {
53-
mcpCompatNone = 0,
54-
mcpCompatSCPRedux = (1<<0), // Support for SCP Redux 2.3.0 - https://forums.alliedmods.net/showpost.php?p=2629088&postcount=413
55-
mcpCompatDrixevel = (1<<1), // Support for Drixevel's Chat Processor - https://forums.alliedmods.net/showthread.php?t=286913
56-
mcpCompatCiderCP = (1<<2), // Support for CiderChatProcessor - https://forums.alliedmods.net/showthread.php?p=2646798
57-
mcpCompatCCC = (1<<16), // Support for Custom Chat Colors - https://forums.alliedmods.net/showthread.php?p=1721580
58-
mcpCompatHexTags = (1<<17), // Support for HexTags - https://forums.alliedmods.net/showthread.php?p=2566623
53+
mcpCompatNone = 0,
54+
mcpCompatSCPRedux = (1<<0), // Support for SCP Redux 2.3.0 - https://forums.alliedmods.net/showpost.php?p=2629088&postcount=413
55+
mcpCompatDrixevel = (1<<1), // Support for Drixevel's Chat Processor - https://forums.alliedmods.net/showthread.php?t=286913
56+
mcpCompatCiderCP = (1<<2), // Support for CiderChatProcessor - https://forums.alliedmods.net/showthread.php?p=2646798
57+
mcpCompatCCC = (1<<16), // Support for Custom Chat Colors - https://forums.alliedmods.net/showthread.php?p=1721580
58+
mcpCompatHexTags = (1<<17), // Support for HexTags - https://forums.alliedmods.net/showthread.php?p=2566623
59+
mcpCompatExtFormat = (1<<31), // Support any plugin that consistently applies tags and colors
5960
}
6061
mcpCompatibility g_compatLevel = mcpCompatNone;
6162
enum mcpTransportMethod {
@@ -294,7 +295,7 @@ public Action OnUserMessage_SayText2Proto(UserMsg msg_id, BfRead msg, const int[
294295

295296
public Action OnUserMessage_SayText2BB(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init) {
296297
// collect the message
297-
int tmp=(g_currentMessage.listRecipients == null ? 0 : g_currentMessage.listRecipients.Length);
298+
298299
g_currentMessage.Reset();
299300
g_currentMessage.sender = msg.ReadByte();
300301
if (!g_currentMessage.sender) return Plugin_Continue;
@@ -490,7 +491,8 @@ bool ProcessMessage() {
490491
else if (result == Plugin_Changed) g_currentMessage.changed = true;
491492

492493
//...but default colors are added after, if missing, so i guess i'll just do it here?
493-
g_currentMessage.changed |= ApplyClientChatColors(); //process colors. this applies prefix and colors if not already done
494+
//process colors. this applies prefix and colors if not already done
495+
g_currentMessage.changed |= ApplyClientChatColors();
494496

495497
//processing message hooks (late)
496498
result = Call_OnChatMessage(1); //can still change colors if wanted i guess
@@ -677,7 +679,7 @@ bool ApplyClientChatColors() {
677679
RemoveTextColors(g_currentMessage.message, sizeof(MessageData::message), false);
678680
return true;
679681
}
680-
bool changed = result == Plugin_Changed;
682+
bool changed = result >= Plugin_Changed;
681683

682684
char colTagEnd[MCP_MAXLENGTH_NATIVECOLOR];
683685
//was the name formatted? does the name tag spill color onto the name?
@@ -689,13 +691,14 @@ bool ApplyClientChatColors() {
689691
FormatEx(g_currentMessage.sender_display, sizeof(MessageData::sender_display), "%s\x03%s", namePrefix, g_currentMessage.sender_name);
690692
}
691693
//don't set changed flag here, as that's standard behaviour/colors
692-
} else { //there's custom formatting going on
694+
} else if (!(g_compatLevel & mcpCompatExtFormat)) {
695+
//name and prefix are changed, and we are tasked to format the message
693696
//we only need to concat these two
694697
FormatEx(g_currentMessage.sender_display, sizeof(MessageData::sender_display), "%s%s", namePrefix, displayName);
695698
changed = true;
696699
}
697700
//alright now let's check. normally formats prefix char with the default color, so if we have a color and it's not default, prepend to message
698-
if (chatColor[0] > 1) {//not empty string, not \x01 color
701+
if (chatColor[0] > 1 && !(g_compatLevel & mcpCompatExtFormat)) {//not empty string, not \x01 color
699702
Format(g_currentMessage.message, sizeof(MessageData::message), "%s%s", chatColor, g_currentMessage.message);
700703
changed = true;
701704
}

scripting/MetaChatProcessor/compat_ccc.sp

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111
#include <ccc>
1212
#pragma newdecls required
1313
#define REQUIRE_PLUGIN
14+
#include <clientprefs>
15+
16+
static Cookie cookieTag = null;
17+
static Cookie cookieName = null;
18+
static Cookie cookieChat = null;
19+
20+
void mcp_ccc_init() {
21+
cookieTag = RegClientCookie("ccc_toggle_tag", "Custom Chat Colors Toggle - Tag", CookieAccess_Private);
22+
cookieName = RegClientCookie("ccc_toggle_name_color", "Custom Chat Colors Toggle - Name Color", CookieAccess_Private);
23+
cookieChat = RegClientCookie("ccc_toggle_chat_color", "Custom Chat Colors Toggle - Chat Color", CookieAccess_Private);
24+
}
1425

1526
//this will parse back colors from ccc into mcp
1627
// this allows other plugins to constistently fetch player colors without
@@ -21,25 +32,64 @@
2132
public int CCC_OnUserConfigLoaded(int client) {
2233
if ((g_compatLevel & mcpCompatCCC) == mcpCompatNone) return;
2334

35+
LoadClientColor(client);
36+
}
37+
38+
public Action CCC_OnColor(int client, const char[] message, CCC_ColorType type) {
39+
if ((g_compatLevel & mcpCompatCCC) == mcpCompatNone) return Plugin_Continue;
40+
41+
// because CCC toggle also uses this forward, we will always supress and handle
42+
// colors ourselfs. This means we need to reload this client, condidering
43+
// their CCC-T config, and skip loading stuff accordingly.
44+
LoadClientColor(client);
45+
return Plugin_Handled;
46+
}
47+
48+
static void LoadClientColor(int client) {
2449
char prefixBuffer[128];
25-
//read prefix color
2650
char temp[64];
2751
bool tagHasAlpha;
28-
int tagColor = CCC_GetColor(client, CCC_TagColor, tagHasAlpha);
29-
parseColor(temp, sizeof(temp), tagColor, tagHasAlpha);
30-
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
31-
//read prefix tag
32-
CCC_GetTag(client, temp, sizeof(temp));
33-
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
34-
//read name color
35-
bool nameHasAlpha;
36-
int nameColor = CCC_GetColor(client, CCC_NameColor, nameHasAlpha);
37-
parseColor(temp, sizeof(temp), nameColor, nameHasAlpha);
38-
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
39-
//read chat color
40-
bool chatHasAlpha;
41-
int chatColor = CCC_GetColor(client, CCC_ChatColor, chatHasAlpha);
42-
parseColor(temp, sizeof(temp), chatColor, chatHasAlpha);
52+
53+
bool useClientTag = true;
54+
bool useClientNameColor = true;
55+
bool useClientChatColor = true;
56+
if (cookieTag != null) {
57+
// support for CCC-Toggle
58+
// color should not bleed, there are defaults in CCC
59+
cookieTag.Get(client, temp, sizeof(temp));
60+
useClientTag = StringToInt(temp)==0;
61+
cookieName.Get(client, temp, sizeof(temp));
62+
useClientNameColor = StringToInt(temp)==0;
63+
cookieChat.Get(client, temp, sizeof(temp));
64+
useClientChatColor = StringToInt(temp)==0;
65+
}
66+
67+
if (useClientTag) {
68+
//read prefix color
69+
int tagColor = CCC_GetColor(client, CCC_TagColor, tagHasAlpha);
70+
parseColor(temp, sizeof(temp), tagColor, tagHasAlpha);
71+
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
72+
//read prefix tag
73+
CCC_GetTag(client, temp, sizeof(temp));
74+
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
75+
}
76+
if (useClientNameColor) {
77+
//read name color
78+
bool nameHasAlpha;
79+
int nameColor = CCC_GetColor(client, CCC_NameColor, nameHasAlpha);
80+
parseColor(temp, sizeof(temp), nameColor, nameHasAlpha);
81+
StrCat(prefixBuffer, sizeof(prefixBuffer), temp);
82+
} else {
83+
StrCat(prefixBuffer, sizeof(prefixBuffer), "\x03")
84+
}
85+
if (useClientChatColor) {
86+
//read chat color
87+
bool chatHasAlpha;
88+
int chatColor = CCC_GetColor(client, CCC_ChatColor, chatHasAlpha);
89+
parseColor(temp, sizeof(temp), chatColor, chatHasAlpha);
90+
} else {
91+
temp="\x01";
92+
}
4393
//copy cat
4494
strcopy(clientNamePrefix[client], sizeof(clientNamePrefix[]), prefixBuffer);
4595
strcopy(clientChatColor[client], sizeof(clientChatColor[]), temp);

scripting/MetaChatProcessor/pluginapi.sp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,19 @@ void pluginAPI_init() {
116116
}
117117

118118
public void OnAllPluginsLoaded() {
119-
if (g_compatLevel & mcpCompatSCPRedux)
119+
if (g_compatLevel & mcpCompatSCPRedux) {
120120
mcp_scp_pluginsloaded();
121+
if (IsPluginLoaded("[Source 2013] Custom Chat Colors Toggle Module")) {
122+
mcp_ccc_init();
123+
}
124+
}
121125
if (g_compatLevel & mcpCompatDrixevel)
122126
mcp_drixevel_pluginsloaded();
123127
if (g_compatLevel & mcpCompatCiderCP)
124128
mcp_cider_pluginsloaded();
125129
}
126130

131+
127132
// -------------------- FORWARD WRAPPER --------------------
128133

129134
/**
@@ -157,8 +162,6 @@ static void ValidateAfterCall(const char[] stage, int error, Action& returnedAct
157162
//always strip and process colors
158163
if (returnedAction == Plugin_Changed) {
159164
if ( (g_currentMessage.options & mcpMsgRemoveColors) == mcpMsgRemoveColors ) {
160-
//remove native colors from user input, keeping tags for maybe processing
161-
// changes in display name will be picked up later
162165
RemoveTextColors(g_currentMessage.sender_display, sizeof(MessageData::sender_display), false);
163166
g_currentMessage.changed |= RemoveTextColors(g_currentMessage.message, sizeof(MessageData::message), false);
164167
}

scripting/MetaChatProcessor/utilities.sp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ void LoadCompatConfig() {
7070
if (kv.GetNum("Cider")>0) g_compatLevel |= mcpCompatCiderCP;
7171
if (kv.GetNum("Custom-ChatColors")>0) g_compatLevel |= mcpCompatCCC;
7272
if (kv.GetNum("HexTags")>0) g_compatLevel |= mcpCompatHexTags;
73+
if (kv.GetNum("External Formatting")>0) g_compatLevel |= mcpCompatExtFormat;
7374
g_fixCompatPostCalls = (kv.GetNum("Fix Post Calls")>0);
7475
kv.GoBack();
7576
} else LogError("[MCP] 'Compatibility' section missing from config");
@@ -107,7 +108,7 @@ void LoadCompatConfig() {
107108

108109
static void GenerateDefaultConfig(KeyValues kv, const char[] path) {
109110
kv.ImportFromString("config { "...
110-
"Compatibility { \"SCP Redux\" 1 Drixevel 1 Cider 1 \"Custom-ChatColors\" 0 HexTags 0 \"Fix Post Calls\" 0 } "...
111+
"Compatibility { \"SCP Redux\" 1 Drixevel 1 Cider 1 \"Custom-ChatColors\" 0 HexTags 0 \"Fix Post Calls\" 0 \"External Formatting\" 0 } "...
111112
"Transport SayText HookMode UserMessage "...
112113
"\"Input Sanitizer\" { \"Trim All Whitespaces\" 1 \"Ban On NewLine\" 1 \"Strip Native Colorcodes\" 1 } "...
113114
"}");
@@ -255,4 +256,45 @@ void BuildMessageFormat(mcpSenderFlag senderflags, mcpTargetGroup targetgroup, c
255256
strcopy(buffer[pos], bufferlen-pos, "Spec");
256257
}
257258
}
258-
}
259+
}
260+
261+
/**
262+
* Check if a plugin is loaded by name; expensive check!
263+
* @param name, the name to check, (nameStrict?case sensitive+exact:case insensitive+contains)
264+
* @param nameStrict, if true, the name needs to match exactly, otherwise name value needs to be contained
265+
* @param author, the author to check, optional+case insensitive+(authorStrict?exact:contains)
266+
* @param authorStrict, if false, author name needs to contain string, if true, author string needs to match exact
267+
* @param version, if non-empty, case sensitive+exact requirement; output value for found plugin
268+
* @param versionLength, max buffer size for version
269+
* @return true if the plugin was found
270+
*/
271+
stock bool IsPluginLoaded(const char[] name, bool nameStrict=true, const char[] author=NULL_STRING, bool authorStrict=false, char[] version="", int versionLength=0) {
272+
Handle iter = GetPluginIterator();
273+
char buffer[128];
274+
while (MorePlugins(iter)) {
275+
Handle plugin = ReadPlugin(iter);
276+
GetPluginInfo(plugin, PlInfo_Name, buffer, sizeof(buffer));
277+
if (nameStrict) {
278+
if (!StrEqual(buffer, name, true)) continue;
279+
} else {
280+
if (StrContains(buffer, name, false)==-1) continue;
281+
}
282+
if (!IsNullString(author)) {
283+
GetPluginInfo(plugin, PlInfo_Author, buffer, sizeof(buffer));
284+
if (authorStrict) {
285+
if (!StrEqual(buffer, author, false)) continue;
286+
} else {
287+
if (StrContains(buffer, author, false)==-1) continue;
288+
}
289+
}
290+
if (versionLength>0) {
291+
GetPluginInfo(plugin, PlInfo_Version, buffer, sizeof(buffer));
292+
if (version[0]!=0 && !StrEqual(buffer, version)) break;
293+
strcopy(version, versionLength, buffer);
294+
}
295+
delete iter;
296+
return true;
297+
}
298+
delete iter;
299+
return false;
300+
}

0 commit comments

Comments
 (0)