-- -- censor.lua: black out certain users' messages -- -- Copyright (c) 2016, Přemysl Janouch -- -- Permission to use, copy, modify, and/or distribute this software for any -- purpose with or without fee is hereby granted. -- -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION -- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- local to_pattern = function (mask) if not mask:match ("!") then mask = mask .. "!*" end if not mask:match ("@") then mask = mask .. "@*" end -- That is, * acts like a wildcard, otherwise everything is escaped return "^" .. mask:gsub ("[%^%$%(%)%%%.%[%]%+%-%?]", "%%%0") :gsub ("%*", ".*") .. "$" end local patterns = {} local read_masks = function (v) patterns = {} local add = function (who, where) local channels = patterns[who] or {} table.insert (channels, where) patterns[who] = channels end for item in v:lower ():gmatch ("[^,]+") do local who, where = item:match ("^([^/]+)/*(.*)") if who then add (to_pattern (who), where == "" or where) end end end degesch.setup_config { masks = { type = "string_array", default = "\"\"", comment = "user masks (optionally \"/#channel\") to censor", on_change = read_masks }, } local censor = function (line) -- Taking a shortcut to avoid lengthy message reassembly local start, text = line:match ("^(.- PRIVMSG .-:)(.*)$") local ctcp, rest = text:match ("^(\x01%g+ )(.*)") text = ctcp and ctcp .. "\x0301,01" .. rest or "\x0301,01" .. text return start .. text end degesch.hook_irc (function (hook, server, line) local msg = degesch.parse (line) if msg.command ~= "PRIVMSG" then return line end local channel = msg.params[1]:lower () for who, where in pairs (patterns) do if msg.prefix:lower ():match (who) then for _, x in pairs (where) do if x == true or x == channel then return censor (line) end end end end return line end)