Small server-side chat filter for Garry's Mod. It blocks configured terms and handles basic chat spam without client files or net messages.
- Checks case changes, punctuation, spaces, stretched letters, and common leetspeak
- Maps a small set of Greek and Cyrillic lookalikes
- Limits message length, speed, and repeated messages
- Supports allowed words and staff exemptions
- Can log rejected messages to the server console
Copy the chatfilter folder to garrysmod/addons/, then restart the server or change level.
chatfilter/
├── addon.json
├── README.md
└── lua/
├── autorun/server/sh_chatfilter.lua
└── chatfilter/config.lua
All settings are in lua/chatfilter/config.lua.
| Setting | What it controls |
|---|---|
bEnabled |
Turns the addon on or off. |
NotifyMessage |
Message shown when a term is blocked. |
bLogBlocked |
Prints rejected messages in the server console. |
ExemptGroups |
Usergroups that skip all checks. |
IsExempt |
Optional custom exemption function. |
BlockedWords |
Terms the filter should catch. |
AllowedWords |
Innocent words that contain a blocked term. |
AntiExploit |
Length, cooldown, and repeat settings. |
Add blocked terms using their normal spelling:
ChatFilterConfig.BlockedWords = {
"blockedterm",
"otherterm",
}The filter allows extra repeated letters but still respects letters that are repeated in the original spelling. Terms must contain 2–64 normalized letters and cannot contain spaces.
Allowed words must match the whole word. They only protect their own occurrence, so a blocked term elsewhere in the same message is still caught.
ChatFilterConfig.AllowedWords = {
"exampleword",
}Group names are compared without case sensitivity:
ChatFilterConfig.ExemptGroups = {
"superadmin",
"admin",
}You can also provide a function:
ChatFilterConfig.IsExempt = function(ply)
return ply:IsAdmin()
endThe function must return true. Errors are caught and do not grant an exemption.
ChatFilterConfig.AntiExploit = {
bEnabled = true,
MaxLength = 200,
MessageCooldown = 0.75,
MaxRepeats = 3,
SpamMessage = "You're sending messages too fast.",
}Only accepted messages update cooldown and repeat state. Capitalization and extra whitespace do not bypass repeat checks. Messages over 4,096 bytes are always rejected.
Set bLogBlocked to true to log rejections. Log values are cleaned, shortened, and kept on one line.
- The lookalike list is intentionally small and will not cover every Unicode character.
- Unsupported non-ASCII characters remain visible but are ignored during term matching.
- Splitting a term across words is checked, although the filter avoids matches buried inside two unrelated words where possible.
- Returning a blocked or cleaned message from
PlayerSaymay stop another chat hook from running. Test this with chat-command addons. - Length limits count bytes, so non-ASCII messages reach the limit sooner.
MIT License. Copyright (c) 2026 Hypercat.