Update LuaIRC, and code to match

This commit is contained in:
ShadowNinja 2014-05-06 15:26:13 -04:00
parent f88760a273
commit af4b92921f
10 changed files with 95 additions and 133 deletions

View File

@ -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/luasocket/*.lua"))
env.Install("$prefix/irc", Glob("src/*.lua")) env.Install("$prefix/irc", Glob("src/*.lua"))
env.Install("$prefix/irc", Glob("src/*.txt")) env.Install("$prefix/irc", Glob("src/*.txt"))

@ -1 +1 @@
Subproject commit b1cbbf1963ad0d614e4140d656b4651b846b5768 Subproject commit bc9805a33c438431ec64af3e620387f8fd39d2d3

View File

@ -1,47 +1,48 @@
mt_irc.bot_commands = {} 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 prefix = mt_irc.config.command_prefix
local nick = mt_irc.conn.nick:lower() 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 -- First check for a nick prefix
if nickpart == nick..": " or if nickpart == nick..": " or
nickpart == nick..", " then nickpart == nick..", " then
self:bot_command(user, message:sub(#nick + 3)) self:bot_command(msg, text:sub(#nick + 3))
return true return true
-- Then check for the configured prefix -- Then check for the configured prefix
elseif prefix and message:sub(1, #prefix):lower() == prefix:lower() then elseif prefix and text:sub(1, #prefix):lower() == prefix:lower() then
self:bot_command(user, message:sub(#prefix + 1)) self:bot_command(msg, text:sub(#prefix + 1))
return true return true
end end
return false return false
end end
function mt_irc:bot_command(user, message) function mt_irc:bot_command(msg, text)
if message:sub(1, 1) == "@" then if text:sub(1, 1) == "@" then
local found, _, player_to, message = message:find("^.([^%s]+)%s(.+)$") local found, _, player_to, message = text:find("^.([^%s]+)%s(.+)$")
if not mt_irc.joined_players[player_to] then if not minetest.get_player_by_name(player_to) then
mt_irc:reply("User '"..player_to.."' has parted.")
return
elseif not minetest.get_player_by_name(player_to) then
mt_irc:reply("User '"..player_to.."' is not in the game.") mt_irc:reply("User '"..player_to.."' is not in the game.")
return return
elseif not mt_irc.joined_players[player_to] then
mt_irc:reply("User '"..player_to.."' is not using IRC.")
return
end end
minetest.chat_send_player(player_to, 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!") mt_irc:reply("Message sent!")
return return
end end
local pos = message:find(" ", 1, true) local pos = text:find(" ", 1, true)
local cmd, args local cmd, args
if pos then if pos then
cmd = message:sub(1, pos - 1) cmd = text:sub(1, pos - 1)
args = message:sub(pos + 1) args = text:sub(pos + 1)
else else
cmd = message cmd = text
args = "" args = ""
end end
@ -51,7 +52,7 @@ function mt_irc:bot_command(user, message)
return return
end end
self.bot_commands[cmd].func(user, args) self.bot_commands[cmd].func(msg.user, args)
end end

View File

@ -30,8 +30,7 @@ minetest.register_on_chat_message(function(name, message)
if nl then if nl then
message = message:sub(1, nl - 1) message = message:sub(1, nl - 1)
end end
mt_irc:queueMsg(mt_irc.msgs.playerMessage( mt_irc:say(mt_irc:playerMessage(name, message))
mt_irc.config.channel, name, message))
end) end)

View File

@ -35,7 +35,7 @@ minetest.register_chatcommand("irc_msg", {
"You can not message that user. (Hint: They have to be in the channel)") "You can not message that user. (Hint: They have to be in the channel)")
return return
end 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!") minetest.chat_send_player(name, "Message sent!")
end end
}) })
@ -69,6 +69,7 @@ minetest.register_chatcommand("irc_connect", {
minetest.register_chatcommand("irc_disconnect", { minetest.register_chatcommand("irc_disconnect", {
params = "[message]",
description = "Disconnect from the IRC server.", description = "Disconnect from the IRC server.",
privs = {irc_admin=true}, privs = {irc_admin=true},
func = function(name, param) func = function(name, param)
@ -76,7 +77,10 @@ minetest.register_chatcommand("irc_disconnect", {
minetest.chat_send_player(name, "You are not connected to IRC.") minetest.chat_send_player(name, "You are not connected to IRC.")
return return
end end
mt_irc:disconnect("Manual disconnect.") if params == "" then
params = "Manual disconnect by "..name
end
mt_irc:disconnect(param)
end end
}) })
@ -104,15 +108,15 @@ minetest.register_chatcommand("irc_quote", {
minetest.chat_send_player(name, "You are not connected to IRC.") minetest.chat_send_player(name, "You are not connected to IRC.")
return return
end end
mt_irc:queueMsg(param) mt_irc:queue(param)
minetest.chat_send_player(name, "Command sent!") minetest.chat_send_player(name, "Command sent!")
end end
}) })
local oldme = minetest.chatcommands["me"].func local oldme = minetest.chatcommands["me"].func
minetest.chatcommands["me"].func = function(name, param) minetest.chatcommands["me"].func = function(name, param, ...)
oldme(name, param) oldme(name, param, ...)
mt_irc:say(("* %s %s"):format(name, param)) mt_irc:say(("* %s %s"):format(name, param))
end end

View File

@ -39,7 +39,6 @@ setting("bool", "send_join_part", true) -- Whether to send player join and par
setting("string", "password") -- Server password setting("string", "password") -- Server password
setting("bool", "secure", false) -- Enable a TLS connection, requires LuaSEC 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("number", "timeout", 60) -- Underlying socket timeout in seconds.
setting("string", "command_prefix") -- Prefix to use for bot commands setting("string", "command_prefix") -- Prefix to use for bot commands
setting("bool", "debug", false) -- Enable debug output setting("bool", "debug", false) -- Enable debug output

View File

@ -7,13 +7,16 @@ mt_irc.registered_hooks = {}
-- TODO: Add proper conversion from CP1252 to UTF-8. -- TODO: Add proper conversion from CP1252 to UTF-8.
local stripped_chars = { } local stripped_chars = {"\2", "\31"}
for c = 127, 255 do for c = 127, 255 do
table.insert(stripped_chars, string.char(c)) table.insert(stripped_chars, string.char(c))
end end
stripped_chars = "["..table.concat(stripped_chars, "").."]" stripped_chars = "["..table.concat(stripped_chars, "").."]"
local function normalize(text) local function normalize(text)
-- Strip colors
text = text:gsub("\3[0-9][0-9,]*", "")
return text:gsub(stripped_chars, "") return text:gsub(stripped_chars, "")
end end
@ -47,44 +50,39 @@ function mt_irc.hooks.send(line)
end end
function mt_irc.hooks.chat(user, channel, message) function mt_irc.hooks.chat(msg)
local channel, text = msg.args[1], msg.args[2]
message = normalize(message) if text:sub(1, 1) == string.char(1) then
mt_irc.conn:invoke("OnCTCP", msg)
-- 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)
return return
end end
if channel == mt_irc.conn.nick then if channel == mt_irc.conn.nick then
mt_irc.last_from = user.nick mt_irc.last_from = msg.user.nick
mt_irc.conn:invoke("PrivateMessage", user, message) mt_irc.conn:invoke("PrivateMessage", msg)
else else
mt_irc.last_from = channel mt_irc.last_from = channel
mt_irc.conn:invoke("OnChannelChat", user, channel, message) mt_irc.conn:invoke("OnChannelChat", msg)
end end
end end
function mt_irc.hooks.ctcp(user, channel, message) function mt_irc.hooks.ctcp(msg)
message = message:sub(2, -2) -- Remove ^C local text = msg.args[2]:sub(2, -2) -- Remove ^C
local args = message:split(' ') local args = text:split(' ')
local command = args[1]:upper() local command = args[1]:upper()
local function reply(s) 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 end
if command == "ACTION" and channel ~= mt_irc.conn.nick then if command == "ACTION" and msg.args[1] == mt_irc.config.channel then
local action = message:sub(8, -1) local action = text:sub(8, -1)
mt_irc:sendLocal(("* %s@IRC %s"):format(user.nick, action)) mt_irc:sendLocal(("* %s@IRC %s"):format(msg.user.nick, action))
elseif command == "VERSION" then 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 elseif command == "PING" then
reply(args[2]) reply(args[2])
elseif command == "TIME" then elseif command == "TIME" then
@ -93,49 +91,52 @@ function mt_irc.hooks.ctcp(user, channel, message)
end 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: -- Support multiple servers in a channel better by converting:
-- "<server@IRC> <player> message" into "<player@server> message" -- "<server@IRC> <player> message" into "<player@server> message"
-- "<server@IRC> *** player joined/left the game" into "*** player@server joined/left the game" -- "<server@IRC> *** player joined/left the game" into "*** player joined/left server"
-- and "<server@IRC> * player orders a pizza" into "* player@server orders a pizza" -- and "<server@IRC> * player orders a pizza" into "* player@server orders a pizza"
local foundchat, _, chatnick, chatmessage = local foundchat, _, chatnick, chatmessage =
message:find("^<([^>]+)> (.*)$") text:find("^<([^>]+)> (.*)$")
local foundjoin, _, joinnick = local foundjoin, _, joinnick =
message:find("^%*%*%* ([^%s]+) joined the game$") text:find("^%*%*%* ([^%s]+) joined the game$")
local foundleave, _, leavenick = local foundleave, _, leavenick =
message:find("^%*%*%* ([^%s]+) left the game$") text:find("^%*%*%* ([^%s]+) left the game$")
local foundaction, _, actionnick, actionmessage = 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 return
elseif foundchat then elseif foundchat then
mt_irc:sendLocal(("<%s@%s> %s") mt_irc:sendLocal(("<%s@%s> %s")
:format(chatnick, user.nick, chatmessage)) :format(chatnick, msg.user.nick, chatmessage))
elseif foundjoin then elseif foundjoin then
mt_irc:sendLocal(("*** %s joined %s") mt_irc:sendLocal(("*** %s joined %s")
:format(joinnick, user.nick)) :format(joinnick, msg.user.nick))
elseif foundleave then elseif foundleave then
mt_irc:sendLocal(("*** %s left %s") mt_irc:sendLocal(("*** %s left %s")
:format(leavenick, user.nick)) :format(leavenick, msg.user.nick))
elseif foundaction then elseif foundaction then
mt_irc:sendLocal(("* %s@%s %s") mt_irc:sendLocal(("* %s@%s %s")
:format(actionnick, user.nick, actionmessage)) :format(actionnick, msg.user.nick, actionmessage))
else else
mt_irc:sendLocal(("<%s@IRC> %s"):format(user.nick, message)) mt_irc:sendLocal(("<%s@IRC> %s"):format(msg.user.nick, text))
end end
end end
function mt_irc.hooks.pm(user, message) function mt_irc.hooks.pm(msg)
-- Trim prefix if it is found -- Trim prefix if it is found
local text = msg.args[2]
local prefix = mt_irc.config.command_prefix local prefix = mt_irc.config.command_prefix
if prefix and message:sub(1, #prefix) == prefix then if prefix and text:sub(1, #prefix) == prefix then
message = message:sub(#prefix + 1) text = text:sub(#prefix + 1)
end end
mt_irc:bot_command(user, message) mt_irc:bot_command(msg, text)
end end
@ -151,9 +152,9 @@ end
function mt_irc.hooks.notice(user, target, message) function mt_irc.hooks.notice(user, target, message)
if not user.nick then return end --Server NOTICEs if user.nick and target == mt_irc.config.channel then
if target == mt_irc.conn.nick then return end mt_irc:sendLocal("-"..user.nick.."@IRC- "..message)
mt_irc:sendLocal("--"..user.nick.."@IRC-- "..message) end
end end
@ -163,9 +164,10 @@ function mt_irc.hooks.mode(user, target, modes, ...)
by = " by "..user.nick by = " by "..user.nick
end end
local options = "" local options = ""
for _, option in pairs({...}) do if select("#", ...) > 0 then
options = options.." "..option options = " "
end end
options = options .. table.concat({...}, " ")
minetest.chat_send_all(("-!- mode/%s [%s%s]%s") minetest.chat_send_all(("-!- mode/%s [%s%s]%s")
:format(target, modes, options, by)) :format(target, modes, options, by))
end end
@ -227,7 +229,7 @@ end
mt_irc:register_hook("PreRegister", mt_irc.hooks.preregister) mt_irc:register_hook("PreRegister", mt_irc.hooks.preregister)
mt_irc:register_hook("OnRaw", mt_irc.hooks.raw) mt_irc:register_hook("OnRaw", mt_irc.hooks.raw)
mt_irc:register_hook("OnSend", mt_irc.hooks.send) 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("OnPart", mt_irc.hooks.part)
mt_irc:register_hook("OnKick", mt_irc.hooks.kick) mt_irc:register_hook("OnKick", mt_irc.hooks.kick)
mt_irc:register_hook("OnJoin", mt_irc.hooks.join) mt_irc:register_hook("OnJoin", mt_irc.hooks.join)

View File

@ -3,7 +3,7 @@
mt_irc = { mt_irc = {
version = "0.2.0", -- Also update CMakeLists.txt version = "0.2.0",
connected = false, connected = false,
cur_time = 0, cur_time = 0,
message_buffer = {}, message_buffer = {},
@ -20,7 +20,7 @@ package.cpath = mt_irc.modpath.."/lib?.so;"
..mt_irc.modpath.."/?.dll;" ..mt_irc.modpath.."/?.dll;"
..package.cpath ..package.cpath
local irc = require('irc') require('irc')
dofile(mt_irc.modpath.."/config.lua") dofile(mt_irc.modpath.."/config.lua")
dofile(mt_irc.modpath.."/messages.lua") dofile(mt_irc.modpath.."/messages.lua")
@ -54,32 +54,12 @@ function mt_irc:step(dtime)
if not self.connected then return end 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 -- 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 return
end 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 end
@ -137,7 +117,7 @@ function mt_irc:say(to, message)
end end
to = to or self.config.channel to = to or self.config.channel
self:queueMsg(self.msgs.privmsg(to, message)) self:queue(irc.msgs.privmsg(to, message))
end end
@ -148,8 +128,11 @@ function mt_irc:reply(message)
self:say(self.last_from, message) self:say(self.last_from, message)
end end
function mt_irc:send(line) function mt_irc:send(msg)
self.conn:send(line) self.conn:send(msg)
end end
function mt_irc:queue(msg)
self.conn:queue(msg)
end

View File

@ -6,35 +6,9 @@ function mt_irc:sendLocal(message)
minetest.chat_send_all(message) minetest.chat_send_all(message)
end end
function mt_irc:queueMsg(message, ...) mt_irc.msgs = irc.msgs
if select("#", ...) > 0 then
message = message:format(...) function mt_irc:playerMessage(name, message)
end return ("<%s> %s"):format(name, message)
table.insert(self.message_buffer, message)
end 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

View File

@ -63,7 +63,7 @@ end)
function mt_irc:sendLocal(message) function mt_irc:sendLocal(message)
for name, _ in pairs(self.joined_players) do for name, _ in pairs(self.joined_players) do
minetest.chat_send_player(name, message, false) minetest.chat_send_player(name, message)
end end
end end