diff --git a/doc/irc.luadoc b/doc/irc.luadoc index dc10d6e..9f84bc9 100644 --- a/doc/irc.luadoc +++ b/doc/irc.luadoc @@ -155,7 +155,7 @@ function irc:shutdown() --
  • username - User username.
  • --
  • host - User hostname.
  • --
  • realname - User real name.
  • ---
  • access - User access, available in channel-oriented callbacks. A table containing the boolean fields 'op', 'halfop', and 'voice'.
  • +--
  • access - User access, available in channel-oriented callbacks. A table containing boolean fields for each access mode that the server supports. Eg: 'o', and 'v'.
  • -- -- Apart from nick, fields may be missing. To fill them in, enable user tracking and use irc:whois. -- @name User diff --git a/handlers.lua b/handlers.lua index 9f49977..864926d 100644 --- a/handlers.lua +++ b/handlers.lua @@ -109,7 +109,7 @@ handlers["353"] = function(o, user, me, chanType, channel, names) local users = o.channels[channel].users for nick in names:gmatch("(%S+)") do - local access, name = parseNick(nick) + local access, name = parseNick(o, nick) users[name] = {access = access} end end @@ -161,18 +161,17 @@ handlers["MODE"] = function(o, user, target, modes, ...) if o.track_users and target ~= o.nick then local add = true local optList = {...} + updatePrefixModes(o) for c in modes:gmatch(".") do if c == "+" then add = true elseif c == "-" then add = false - elseif c == "o" then - local user = table.remove(optList, 1) - o.channels[target].users[user].access.op = add - elseif c == "h" then - local user = table.remove(optList, 1) - o.channels[target].users[user].access.halfop = add - elseif c == "v" then - local user = table.remove(optList, 1) - o.channels[target].users[user].access.voice = add + elseif o.modeprefix[c] then + local nick = table.remove(optList, 1) + local access = o.channels[target].users[nick].access + access[o.modeprefix[c]] = add + if c == "o" then access.op = add + elseif c == "v" then access.voice = add + end end end end diff --git a/util.lua b/util.lua index 0b22e91..b0d5955 100644 --- a/util.lua +++ b/util.lua @@ -50,29 +50,51 @@ function parse(line) return prefix, cmd, params end -function parseNick(nick) - local access, name = nick:match("^([%+@]*)(.+)$") - return parseAccess(access or ""), name +function parseNick(conn, nick) + local access = {} + updatePrefixModes(conn) + local namestart = 1 + for i = 1, #nick - 1 do + local c = nick:sub(i, i) + if conn.prefixmode[c] then + access[conn.prefixmode[c]] = true + else + namestart = i + break + end + end + access.op = access.o + access.voice = access.v + local name = nick:sub(namestart) + return access, name end function parsePrefix(prefix) local user = {} if prefix then - user.access, user.nick, user.username, user.host = prefix:match("^([%+@]*)(.+)!(.+)@(.+)$") + user.nick, user.username, user.host = prefix:match("^(.+)!(.+)@(.+)$") end - user.access = parseAccess(user.access or "") return user end -function parseAccess(accessString) - local access = {op = false, halfop = false, voice = false} - for c in accessString:gmatch(".") do - if c == "@" then access.op = true - elseif c == "%" then access.halfop = true - elseif c == "+" then access.voice = true - end +function updatePrefixModes(conn) + if conn.prefixmode and conn.modeprefix then + return + end + conn.prefixmode = {} + conn.modeprefix = {} + if conn.supports.PREFIX then + local modes, prefixes = conn.supports.PREFIX:match("%(([^%)]*)%)(.*)") + for i = 1, #modes do + conn.prefixmode[prefixes:sub(i, i)] = modes:sub(i, i) + conn.modeprefix[ modes:sub(i, i)] = prefixes:sub(i, i) + end + else + conn.prefixmode['@'] = 'o' + conn.prefixmode['+'] = 'v' + conn.modeprefix['o'] = '@' + conn.modeprefix['v'] = '+' end - return access end --mIRC markup scheme (de-facto standard)