mirror of
https://github.com/ShadowNinja/LuaIRC.git
synced 2024-11-05 01:50:27 +01:00
Add support for tag escapes
This commit is contained in:
parent
81d28bf4dc
commit
c27e2ec7e9
7
init.lua
7
init.lua
|
@ -178,7 +178,9 @@ function meta:think()
|
|||
local line = getline(self, 3)
|
||||
if line and #line > 0 then
|
||||
if not self:invoke("OnRaw", line) then
|
||||
self:handle(parse(line))
|
||||
local msg = Message()
|
||||
msg:fromRFC1459(line)
|
||||
self:handle(msg)
|
||||
end
|
||||
else
|
||||
break
|
||||
|
@ -227,7 +229,8 @@ function meta:whois(nick)
|
|||
while true do
|
||||
local line = getline(self, 3)
|
||||
if line then
|
||||
local msg = parse(line)
|
||||
local msg = Message()
|
||||
msg:fromRFC1249(line)
|
||||
|
||||
local handler = whoisHandlers[msg.command]
|
||||
if handler then
|
||||
|
|
73
messages.lua
73
messages.lua
|
@ -2,6 +2,7 @@ local assert = assert
|
|||
local setmetatable = setmetatable
|
||||
local unpack = unpack
|
||||
local pairs = pairs
|
||||
local insert = table.insert
|
||||
|
||||
module "irc"
|
||||
|
||||
|
@ -17,6 +18,18 @@ function Message(cmd, args)
|
|||
}, msg_meta)
|
||||
end
|
||||
|
||||
local tag_escapes = {
|
||||
[";"] = "\\:",
|
||||
[" "] = "\\s",
|
||||
["\0"] = "\\0",
|
||||
["\\"] = "\\\\",
|
||||
["\r"] = "\\r",
|
||||
["\n"] = "\\n",
|
||||
}
|
||||
|
||||
local tag_unescapes = {}
|
||||
for x, y in pairs(tag_escapes) do tag_unescapes[y] = x end
|
||||
|
||||
function msg_meta:toRFC1459()
|
||||
s = ""
|
||||
|
||||
|
@ -25,10 +38,7 @@ function msg_meta:toRFC1459()
|
|||
for key, value in pairs(self.tags) do
|
||||
s = s..key
|
||||
if value ~= true then
|
||||
assert(not value:find("[%z\07\r\n; ]"),
|
||||
"NUL, BELL, CR, LF, semicolon, and"
|
||||
.." space are not allowed in RFC1459"
|
||||
.." formated tag values.")
|
||||
value = value:gsub("[; %z\\\r\n]", tag_escapes)
|
||||
s = s.."="..value
|
||||
end
|
||||
s = s..";"
|
||||
|
@ -59,6 +69,55 @@ function msg_meta:toRFC1459()
|
|||
return s
|
||||
end
|
||||
|
||||
local function parsePrefix(prefix)
|
||||
local user = {}
|
||||
user.nick, user.username, user.host = prefix:match("^(.+)!(.+)@(.+)$")
|
||||
if not user.nick and prefix:find(".", 1, true) then
|
||||
user.server = prefix
|
||||
end
|
||||
return user
|
||||
end
|
||||
|
||||
function msg_meta:fromRFC1459(line)
|
||||
-- IRCv3 tags
|
||||
if line:sub(1, 1) == "@" then
|
||||
self.tags = {}
|
||||
local space = line:find(" ", 1, true)
|
||||
-- For each semicolon-delimited section from after
|
||||
-- the @ character to before the space character.
|
||||
for tag in line:sub(2, space - 1):gmatch("([^;]+)") do
|
||||
local eq = tag:find("=", 1, true)
|
||||
if eq then
|
||||
self.tags[tag:sub(1, eq - 1)] =
|
||||
tag:sub(eq + 1):gsub("\\([:s0\\rn])", tag_unescapes)
|
||||
else
|
||||
self.tags[tag] = true
|
||||
end
|
||||
end
|
||||
line = line:sub(space + 1)
|
||||
end
|
||||
|
||||
if line:sub(1, 1) == ":" then
|
||||
local space = line:find(" ", 1, true)
|
||||
self.prefix = line:sub(2, space - 1)
|
||||
self.user = parsePrefix(self.prefix)
|
||||
line = line:sub(space + 1)
|
||||
end
|
||||
|
||||
local pos
|
||||
self.command, pos = line:match("(%S+)()")
|
||||
line = line:sub(pos)
|
||||
|
||||
for pos, param in line:gmatch("()(%S+)") do
|
||||
if param:sub(1, 1) == ":" then
|
||||
param = line:sub(pos + 1)
|
||||
insert(self.args, param)
|
||||
break
|
||||
end
|
||||
insert(self.args, param)
|
||||
end
|
||||
end
|
||||
|
||||
function msgs.privmsg(to, text)
|
||||
return Message("PRIVMSG", {to, text})
|
||||
end
|
||||
|
@ -135,9 +194,9 @@ end
|
|||
function msgs.mode(target, modes)
|
||||
-- We have to split the modes parameter because the mode string and
|
||||
-- each parameter are seperate arguments (The first command is incorrect)
|
||||
-- MODE :+ov Nick1 Nick2
|
||||
-- MODE +ov Nick1 Nick2
|
||||
mt = split(modes)
|
||||
-- MODE foo :+ov Nick1 Nick2
|
||||
-- MODE foo +ov Nick1 Nick2
|
||||
local mt = split(modes)
|
||||
return Message("MODE", {target, unpack(mt)})
|
||||
end
|
||||
|
||||
|
|
52
util.lua
52
util.lua
|
@ -10,49 +10,6 @@ local random = math.random
|
|||
|
||||
module "irc"
|
||||
|
||||
-- Protocol parsing
|
||||
function parse(line)
|
||||
local msg = Message()
|
||||
|
||||
-- IRCv3 tags
|
||||
if line:sub(1, 1) == "@" then
|
||||
msg.tags = {}
|
||||
local space = line:find(" ", 1, true)
|
||||
-- For each semicolon-delimited section from after
|
||||
-- the @ character to before the space character.
|
||||
for tag in line:sub(2, space - 1):gmatch("([^;]+)") do
|
||||
local eq = tag:find("=", 1, true)
|
||||
if eq then
|
||||
msg.tags[tag:sub(1, eq - 1)] = tag:sub(eq + 1)
|
||||
else
|
||||
msg.tags[tag] = true
|
||||
end
|
||||
end
|
||||
line = line:sub(space + 1)
|
||||
end
|
||||
|
||||
if line:sub(1, 1) == ":" then
|
||||
local space = line:find(" ", 1, true)
|
||||
msg.prefix = line:sub(2, space - 1)
|
||||
msg.user = parsePrefix(msg.prefix)
|
||||
line = line:sub(space + 1)
|
||||
end
|
||||
|
||||
local pos
|
||||
msg.command, pos = line:match("(%S+)()")
|
||||
line = line:sub(pos)
|
||||
|
||||
for pos, param in line:gmatch("()(%S+)") do
|
||||
if param:sub(1, 1) == ":" then
|
||||
param = line:sub(pos + 1)
|
||||
table.insert(msg.args, param)
|
||||
break
|
||||
end
|
||||
table.insert(msg.args, param)
|
||||
end
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
function parseNick(conn, nick)
|
||||
local access = {}
|
||||
|
@ -73,15 +30,6 @@ function parseNick(conn, nick)
|
|||
return access, name
|
||||
end
|
||||
|
||||
function parsePrefix(prefix)
|
||||
local user = {}
|
||||
user.nick, user.username, user.host = prefix:match("^(.+)!(.+)@(.+)$")
|
||||
if not user.nick and prefix:find(".", 1, true) then
|
||||
user.server = prefix
|
||||
end
|
||||
return user
|
||||
end
|
||||
|
||||
function updatePrefixModes(conn)
|
||||
if conn.prefixmode and conn.modeprefix then
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue
Block a user