diff --git a/doc/irc.luadoc b/doc/irc.luadoc index 34b2a4d..432f15d 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'.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 56314bd..b31c098 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)