{"id":19952415,"url":"https://github.com/dosmike/sm-metachatprocessor","last_synced_at":"2026-02-11T01:33:11.829Z","repository":{"id":58508098,"uuid":"474065517","full_name":"DosMike/SM-MetaChatProcessor","owner":"DosMike","description":"Another one","archived":false,"fork":false,"pushed_at":"2025-05-25T18:05:01.000Z","size":207,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-10T22:23:57.858Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"SourcePawn","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DosMike.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-03-25T15:30:35.000Z","updated_at":"2025-07-14T15:31:17.000Z","dependencies_parsed_at":"2023-12-27T11:47:14.645Z","dependency_job_id":"b3c30b83-45b2-4170-9ea0-4923c32dbed6","html_url":"https://github.com/DosMike/SM-MetaChatProcessor","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/DosMike/SM-MetaChatProcessor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DosMike%2FSM-MetaChatProcessor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DosMike%2FSM-MetaChatProcessor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DosMike%2FSM-MetaChatProcessor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DosMike%2FSM-MetaChatProcessor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DosMike","download_url":"https://codeload.github.com/DosMike/SM-MetaChatProcessor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DosMike%2FSM-MetaChatProcessor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29324221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T00:34:26.354Z","status":"ssl_error","status_checked_at":"2026-02-11T00:34:09.494Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T01:12:58.439Z","updated_at":"2026-02-11T01:33:11.804Z","avatar_url":"https://github.com/DosMike.png","language":"SourcePawn","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Meta Chat Processor\n\n**Motivation:** The usual, existing chat-processors did not offer the feature set I required. At the same time I didn't want to drop existing plugins / configs that used previous chat-processors, so I naturally went for the most complex thing I could have done:\nSwitch to private forwards and implement compatibility layers. Until now my other plugin implements a pretty rudimentary implementation of SCP forwards to allow CCC to work, while I change the chat format from AllChat/TeamChat to WorldChat/RegionChat (message 'target group' changes), but I can hopefully do it in a nicer way with MCP soon.\nI want to note that I tested MCP with both Custom-ChatColors and HexTags, both seem to work without any issues.\n\nThis plugin is intended to merge, replace and extend some previous chat processors.\nWith the difference to other chat processors, that I want to keep compatibility for plugins that depend on these chat processors to some degree.\n\nDifferences: Instead of a simple forward, there's 3.5 stacked forwards for pre, early, normal and late manipulation, followed by a 'color', and 'formatted' forward if the message was changed before the post forward.\nThis should offer enough flexibility to implement compatibility for other chat processors and then some.\nSupporting certain chat processors requires basic name tagging capabilities. In MCP this is done through name prefixes, instead of tags. The prefix merges tag color, tag and name color.\nThe message format in MCP is broken down more than usual, allowing for a more refined manipulation, and registration of custom prefixes, e.g. (Region)name : message.\nLastly the message is post processed to remove redundant colors and subsequently save bytes in case two plugins can't agree on where to put colors.\nThe last difference is probably that MCP uses private forwards instead of global forwards, meaning you have to register your functions like e.g. Events or SDKHooks.\n\nIn order to implement some of these features, the available data has to be expanded. This is done with a gamedata file on one side, and translation files on the other.\nThe gamedata file can handle team colors, while the translation file handles things like default colors, team names, ect. Note that games that use (TEAM) as prefix can\nbe forced to use the actual team name and vice versa, thus a translation file per game is required. To keep the localized nature, custom senderflag and group names have\nto be registered with translation phrases, that can then be manipulated numerically.\n\nOn PrintToChat support\nWhile CPrintToChat from the color includes uses SayText2 to send messages, they are marked as non-hookable so only regular PrintToChat messages could be hooked.\nIn addition to that, these messages might already be sent on a per-client basis for translation or otherwise, making parsing very hard!\nInstead of doing the impossible, MCP instead has a native to send SayText2 messages, to basically fake say messages.\n\n## Config \u0026 Setup\n\nAs mentioned above, MCP implements compatibility layers for Simple Chat-Processor, Drixevel's Chat-Processor and Cider Chat-Processor. As I expect most people to not read the docs or just skim over them, all three compat layers are enabled by default.\nI 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).\nSimple 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.\nThe compatibility options for `Custom-ChatColors` and `HexTags` will try to read the clients chat colors back into MCP for other plugins to access.\nIn 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.\n\nBy 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.\nThe `Trim All Whitespaces` option will catch unicode spaces as well, to properly block messages without content.\nLastly there's the option `Ban On NewLine`, this option will automatically perma-ban clients sending new line characters in chat. This should get picked up by SourceBans and other ban management utilities.\nThere is no way (that I know of) for a player to input new line characters into a chat message, and this seems to be only used by hack clients to disrupt chat flow (With the latest TF2 patch this should not longer be possible in that game anyways).\n\nThe config can be found at `addons/sourcemod/config/metachatprocessor.cfg`:\n```c\n\"config\"\n{\n\t\"Compatibility\"\n\t{\n\t\t\"SCP Redux\"\t\t\"1\"\n\t\t\"Drixevel\"\t\t\"1\"\n\t\t\"Cider\"\t\t\t\"1\"\n\t\t\"Custom-ChatColors\"\t\"1\"\n\t\t\"HexTags\"\t\t\"1\"\n\t\t\"Fix Post Calls\"\t\"0\"\n\t\t\"External Formatting\" \"0\"\n\t}\n\t// Transport defines the message channel/type. You should probably keep it at SayText.\n\t// Possible values: [ PrintToChat , SayText ]\n\t\"Transport\"\t\t\"SayText\"\n\t// HookMode defines how messages are cought. Command listener is experimental and might not block the original message correctly in all cases.\n\t// Possible values: [ Command , UserMessage ]\n\t\"HookMode\"\t\t\"UserMessage\"\n\t\"Input Sanitizer\"\n\t{\n\t\t// Trim messages of \"space\" codepoints (utf8 support) ?\n\t\t\"Trim All Whitespaces\"\t\t1\n\t\t// get rid of hackers\n\t\t\"Ban On NewLine\"\t\t\t1\n\t\t// clients are not allowed to use \\x01..\\x08 colors\n\t\t\"Strip Native Colorcodes\"\t1\n\t} \n}\n```\n\n## [Modules](Modules.md)\n\n## Forwards \u0026 Call order\n\n#### mcpHookPre:\n`Action (int\u0026 sender, ArrayList recipients, mcpSenderFlag\u0026 senderflags, mcpTargetGroup\u0026 targetgroup, mcpMessageOption\u0026 options, char[] targetgroupColor)`\n\nCalled before the usual processing for early blocking/management.\n\n#### mcpHookEarly, mcpHookDefault:\n`Action (int\u0026 sender, ArrayList recipients, mcpSenderFlag\u0026 senderflags, mcpTargetGroup\u0026 targetgroup, mcpMessageOption\u0026 options, char[] targetgroupColor, char[] name, char[] message)`\n\nThese are the main forwards, please use mcpHookDefault unless there's a conflict and it would break.\n\n#### mcpHookColors:\n`Action (int sender, mcpSenderFlag senderflags, mcpTargetGroup targetgroup, mcpMessageOption options, char[] nameTag, char[] displayName, char[] chatColor)`\n\nThe dedicated forward for when mcp prefix and colors are applied. the display name might have formats from earlier forwards, nameTag has the tag\u0026color from mcp.\n\n#### mcpHookLate:\n`Action (int\u0026 sender, ArrayList recipients, mcpSenderFlag\u0026 senderflags, mcpTargetGroup\u0026 targetgroup, mcpMessageOption\u0026 options, char[] targetgroupColor, char[] name, char[] message)`\n\nSame signature as as mcpHookEarly and mcpHookDefault, but already catches the default coloring applied by MCP or other most other plugins.\n\n#### mcpHookGroupName:\n`Action (int sender, int recipient, mcpSenderFlag senderflags, mcpTargetGroup targetgroup, const char[] groupphrase, char[] groupname)`\n\nThis is intended for complex target group names that eventually contains placeholders withing their target group.\nAn example could be SourceMods DM format that would resolve to `(To %N)`, that would require this hook to `Format` that username in.\n\n#### mcpHookFormatted:\n`Action (int sender, int recipient, mcpSenderFlag senderflags, mcpTargetGroup targetgroup, mcpMessageOption options, char[] formatted)`\n\nCalled after the client specific format translations are applied and the message is about to be sent to a client.\n\n#### mcpHookPost:\n`void (int sender, ArrayList recipients, mcpSenderFlag senderflags, mcpTargetGroup targetgroup, mcpMessageOption options, const char[] targetgroupColor, const char[] name, const char[] message)`\n\nThe message is sent and you may do some post sending cleanup.\n\n## Other natives\n\n#### Manage Senderflags:\nWith `MCP_RegisterSenderFlag` and `MCP_UnregisterSenderFlags` you can register custom sender flags.\nThis is done by translation phrase and will return a flag bit. Since theres 32 bits in a cell, there's a global limit of 32 senderflag. These will be concatinated within asterisks in front of a chat message (default flags are `*DEAD*` and `*SPEC*`).\n\n#### Manage Targetgroup:\nUsing `MCP_RegisterTargetGroup` and `MCP_UnregisterTargetGroups` you can add custom message target group names.\nAgain, these use translation phrases but as only one target group can be used at a time, there can be almost any amount of target groups. Target groups are formatted between sender flags and username (default groups are `(TEAM)` or `(Spectator)`).\nThrough the modular translation system you can exchange the `(TEAM)` prefix for named team prefixes like `(Terrorists)` or `(Survivors)` and vice versa.\nThese groups are put into the enum in sequence, so checking for a team message can be done with this condition: `(mcpTargetTeam1 \u003c= targetgroup \u003c= mcpTargetTeamSender)`.\n\n#### Name Prefixes and Chat Colors\nYes, MetaChatProcessor has natives to set the name prefix and chat color. I added it, as Drixevel's Chat-Processor has a whole tag system and it felt kinda wrong to have that in the compat layer but nothing comparable in Meta Chat-Processor itself.\nThe name prefix combines tag color, tag string and name color as it's usually really only one value. The chat color is more strongly enforced to be a color instead of a chat prefix. The values are not stored and reset on connect.\n\n#### Manually Sending messages:\nYou can bypass the SayText2 hook by calling `MCP_SendChat` directly. This allows you to easily create messages outside the normal format specifications.\n\n#### Escaping colors:\nIf you want to apply colors by color tags, as we are pretty much used to now, you might run into troubles when a client inputs curly braces / color codes in the input.\nTo prevent those from parsing, you can use `MCP_EscapeCurlies` and `MCP_UnecapeCurlies` which uses `MCP_PUA_ESCAPED_LCURLY` (\\uEC01) as temporary replacement.\nThis character is from the private use block and should neither break anything nor render in the client. Since I can not predict how plugins will use curlies I cannot default replace them, in neither input nor color tags.\n\n#### Manipulating recipients:\nIn order to help you manage the recipients list, there the `MCP_FindClients*` group of methods as well as `MCP_RemoveListElements`.\nYou should not worry about duplicate entries in the recipients list, that is already handled by MCP after each forward is called.\n\n## About buffers:\nThe message buffers in MCP are a bit bigger then previously. This is mostly to give color tags some additional space as they might collapse to no more than 7 bytes when parsed.\nPlease keep in mind that the maximum length for these network packages is around 256 bytes so you should not exceed `MCP_MAXLENGTH_MESSAGE`.\n\n## Compatibility:\nOut of the box MCP should work with Custom-ChatColors and HexTags, replacing SCP Redux, DCP and CCP. Keep in mind that MCP only provides API compatibility. This means features like All-Talk or Dead-Talk are not included in MCP itself.\nThe Colortags from Custom-ChatColors and HexTags are pulled into MCPs prefix system, so other plugins can read and work with them, but are NOT pushed back into Custom-ChatColors or HexTags if set through MCP.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdosmike%2Fsm-metachatprocessor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdosmike%2Fsm-metachatprocessor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdosmike%2Fsm-metachatprocessor/lists"}