From af4b92921fa2e8dbb1f8186c1c7ad59d06e9ca08 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 6 May 2014 15:26:13 -0400 Subject: [PATCH] Update LuaIRC, and code to match --- SConstruct | 2 +- src/LuaIRC | 2 +- src/botcmds.lua | 37 +++++++++--------- src/callback.lua | 3 +- src/chatcmds.lua | 14 ++++--- src/config.lua | 1 - src/hooks.lua | 94 +++++++++++++++++++++++---------------------- src/init.lua | 39 ++++++------------- src/messages.lua | 34 ++-------------- src/player_part.lua | 2 +- 10 files changed, 95 insertions(+), 133 deletions(-) diff --git a/SConstruct b/SConstruct index e2360c2..ce45117 100644 --- a/SConstruct +++ b/SConstruct @@ -84,7 +84,7 @@ luasocket_out = env.LoadableModule( ) -env.InstallAs("$prefix/irc/irc", "src/LuaIRC") +env.Install("$prefix/irc/irc", Glob("src/LuaIRC/*.lua")) env.Install("$prefix/irc", Glob("src/luasocket/*.lua")) env.Install("$prefix/irc", Glob("src/*.lua")) env.Install("$prefix/irc", Glob("src/*.txt")) diff --git a/src/LuaIRC b/src/LuaIRC index b1cbbf1..bc9805a 160000 --- a/src/LuaIRC +++ b/src/LuaIRC @@ -1 +1 @@ -Subproject commit b1cbbf1963ad0d614e4140d656b4651b846b5768 +Subproject commit bc9805a33c438431ec64af3e620387f8fd39d2d3 diff --git a/src/botcmds.lua b/src/botcmds.lua index 41ba12b..a574338 100644 --- a/src/botcmds.lua +++ b/src/botcmds.lua @@ -1,47 +1,48 @@ mt_irc.bot_commands = {} -function mt_irc:check_botcmd(user, target, message) +function mt_irc:check_botcmd(msg) local prefix = mt_irc.config.command_prefix local nick = mt_irc.conn.nick:lower() - local nickpart = message:sub(1, #nick + 2):lower() + local text = msg.args[2] + local nickpart = text:sub(1, #nick + 2):lower() -- First check for a nick prefix if nickpart == nick..": " or nickpart == nick..", " then - self:bot_command(user, message:sub(#nick + 3)) + self:bot_command(msg, text:sub(#nick + 3)) return true -- Then check for the configured prefix - elseif prefix and message:sub(1, #prefix):lower() == prefix:lower() then - self:bot_command(user, message:sub(#prefix + 1)) + elseif prefix and text:sub(1, #prefix):lower() == prefix:lower() then + self:bot_command(msg, text:sub(#prefix + 1)) return true end return false end -function mt_irc:bot_command(user, message) - if message:sub(1, 1) == "@" then - local found, _, player_to, message = message:find("^.([^%s]+)%s(.+)$") - if not mt_irc.joined_players[player_to] then - mt_irc:reply("User '"..player_to.."' has parted.") - return - elseif not minetest.get_player_by_name(player_to) then +function mt_irc:bot_command(msg, text) + if text:sub(1, 1) == "@" then + local found, _, player_to, message = text:find("^.([^%s]+)%s(.+)$") + if not minetest.get_player_by_name(player_to) then mt_irc:reply("User '"..player_to.."' is not in the game.") return + elseif not mt_irc.joined_players[player_to] then + mt_irc:reply("User '"..player_to.."' is not using IRC.") + return end minetest.chat_send_player(player_to, - "PM from "..user.nick.."@IRC: "..message, false) + "PM from "..msg.user.nick.."@IRC: "..message, false) mt_irc:reply("Message sent!") return end - local pos = message:find(" ", 1, true) + local pos = text:find(" ", 1, true) local cmd, args if pos then - cmd = message:sub(1, pos - 1) - args = message:sub(pos + 1) + cmd = text:sub(1, pos - 1) + args = text:sub(pos + 1) else - cmd = message + cmd = text args = "" end @@ -51,7 +52,7 @@ function mt_irc:bot_command(user, message) return end - self.bot_commands[cmd].func(user, args) + self.bot_commands[cmd].func(msg.user, args) end diff --git a/src/callback.lua b/src/callback.lua index 34de19c..f85a636 100644 --- a/src/callback.lua +++ b/src/callback.lua @@ -30,8 +30,7 @@ minetest.register_on_chat_message(function(name, message) if nl then message = message:sub(1, nl - 1) end - mt_irc:queueMsg(mt_irc.msgs.playerMessage( - mt_irc.config.channel, name, message)) + mt_irc:say(mt_irc:playerMessage(name, message)) end) diff --git a/src/chatcmds.lua b/src/chatcmds.lua index badf28f..790688e 100644 --- a/src/chatcmds.lua +++ b/src/chatcmds.lua @@ -35,7 +35,7 @@ minetest.register_chatcommand("irc_msg", { "You can not message that user. (Hint: They have to be in the channel)") return end - mt_irc:queueMsg(mt_irc.msgs.playerMessage(toname, name, message)) + mt_irc:say(toname, mt_irc:playerMessage(name, message)) minetest.chat_send_player(name, "Message sent!") end }) @@ -69,6 +69,7 @@ minetest.register_chatcommand("irc_connect", { minetest.register_chatcommand("irc_disconnect", { + params = "[message]", description = "Disconnect from the IRC server.", privs = {irc_admin=true}, func = function(name, param) @@ -76,7 +77,10 @@ minetest.register_chatcommand("irc_disconnect", { minetest.chat_send_player(name, "You are not connected to IRC.") return end - mt_irc:disconnect("Manual disconnect.") + if params == "" then + params = "Manual disconnect by "..name + end + mt_irc:disconnect(param) end }) @@ -104,15 +108,15 @@ minetest.register_chatcommand("irc_quote", { minetest.chat_send_player(name, "You are not connected to IRC.") return end - mt_irc:queueMsg(param) + mt_irc:queue(param) minetest.chat_send_player(name, "Command sent!") end }) local oldme = minetest.chatcommands["me"].func -minetest.chatcommands["me"].func = function(name, param) - oldme(name, param) +minetest.chatcommands["me"].func = function(name, param, ...) + oldme(name, param, ...) mt_irc:say(("* %s %s"):format(name, param)) end diff --git a/src/config.lua b/src/config.lua index b7492fb..a6ea892 100644 --- a/src/config.lua +++ b/src/config.lua @@ -39,7 +39,6 @@ setting("bool", "send_join_part", true) -- Whether to send player join and par setting("string", "password") -- Server password setting("bool", "secure", false) -- Enable a TLS connection, requires LuaSEC -setting("number", "interval", 2) -- Time between chat updates in seconds. Setting this too low can cause "Excess flood" disconnects. setting("number", "timeout", 60) -- Underlying socket timeout in seconds. setting("string", "command_prefix") -- Prefix to use for bot commands setting("bool", "debug", false) -- Enable debug output diff --git a/src/hooks.lua b/src/hooks.lua index e87f38f..c791912 100644 --- a/src/hooks.lua +++ b/src/hooks.lua @@ -7,13 +7,16 @@ mt_irc.registered_hooks = {} -- TODO: Add proper conversion from CP1252 to UTF-8. -local stripped_chars = { } +local stripped_chars = {"\2", "\31"} for c = 127, 255 do table.insert(stripped_chars, string.char(c)) end stripped_chars = "["..table.concat(stripped_chars, "").."]" local function normalize(text) + -- Strip colors + text = text:gsub("\3[0-9][0-9,]*", "") + return text:gsub(stripped_chars, "") end @@ -47,44 +50,39 @@ function mt_irc.hooks.send(line) end -function mt_irc.hooks.chat(user, channel, message) - - message = normalize(message) - - -- Strip bold, underline, and colors - message = message:gsub('\2', '') - message = message:gsub('\31', '') - message = message:gsub('\3[0-9][0-9,]*', '') - - if string.sub(message, 1, 1) == string.char(1) then - mt_irc.conn:invoke("OnCTCP", user, channel, message) +function mt_irc.hooks.chat(msg) + local channel, text = msg.args[1], msg.args[2] + if text:sub(1, 1) == string.char(1) then + mt_irc.conn:invoke("OnCTCP", msg) return end if channel == mt_irc.conn.nick then - mt_irc.last_from = user.nick - mt_irc.conn:invoke("PrivateMessage", user, message) + mt_irc.last_from = msg.user.nick + mt_irc.conn:invoke("PrivateMessage", msg) else mt_irc.last_from = channel - mt_irc.conn:invoke("OnChannelChat", user, channel, message) + mt_irc.conn:invoke("OnChannelChat", msg) end end -function mt_irc.hooks.ctcp(user, channel, message) - message = message:sub(2, -2) -- Remove ^C - local args = message:split(' ') +function mt_irc.hooks.ctcp(msg) + local text = msg.args[2]:sub(2, -2) -- Remove ^C + local args = text:split(' ') local command = args[1]:upper() local function reply(s) - mt_irc:queueMsg("NOTICE %s :\1%s %s\1", user.nick, command, s) + mt_irc:queue(irc.msgs.notice(msg.user.nick, + ("\1%s %s\1"):format(command, s))) end - if command == "ACTION" and channel ~= mt_irc.conn.nick then - local action = message:sub(8, -1) - mt_irc:sendLocal(("* %s@IRC %s"):format(user.nick, action)) + if command == "ACTION" and msg.args[1] == mt_irc.config.channel then + local action = text:sub(8, -1) + mt_irc:sendLocal(("* %s@IRC %s"):format(msg.user.nick, action)) elseif command == "VERSION" then - reply("Minetest IRC mod "..mt_irc.version) + reply(("Minetest IRC mod version %s.") + :format(mt_irc.version)) elseif command == "PING" then reply(args[2]) elseif command == "TIME" then @@ -93,49 +91,52 @@ function mt_irc.hooks.ctcp(user, channel, message) end -function mt_irc.hooks.channelChat(user, channel, message) +function mt_irc.hooks.channelChat(msg) + local text = normalize(msg.args[2]) + -- Support multiple servers in a channel better by converting: -- " message" into " message" - -- " *** player joined/left the game" into "*** player@server joined/left the game" + -- " *** player joined/left the game" into "*** player joined/left server" -- and " * player orders a pizza" into "* player@server orders a pizza" local foundchat, _, chatnick, chatmessage = - message:find("^<([^>]+)> (.*)$") + text:find("^<([^>]+)> (.*)$") local foundjoin, _, joinnick = - message:find("^%*%*%* ([^%s]+) joined the game$") + text:find("^%*%*%* ([^%s]+) joined the game$") local foundleave, _, leavenick = - message:find("^%*%*%* ([^%s]+) left the game$") + text:find("^%*%*%* ([^%s]+) left the game$") local foundaction, _, actionnick, actionmessage = - message:find("^%* ([^%s]+) (.*)$") + text:find("^%* ([^%s]+) (.*)$") - mt_irc:check_botcmd(user, channel, message) + mt_irc:check_botcmd(msg) - if message:sub(1, 5) == "[off]" then + if text:sub(1, 5) == "[off]" then return elseif foundchat then mt_irc:sendLocal(("<%s@%s> %s") - :format(chatnick, user.nick, chatmessage)) + :format(chatnick, msg.user.nick, chatmessage)) elseif foundjoin then mt_irc:sendLocal(("*** %s joined %s") - :format(joinnick, user.nick)) + :format(joinnick, msg.user.nick)) elseif foundleave then mt_irc:sendLocal(("*** %s left %s") - :format(leavenick, user.nick)) + :format(leavenick, msg.user.nick)) elseif foundaction then mt_irc:sendLocal(("* %s@%s %s") - :format(actionnick, user.nick, actionmessage)) + :format(actionnick, msg.user.nick, actionmessage)) else - mt_irc:sendLocal(("<%s@IRC> %s"):format(user.nick, message)) + mt_irc:sendLocal(("<%s@IRC> %s"):format(msg.user.nick, text)) end end -function mt_irc.hooks.pm(user, message) +function mt_irc.hooks.pm(msg) -- Trim prefix if it is found + local text = msg.args[2] local prefix = mt_irc.config.command_prefix - if prefix and message:sub(1, #prefix) == prefix then - message = message:sub(#prefix + 1) + if prefix and text:sub(1, #prefix) == prefix then + text = text:sub(#prefix + 1) end - mt_irc:bot_command(user, message) + mt_irc:bot_command(msg, text) end @@ -151,9 +152,9 @@ end function mt_irc.hooks.notice(user, target, message) - if not user.nick then return end --Server NOTICEs - if target == mt_irc.conn.nick then return end - mt_irc:sendLocal("--"..user.nick.."@IRC-- "..message) + if user.nick and target == mt_irc.config.channel then + mt_irc:sendLocal("-"..user.nick.."@IRC- "..message) + end end @@ -163,9 +164,10 @@ function mt_irc.hooks.mode(user, target, modes, ...) by = " by "..user.nick end local options = "" - for _, option in pairs({...}) do - options = options.." "..option + if select("#", ...) > 0 then + options = " " end + options = options .. table.concat({...}, " ") minetest.chat_send_all(("-!- mode/%s [%s%s]%s") :format(target, modes, options, by)) end @@ -227,7 +229,7 @@ end mt_irc:register_hook("PreRegister", mt_irc.hooks.preregister) mt_irc:register_hook("OnRaw", mt_irc.hooks.raw) mt_irc:register_hook("OnSend", mt_irc.hooks.send) -mt_irc:register_hook("OnChat", mt_irc.hooks.chat) +mt_irc:register_hook("DoPrivmsg", mt_irc.hooks.chat) mt_irc:register_hook("OnPart", mt_irc.hooks.part) mt_irc:register_hook("OnKick", mt_irc.hooks.kick) mt_irc:register_hook("OnJoin", mt_irc.hooks.join) diff --git a/src/init.lua b/src/init.lua index 3e22a99..66dd518 100644 --- a/src/init.lua +++ b/src/init.lua @@ -3,7 +3,7 @@ mt_irc = { - version = "0.2.0", -- Also update CMakeLists.txt + version = "0.2.0", connected = false, cur_time = 0, message_buffer = {}, @@ -20,7 +20,7 @@ package.cpath = mt_irc.modpath.."/lib?.so;" ..mt_irc.modpath.."/?.dll;" ..package.cpath -local irc = require('irc') +require('irc') dofile(mt_irc.modpath.."/config.lua") dofile(mt_irc.modpath.."/messages.lua") @@ -54,32 +54,12 @@ function mt_irc:step(dtime) if not self.connected then return end - -- Tick down the recent message count - self.cur_time = self.cur_time + dtime - if self.cur_time >= self.config.interval then - if self.recent_message_count > 0 then - self.recent_message_count = self.recent_message_count - 1 - end - self.cur_time = self.cur_time - self.config.interval - end - -- Hooks will manage incoming messages and errors - if not pcall(function() self.conn:think() end) then + local good, err = xpcall(function() self.conn:think() end, debug.traceback) + if not good then + print(err) return end - - -- Send messages in the buffer - if #self.message_buffer > 10 then - minetest.log("error", "IRC: Message buffer overflow, clearing.") - self.message_buffer = {} - elseif #self.message_buffer > 0 then - for i=1, #self.message_buffer do - if self.recent_message_count > 4 then break end - self.recent_message_count = self.recent_message_count + 1 - local msg = table.remove(self.message_buffer, 1) --Pop the first message - self:send(msg) - end - end end @@ -137,7 +117,7 @@ function mt_irc:say(to, message) end to = to or self.config.channel - self:queueMsg(self.msgs.privmsg(to, message)) + self:queue(irc.msgs.privmsg(to, message)) end @@ -148,8 +128,11 @@ function mt_irc:reply(message) self:say(self.last_from, message) end -function mt_irc:send(line) - self.conn:send(line) +function mt_irc:send(msg) + self.conn:send(msg) end +function mt_irc:queue(msg) + self.conn:queue(msg) +end diff --git a/src/messages.lua b/src/messages.lua index 145cd4b..4f3515c 100644 --- a/src/messages.lua +++ b/src/messages.lua @@ -6,35 +6,9 @@ function mt_irc:sendLocal(message) minetest.chat_send_all(message) end -function mt_irc:queueMsg(message, ...) - if select("#", ...) > 0 then - message = message:format(...) - end - table.insert(self.message_buffer, message) +mt_irc.msgs = irc.msgs + +function mt_irc:playerMessage(name, message) + return ("<%s> %s"):format(name, message) end -function mt_irc:sendMsg(message) - self.conn:send(message) -end - -mt_irc.msgs = {} - -function mt_irc.msgs.privmsg(to, message) - return ("PRIVMSG %s :%s"):format(to, message) -end - -function mt_irc.msgs.notice(to, message) - return ("NOTICE %s :%s"):format(to, message) -end - -function mt_irc.msgs.action(to, message) - return ("PRIVMSG %s :%cACTION %s%c") - :format(to, string.char(1), message, string.char(1)) -end - -function mt_irc.msgs.playerMessage(to, name, message) - return mt_irc.msgs.privmsg(to, ("<%s> %s"):format(name, message)) -end - --- TODO Add more message types - diff --git a/src/player_part.lua b/src/player_part.lua index abd1583..3cdc388 100644 --- a/src/player_part.lua +++ b/src/player_part.lua @@ -63,7 +63,7 @@ end) function mt_irc:sendLocal(message) for name, _ in pairs(self.joined_players) do - minetest.chat_send_player(name, message, false) + minetest.chat_send_player(name, message) end end