LuaIRC/util.lua

161 lines
3.5 KiB
Lua

local setmetatable = setmetatable
local sub = string.sub
local byte = string.byte
local char = string.char
local table = table
local assert = assert
local tostring = tostring
local type = type
local random = math.random
module "irc"
-- Protocol parsing
function parse(line)
local msg = Message()
if line:sub(1, 1) == ":" then
local space = line:find(" ")
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 = {}
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 = {}
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
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
end
--mIRC markup scheme (de-facto standard)
color = {
black = 1,
blue = 2,
green = 3,
red = 4,
lightred = 5,
purple = 6,
brown = 7,
yellow = 8,
lightgreen = 9,
navy = 10,
cyan = 11,
lightblue = 12,
violet = 13,
gray = 14,
lightgray = 15,
white = 16
}
local colByte = char(3)
setmetatable(color, {__call = function(_, text, colornum)
colornum = type(colornum) == "string" and assert(color[colornum], "Invalid color '"..colornum.."'") or colornum
return table.concat{colByte, tostring(colornum), text, colByte}
end})
local boldByte = char(2)
function bold(text)
return boldByte..text..boldByte
end
local underlineByte = char(31)
function underline(text)
return underlineByte..text..underlineByte
end
function checkNick(nick)
return nick:find("^[a-zA-Z_%-%[|%]%^{|}`][a-zA-Z0-9_%-%[|%]%^{|}`]*$") ~= nil
end
function defaultNickGenerator(nick)
-- LuaBot -> LuaCot -> LuaCou -> ...
-- We change a random character rather than appending to the
-- nickname as otherwise the new nick could exceed the ircd's
-- maximum nickname length.
local randindex = random(1, #nick)
local randchar = sub(nick, randindex, randindex)
local b = byte(randchar)
b = b + 1
if b < 65 or b > 125 then
b = 65
end
-- Get the halves before and after the changed character
local first = sub(nick, 1, randindex - 1)
local last = sub(nick, randindex + 1, #nick)
nick = first..char(b)..last -- Insert the new charachter
return nick
end
function capitalize(text)
-- Converts first character to upercase and the rest to lowercase.
-- "PING" -> "Ping" | "hello" -> "Hello" | "123" -> "123"
return text:sub(1, 1):upper()..text:sub(2):lower()
end
function split(str, sep)
local t = {}
for s in str:gmatch("%S+") do
table.insert(t, s)
end
return t
end