diff --git a/asyncoperations.lua b/asyncoperations.lua
index 353b894..3a6bf7b 100644
--- a/asyncoperations.lua
+++ b/asyncoperations.lua
@@ -28,6 +28,10 @@ function meta:send(msg, ...)
end
end
+function meta:queue(msg)
+ table.insert(self.messageQueue, msg)
+end
+
local function verify(str, errLevel)
if str:find("^:") or str:find("%s%z") then
error(("malformed parameter '%s' to irc command"):format(str), errLevel)
@@ -39,26 +43,26 @@ end
function meta:sendChat(target, msg)
-- Split the message into segments if it includes newlines.
for line in msg:gmatch("([^\r\n]+)") do
- self:send(msgs.privmsg(verify(target, 3), line))
+ self:queue(msgs.privmsg(verify(target, 3), line))
end
end
function meta:sendNotice(target, msg)
-- Split the message into segments if it includes newlines.
for line in msg:gmatch("([^\r\n]+)") do
- self:send(msgs.notice(verify(target, 3), line))
+ self:queue(msgs.notice(verify(target, 3), line))
end
end
function meta:join(channel, key)
- self:send(msgs.join(
+ self:queue(msgs.join(
verify(channel, 3),
key and verify(key, 3) or nil))
end
function meta:part(channel, reason)
channel = verify(channel, 3)
- self:send(msgs.part(channel, reason))
+ self:queue(msgs.part(channel, reason))
if self.track_users then
self.channels[channel] = nil
end
@@ -88,6 +92,6 @@ function meta:setMode(t)
mode = table.concat{mode, "-", verify(rem, 3)}
end
- self:send(msgs.mode(verify(target, 3), mode))
+ self:queue(msgs.mode(verify(target, 3), mode))
end
diff --git a/doc/irc.luadoc b/doc/irc.luadoc
index 36c5242..5ab1e34 100644
--- a/doc/irc.luadoc
+++ b/doc/irc.luadoc
@@ -75,6 +75,10 @@ function irc:topic(channel)
-- @param ... Format parameters for msg
, with string.format
semantics. [optional]
function irc:send(msg, ...)
+--- Queue Message to be sent to the server.
+-- @param msg Message to be sent.
+function irc:queue(msg)
+
--- Send a message to a channel or user.
-- @param target Nick or channel to send to.
-- @param message Message text.
diff --git a/handlers.lua b/handlers.lua
index fb4de37..d5db2f8 100644
--- a/handlers.lua
+++ b/handlers.lua
@@ -82,7 +82,7 @@ end
local function needNewNick(conn, msg)
local newnick = conn.nickGenerator(msg.args[2])
- conn:send(msgs.nick(newnick))
+ conn:queue(msgs.nick(newnick))
end
-- ERR_ERRONEUSNICKNAME (Misspelt but remains for historical reasons)
diff --git a/init.lua b/init.lua
index 5176367..283dbb8 100644
--- a/init.lua
+++ b/init.lua
@@ -10,6 +10,7 @@ local require = require
local tonumber = tonumber
local type = type
local pcall = pcall
+local remove = table.remove
module "irc"
@@ -41,6 +42,9 @@ function new(data)
hooks = {};
track_users = true;
supports = {};
+ messageQueue = {};
+ lastThought = 0;
+ recentMessages = 0;
}
assert(checkNick(o.nick), "Erroneous nickname passed to irc.new")
return setmetatable(o, meta_preconnect)
@@ -121,17 +125,17 @@ function meta_preconnect:connect(_host, _port)
self.socket = s
setmetatable(self, meta)
- self:send(Message("CAP", {"REQ", "multi-prefix"}))
+ self:queue(Message("CAP", {"REQ", "multi-prefix"}))
self:invoke("PreRegister", self)
- self:send(Message("CAP", {"END"}))
+ self:queue(Message("CAP", {"END"}))
if password then
- self:send(Message("PASS", {password}))
+ self:queue(Message("PASS", {password}))
end
- self:send(msgs.nick(self.nick))
- self:send(Message("USER", {self.username, "0", "*", self.realname}))
+ self:queue(msgs.nick(self.nick))
+ self:queue(Message("USER", {self.username, "0", "*", self.realname}))
self.channels = {}
@@ -180,6 +184,21 @@ function meta:think()
break
end
end
+
+ -- Handle outgoing message queue
+ local diff = socket.gettime() - self.lastThought
+ self.recentMessages = self.recentMessages - (diff * 2)
+ if self.recentMessages < 0 then
+ self.recentMessages = 0
+ end
+ for i = 1, #self.messageQueue do
+ if self.recentMessages > 4 then
+ break
+ end
+ self:send(remove(self.messageQueue, 1))
+ self.recentMessages = self.recentMessages + 1
+ end
+ self.lastThought = socket.gettime()
end
local handlers = handlers
@@ -231,6 +250,6 @@ function meta:whois(nick)
end
function meta:topic(channel)
- self:send(msgs.topic(channel))
+ self:queue(msgs.topic(channel))
end