From 7adba31f8cb78ebf5eddf47e6c04bcfad26d569f Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Wed, 23 Oct 2013 09:37:21 -0400 Subject: [PATCH] Add a message queue --- asyncoperations.lua | 14 +++++++++----- doc/irc.luadoc | 4 ++++ handlers.lua | 2 +- init.lua | 31 +++++++++++++++++++++++++------ 4 files changed, 39 insertions(+), 12 deletions(-) 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