mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2024-12-25 02:00:37 +01:00
Updated IRC mod
- Updated IRC mod using last versions of IRC library and functions, contains tweak and increase performances
This commit is contained in:
parent
e8e073ec78
commit
1a14e9ab91
@ -18,8 +18,7 @@ if not jit and package.config:sub(1, 1) == "/" then
|
|||||||
";/usr/share/lua/5.1/?.lua"..
|
";/usr/share/lua/5.1/?.lua"..
|
||||||
";/usr/share/lua/5.1/?/init.lua"
|
";/usr/share/lua/5.1/?/init.lua"
|
||||||
package.cpath = package.cpath..
|
package.cpath = package.cpath..
|
||||||
-- ";/usr/lib/lua/5.1/?.so"
|
";/usr/lib/lua/5.1/?.so"
|
||||||
";/usr/lib/x86_64-linux-gnu/lua/5.1/?.so"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
irc = {
|
irc = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
--- LuaIRC is a low-level IRC library for Lua.
|
--- LuaIRC is a low-level IRC library for Lua.
|
||||||
-- All functions raise Lua exceptions on error.
|
-- All functions raise Lua exceptions on error.
|
||||||
--
|
--
|
||||||
-- Use <code>new</code> to create a new IRC object.<br/>
|
-- Use <code>new</code> to create a new Connection object.<br/>
|
||||||
-- Example:<br/><br/>
|
-- Example:<br/><br/>
|
||||||
--<code>
|
--<code>
|
||||||
--require "irc"<br/>
|
--require "irc"<br/>
|
||||||
@ -24,11 +24,12 @@
|
|||||||
|
|
||||||
module "irc"
|
module "irc"
|
||||||
|
|
||||||
--- Create a new IRC object. Use <code>irc:connect</code> to connect to a server.
|
--- Create a new Connection object. Use <code>irc:connect</code> to connect to a server.
|
||||||
-- @param user Table with fields <code>nick</code>, <code>username</code> and <code>realname</code>.
|
-- @param user Table with fields <code>nick</code>, <code>username</code> and <code>realname</code>.
|
||||||
-- The <code>nick</code> field is required.
|
-- The <code>nick</code> field is required.
|
||||||
--
|
--
|
||||||
-- @return Returns a new <code>irc</code> object.
|
-- @return Returns a new Connection object.
|
||||||
|
-- @see Connection
|
||||||
function new(user)
|
function new(user)
|
||||||
|
|
||||||
--- Hook a function to an event.
|
--- Hook a function to an event.
|
||||||
@ -49,7 +50,7 @@ function irc:unhook(name, id)
|
|||||||
function irc:connect(server, port)
|
function irc:connect(server, port)
|
||||||
|
|
||||||
-- @param table Table of connection details
|
-- @param table Table of connection details
|
||||||
-- @see Connection
|
-- @see ConnectOptions
|
||||||
function irc:connect(table)
|
function irc:connect(table)
|
||||||
|
|
||||||
--- Disconnect <code>irc</code> from the server.
|
--- Disconnect <code>irc</code> from the server.
|
||||||
@ -116,16 +117,26 @@ function irc:handle(msg)
|
|||||||
function irc:shutdown()
|
function irc:shutdown()
|
||||||
|
|
||||||
--- Table with connection information.
|
--- Table with connection information.
|
||||||
-- <ul>
|
-- @name ConnectOptions
|
||||||
-- <li><code>host</code> - Server host name.</li>
|
-- @class table
|
||||||
-- <li><code>port</code> - Server port. [defaults to <code>6667</code>]</li>
|
-- @field host Server host name.
|
||||||
-- <li><code>timeout</code> - Connect timeout. [defaults to <code>30</code>]</li>
|
-- @field port Server port. [defaults to <code>6667</code>]
|
||||||
-- <li><code>password</code> - Server password.</li>
|
-- @field timeout Connect timeout. [defaults to <code>30</code>]
|
||||||
-- <li><code>secure</code> - Boolean to enable TLS connection, pass a params table (described, [luasec]) to control</li>
|
-- @field password Server password.
|
||||||
-- </ul>
|
-- @field secure Boolean to enable TLS connection, pass a params table (described, [luasec]) to control
|
||||||
-- [luasec]: http://www.inf.puc-rio.br/~brunoos/luasec/reference.html
|
-- [luasec]: http://www.inf.puc-rio.br/~brunoos/luasec/reference.html
|
||||||
|
|
||||||
|
--- Class representing a connection.
|
||||||
-- @name Connection
|
-- @name Connection
|
||||||
-- @class table
|
-- @class table
|
||||||
|
-- @field authed Boolean indicating whether the connection has completed registration.
|
||||||
|
-- @field connected Whether the connection is currently connected.
|
||||||
|
-- @field motd The server's message of the day. Can be nil.
|
||||||
|
-- @field nick The current nickname.
|
||||||
|
-- @field realname The real name sent to the server.
|
||||||
|
-- @field username The username/ident sent to the server.
|
||||||
|
-- @field socket Raw socket used by the library.
|
||||||
|
-- @field supports What the server claims to support in it's ISUPPORT message.
|
||||||
|
|
||||||
--- Class representing an IRC message.
|
--- Class representing an IRC message.
|
||||||
-- @name Message
|
-- @name Message
|
||||||
@ -145,8 +156,8 @@ function irc:shutdown()
|
|||||||
--- List of hooks you can use with irc:hook.
|
--- List of hooks you can use with irc:hook.
|
||||||
-- The parameter list describes the parameters passed to the callback function.
|
-- The parameter list describes the parameters passed to the callback function.
|
||||||
-- <ul>
|
-- <ul>
|
||||||
-- <li><code>PreRegister(connection)</code>Useful for CAP commands and SASL.</li>
|
-- <li><code>PreRegister()</code> - Usefull for requesting capabilities.</li>
|
||||||
-- <li><code>OnRaw(line) - (any non false/nil return value assumes line handled and will not be further processed)</code></li>
|
-- <li><code>OnRaw(line)</code> - Any non false/nil return value assumes line handled and will not be further processed.</li>
|
||||||
-- <li><code>OnSend(line)</code></li>
|
-- <li><code>OnSend(line)</code></li>
|
||||||
-- <li><code>OnDisconnect(message, errorOccurred)</code></li>
|
-- <li><code>OnDisconnect(message, errorOccurred)</code></li>
|
||||||
-- <li><code>OnChat(user, channel, message)</code></li>
|
-- <li><code>OnChat(user, channel, message)</code></li>
|
||||||
@ -162,7 +173,10 @@ function irc:shutdown()
|
|||||||
-- <li><code>OnUserMode(modes)</code></li>
|
-- <li><code>OnUserMode(modes)</code></li>
|
||||||
-- <li><code>OnChannelMode(user, channel, modes)</code></li>
|
-- <li><code>OnChannelMode(user, channel, modes)</code></li>
|
||||||
-- <li><code>OnModeChange(user, target, modes, ...)</code>* ('...' contains mode options such as banmasks)</li>
|
-- <li><code>OnModeChange(user, target, modes, ...)</code>* ('...' contains mode options such as banmasks)</li>
|
||||||
-- <li><code>DoX(msg)</code>'X' is any IRC command or numeric with the first letter capitalized (eg, DoPing and Do001)</li>
|
-- <li><code>OnCapabilityList(caps)</code></li>
|
||||||
|
-- <li><code>OnCapabilityAvailable(cap, value)</code> Called only when a capability becomes available or changes.</li>
|
||||||
|
-- <li><code>OnCapabilitySet(cap, enabled)</code>*</li>
|
||||||
|
-- <li><code>DoX(msg)</code>* - 'X' is any IRC command or numeric with the first letter capitalized (eg, DoPing and Do001)</li>
|
||||||
-- </ul>
|
-- </ul>
|
||||||
-- * Event also invoked for yourself.
|
-- * Event also invoked for yourself.
|
||||||
-- † Channel passed only when user tracking is enabled
|
-- † Channel passed only when user tracking is enabled
|
||||||
|
@ -7,6 +7,67 @@ handlers["PING"] = function(conn, msg)
|
|||||||
conn:send(irc.Message({command="PONG", args=msg.args}))
|
conn:send(irc.Message({command="PONG", args=msg.args}))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function requestWanted(conn, wanted)
|
||||||
|
local args = {}
|
||||||
|
for cap, value in pairs(wanted) do
|
||||||
|
if type(value) == "string" then
|
||||||
|
cap = cap .. "=" .. value
|
||||||
|
end
|
||||||
|
if not conn.capabilities[cap] then
|
||||||
|
table.insert(args, cap)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
conn:queue(irc.Message({
|
||||||
|
command = "CAP",
|
||||||
|
args = {"REQ", table.concat(args, " ")}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
handlers["CAP"] = function(conn, msg)
|
||||||
|
local cmd = msg.args[2]
|
||||||
|
if not cmd then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if cmd == "LS" then
|
||||||
|
local list = msg.args[3]
|
||||||
|
local last = false
|
||||||
|
if list == "*" then
|
||||||
|
list = msg.args[4]
|
||||||
|
else
|
||||||
|
last = true
|
||||||
|
end
|
||||||
|
local avail = conn.availableCapabilities
|
||||||
|
local wanted = conn.wantedCapabilities
|
||||||
|
for item in list:gmatch("(%S+)") do
|
||||||
|
local eq = item:find("=", 1, true)
|
||||||
|
local k, v
|
||||||
|
if eq then
|
||||||
|
k, v = item:sub(1, eq - 1), item:sub(eq + 1)
|
||||||
|
else
|
||||||
|
k, v = item, true
|
||||||
|
end
|
||||||
|
if not avail[k] or avail[k] ~= v then
|
||||||
|
wanted[k] = conn:invoke("OnCapabilityAvailable", k, v)
|
||||||
|
end
|
||||||
|
avail[k] = v
|
||||||
|
end
|
||||||
|
if last then
|
||||||
|
if next(wanted) then
|
||||||
|
requestWanted(conn, wanted)
|
||||||
|
end
|
||||||
|
conn:invoke("OnCapabilityList", conn.availableCapabilities)
|
||||||
|
end
|
||||||
|
elseif cmd == "ACK" then
|
||||||
|
for item in msg.args[3]:gmatch("(%S+)") do
|
||||||
|
local enabled = (item:sub(1, 1) ~= "-")
|
||||||
|
local name = enabled and item or item:sub(2)
|
||||||
|
conn:invoke("OnCapabilitySet", name, enabled)
|
||||||
|
conn.capabilities[name] = enabled
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
handlers["001"] = function(conn, msg)
|
handlers["001"] = function(conn, msg)
|
||||||
conn.authed = true
|
conn.authed = true
|
||||||
conn.nick = msg.args[1]
|
conn.nick = msg.args[1]
|
||||||
@ -16,7 +77,6 @@ handlers["PRIVMSG"] = function(conn, msg)
|
|||||||
conn:invoke("OnChat", msg.user, msg.args[1], msg.args[2])
|
conn:invoke("OnChat", msg.user, msg.args[1], msg.args[2])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
handlers["NOTICE"] = function(conn, msg)
|
handlers["NOTICE"] = function(conn, msg)
|
||||||
conn:invoke("OnNotice", msg.user, msg.args[1], msg.args[2])
|
conn:invoke("OnNotice", msg.user, msg.args[1], msg.args[2])
|
||||||
end
|
end
|
||||||
@ -71,13 +131,13 @@ handlers["NICK"] = function(conn, msg)
|
|||||||
conn:invoke("NickChange", msg.user, newNick)
|
conn:invoke("NickChange", msg.user, newNick)
|
||||||
end
|
end
|
||||||
if msg.user.nick == conn.nick then
|
if msg.user.nick == conn.nick then
|
||||||
conn.nick = newnick
|
conn.nick = newNick
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function needNewNick(conn, msg)
|
local function needNewNick(conn, msg)
|
||||||
local newnick = conn.nickGenerator(msg.args[2])
|
local newnick = conn.nickGenerator(msg.args[2])
|
||||||
conn:queue(msgs.nick(newnick))
|
conn:queue(irc.msgs.nick(newnick))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ERR_ERRONEUSNICKNAME (Misspelt but remains for historical reasons)
|
-- ERR_ERRONEUSNICKNAME (Misspelt but remains for historical reasons)
|
||||||
@ -86,6 +146,13 @@ handlers["432"] = needNewNick
|
|||||||
-- ERR_NICKNAMEINUSE
|
-- ERR_NICKNAMEINUSE
|
||||||
handlers["433"] = needNewNick
|
handlers["433"] = needNewNick
|
||||||
|
|
||||||
|
-- ERR_UNAVAILRESOURCE
|
||||||
|
handlers["437"] = function(conn, msg)
|
||||||
|
if not conn.authed then
|
||||||
|
needNewNick(conn, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- RPL_ISUPPORT
|
-- RPL_ISUPPORT
|
||||||
handlers["005"] = function(conn, msg)
|
handlers["005"] = function(conn, msg)
|
||||||
local arglen = #msg.args
|
local arglen = #msg.args
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
local name = ...
|
||||||
|
name = name:gsub("%.init$", "")
|
||||||
|
|
||||||
local irc = require("irc.main")
|
local irc = require(name..".main")
|
||||||
require("irc.util")
|
require(name..".util")
|
||||||
require("irc.asyncoperations")
|
require(name..".asyncoperations")
|
||||||
require("irc.handlers")
|
require(name..".handlers")
|
||||||
require("irc.messages")
|
require(name..".messages")
|
||||||
|
|
||||||
return irc
|
return irc
|
||||||
|
|
||||||
|
@ -11,12 +11,15 @@ local meta_preconnect = {}
|
|||||||
function meta_preconnect.__index(o, k)
|
function meta_preconnect.__index(o, k)
|
||||||
local v = rawget(meta_preconnect, k)
|
local v = rawget(meta_preconnect, k)
|
||||||
|
|
||||||
if not v and meta[k] then
|
if v == nil and meta[k] then
|
||||||
error(("field '%s' is not accessible before connecting"):format(k), 2)
|
error(("field '%s' is not accessible before connecting"):format(k), 2)
|
||||||
end
|
end
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
meta.connected = true
|
||||||
|
meta_preconnect.connected = false
|
||||||
|
|
||||||
function irc.new(data)
|
function irc.new(data)
|
||||||
local o = {
|
local o = {
|
||||||
nick = assert(data.nick, "Field 'nick' is required");
|
nick = assert(data.nick, "Field 'nick' is required");
|
||||||
@ -29,6 +32,9 @@ function irc.new(data)
|
|||||||
messageQueue = {};
|
messageQueue = {};
|
||||||
lastThought = 0;
|
lastThought = 0;
|
||||||
recentMessages = 0;
|
recentMessages = 0;
|
||||||
|
availableCapabilities = {};
|
||||||
|
wantedCapabilities = {};
|
||||||
|
capabilities = {};
|
||||||
}
|
}
|
||||||
assert(irc.checkNick(o.nick), "Erroneous nickname passed to irc.new")
|
assert(irc.checkNick(o.nick), "Erroneous nickname passed to irc.new")
|
||||||
return setmetatable(o, meta_preconnect)
|
return setmetatable(o, meta_preconnect)
|
||||||
@ -57,8 +63,9 @@ function meta:invoke(name, ...)
|
|||||||
local hooks = self.hooks[name]
|
local hooks = self.hooks[name]
|
||||||
if hooks then
|
if hooks then
|
||||||
for id, f in pairs(hooks) do
|
for id, f in pairs(hooks) do
|
||||||
if f(...) then
|
local ret = f(...)
|
||||||
return true
|
if ret then
|
||||||
|
return ret
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -109,10 +116,7 @@ function meta_preconnect:connect(_host, _port)
|
|||||||
self.socket = s
|
self.socket = s
|
||||||
setmetatable(self, meta)
|
setmetatable(self, meta)
|
||||||
|
|
||||||
self:queue(irc.Message({command="CAP", args={"REQ", "multi-prefix"}}))
|
self:invoke("PreRegister")
|
||||||
|
|
||||||
self:invoke("PreRegister", self)
|
|
||||||
self:queue(irc.Message({command="CAP", args={"END"}}))
|
|
||||||
|
|
||||||
if password then
|
if password then
|
||||||
self:queue(irc.Message({command="PASS", args={password}}))
|
self:queue(irc.Message({command="PASS", args={password}}))
|
||||||
@ -142,7 +146,7 @@ end
|
|||||||
|
|
||||||
function meta:shutdown()
|
function meta:shutdown()
|
||||||
self.socket:close()
|
self.socket:close()
|
||||||
setmetatable(self, nil)
|
setmetatable(self, meta_preconnect)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getline(self, errlevel)
|
local function getline(self, errlevel)
|
||||||
|
@ -198,3 +198,7 @@ function msgs.mode(target, modes)
|
|||||||
return irc.Message({command="MODE", args={target, unpack(mt)}})
|
return irc.Message({command="MODE", args={target, unpack(mt)}})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function msgs.cap(cmd, ...)
|
||||||
|
return irc.Message({command="CAP", args={cmd, ...}})
|
||||||
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user