From d443e2eeeb85521c6a80c9bac318125d422b0ba3 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 25 Jun 2013 18:17:52 -0400 Subject: [PATCH] Track user access changing and enable multi-prefix This also changes the format of user.access. --- doc/irc.luadoc | 2 +- handlers.lua | 21 ++++++++++++++++++++- init.lua | 4 +++- util.lua | 17 +++++++++++++++-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/doc/irc.luadoc b/doc/irc.luadoc index 18fd3b6..c8c5d8e 100644 --- a/doc/irc.luadoc +++ b/doc/irc.luadoc @@ -154,7 +154,7 @@ function irc:shutdown() --
  • username - User username.
  • --
  • host - User hostname.
  • --
  • realname - User real name.
  • ---
  • access - User access, available in channel-oriented callbacks. Can be '+', '@', and others, depending on the server.
  • +--
  • access - User access, available in channel-oriented callbacks. A table containing the boolean fields 'op', 'halfop', and 'voice'.
  • -- -- 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 74ace38..6b892f9 100644 --- a/handlers.lua +++ b/handlers.lua @@ -1,6 +1,7 @@ local pairs = pairs local error = error local tonumber = tonumber +local table = table module "irc" @@ -83,7 +84,7 @@ handlers["353"] = function(o, prefix, me, chanType, channel, names) local users = o.channels[channel].users for nick in names:gmatch("(%S+)") do local access, name = parseNick(nick) - users[name] = {type = access} + users[name] = {access = access} end end end @@ -131,6 +132,24 @@ handlers["324"] = function(o, prefix, user, channel, modes) end handlers["MODE"] = function(o, prefix, target, modes, ...) + if o.track_users and target ~= o.nick then + local add = true + local optList = {...} + 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 + end + end + end o:invoke("OnModeChange", parsePrefix(prefix), target, modes, ...) end diff --git a/init.lua b/init.lua index 4f0f0da..e94aa24 100644 --- a/init.lua +++ b/init.lua @@ -116,7 +116,9 @@ function meta_preconnect:connect(_host, _port) self.socket = s setmetatable(self, meta) - + + self:send("CAP REQ multi-prefix") + self:invoke("PreRegister", self) self:send("CAP END") diff --git a/util.lua b/util.lua index 91b9ad4..232ffd6 100644 --- a/util.lua +++ b/util.lua @@ -48,17 +48,30 @@ function parse(line) end function parseNick(nick) - return nick:match("^([%+@]?)(.+)$") + local access, name = nick:match("^([%+@]*)(.+)$") + return parseAccess(access or ""), name end function parsePrefix(prefix) local user = {} if prefix then - user.access, user.nick, user.username, user.host = prefix:match("^([%+@]?)(.+)!(.+)@(.+)$") + user.access, 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 + end + return access +end + --mIRC markup scheme (de-facto standard) color = { black = 1,