Compare commits

...

10 Commits

Author SHA1 Message Date
Diego Martínez
809ca1b526 added msg_out, nick_change, and part callback support 2013-03-28 23:29:23 -03:00
Diego Martínez
f19033185b Fixed some stupid bugs 2013-03-28 07:41:24 -03:00
Diego Martínez
9eb893e50a Fixed crash when requesting help for unknown command with !help 2013-01-26 18:50:18 -02:00
Diego Martínez
33a16ac395 Reconnect with a different nickname if the original is already in use 2013-01-19 04:59:38 -02:00
Diego Martínez
96ed8287f4 added callbacks to block or otherwise process messages from other mods 2013-01-11 14:20:30 -02:00
Diego Martínez
b147586bc3 Removed LITE_VERSION option 2013-01-09 12:25:32 -02:00
Diego Martínez
8349018333 Updated README 2013-01-09 12:24:16 -02:00
Diego Martínez
977bc94f11 Added option to not build luasocket as part of the mod 2013-01-09 12:01:03 -02:00
Diego Martínez
105db6bc60 Added message when a user joins or parts the channel 2013-01-08 22:50:56 -02:00
Diego Martínez
0ebe49f0b1 Added message when a user changes nickname 2013-01-08 22:45:55 -02:00
8 changed files with 227 additions and 36 deletions

View File

@ -7,6 +7,8 @@ This mod is just a glue between luasocket, LuaIRC, and Minetest. It
provides a two-way communication between the in-game chat, and an
arbitrary IRC channel.
The forum topic is at http://minetest.net/forum/viewtopic.php?id=3905
COMPILING
---------
@ -172,14 +174,21 @@ To avoid possible misunderstandings (since all in-game players use the
private messages that are not in that format, and will send back a
nice reminder as a private message.
The bot also supports some basic commands, which are invoked by sending
a private message to it. Use `!help' to get a list of commands, and
`!help <command>' to get help about a specific command.
THANKS
------
I'd like to thank the users who supported this mod both on the Minetest
Forums and on the #minetest channel. In no particular order:
leo_rockway, VanessaE, OldCoder, sfan5, RealBadAngel, Muadtralk/sdzen,
Josh, celeron55, KikaRz, and many others I forgot about (sorry!).
Shaun/kizeren, RAPHAEL, DARGON, Calinou, Exio, vortexlabs/mrtux,
marveidemanis, marktraceur, jmf/john_minetest, sdzen/Muadtralk,
VanessaE, PilzAdam, sfan5, celeron55, KikaRz, OldCoder, RealBadAngel,
and all the people who commented in the forum topic. Thanks to you all!
LICENSE
-------

View File

@ -12,7 +12,6 @@ In order to allow your mod to interface with this mod, you must add `irc'
REFERENCE
---------
These are the functions defined by the mod:
mt_irc.say ( [name ,] message )
Sends <message> to either the channel (if <name> is nil or not specified),
@ -40,6 +39,103 @@ mt_irc.register_bot_command ( name, cmddef )
params = nil, -- No params
description = "Greet user",
func = function ( from, param )
mt_irc.say(from, "Hello!");
mt_irc.say(from, "Hello!")
end,
});
mt_irc.connected_players [ name ]
This table holds the players who are currently on the channel (may be less
than the players in the game). It is modified by the /part and /join chat
commands.
Example:
if (mt_irc.connected_players["joe"]) then
-- Joe is talking on IRC
end
mt_irc.register_callback ( name, func )
Registers a function to be called when an event happens. <name> is the name
of the event, and <func> is the function to be called. See CALLBACKS below
for more information
Example:
mt_irc.register_callback("channel_msg", function ( from, msg )
if (from == "joe") then
mt_irc.say("joe", "You are not allowed to do that!")
return true
end
end)
This mod also supplies some utility functions:
string.expandvars ( string, vars )
Expands all occurrences of the pattern "$(varname)" with the value of
`varname' in the <vars> table. Variable names not found on the table
are left verbatim in the string.
Example:
local tpl = "$(foo) $(bar) $(baz)"
local s = tpl:expandvars({ foo=1, bar="Hello" })
-- `s' now contains "1 Hello $(baz)"
In addition, all the configuration options decribed in `README.txt' are
available to other mods, though they should be considered "read only". Do
not modify these settings at runtime or you will most likely crash the
server!
CALLBACKS
---------
The `mt_irc.register_callback' function can register functions to be called
when some events happen. These are the events supported:
msg_out ( from, message )
Called right before the bot sends a message to the channel.
<from> is the name of the user sending the message. <message> is the
unmodified message sent by the user.
Return values:
"string" New message to be sent.
false Filter out the message (do not send anything).
nil Use original message
other Use a string repr of the value as message.
Example:
mt_irc.register_callback("msg_out", function ( from, msg )
if (from == "joe") then
mt_irc.say("joe", "You are not allowed to do that!")
return false
end
end)
msg_in ( from, to, message )
Called right before the bot sends a private message to an user.
<from> is the name of the user sending the message. <to> is the recipient
of the message. <message> is the unmodified message sent by the user.
Return values:
"string" New message to be sent.
false Filter out the message (do not send anything).
nil Use original message
other Use a string repr of the value as message.
Example:
mt_irc.register_callback("msg_in", function ( from, to, msg )
if (to == "admin") then
mt_irc.say(from, "You are not allowed to do that!")
return true
end
end)
nick_change ( old_nick, new_nick )
Called when an user in IRC changes nickname.
<old_nick> and <new_nick> are self-explanatory.
Return value:
none
Example:
mt_irc.register_callback("nick_change", function ( old_nick, new_nick )
mt_irc.say(from, "Hello "..new_nick.."! You were "..old_nick.."?")
end)
part ( nick, part_msg )
Called when an user leaves the IRC channel.
<nick> is the user leaving; <part_msg> is the "parting message".
Return value:
none
Example:
mt_irc.register_callback("part", function ( nick, part_msg )
mt_irc.say(from, nick.." has left the building!")
end)

View File

@ -4,6 +4,7 @@ TODO List
- Check for availability of nickname on join, and select a different one
until one is available.
- Implement more callbacks for `mt_irc.register_callback'.
Not TODO List
-------------

View File

@ -1,2 +1,7 @@
#! /bin/sh
(cd Build && cmake . && make && make pack_mod && rm -fr ~/.minetest/games/testing/mods/irc && cp -fr irc ~/.minetest/games/testing/mods/ )
cd Build \
&& cmake .. \
&& make \
&& make pack_mod \
&& rm -fr ~/.minetest/games/testing/mods/irc \
&& cp -fr irc ~/.minetest/games/testing/mods/

View File

@ -5,6 +5,7 @@ mt_irc.bot_help = function ( from, cmdname )
local cmd = mt_irc.bot_commands[cmdname];
if (not cmd) then
irc.say(from, "Unknown command `"..cmdname.."'");
return;
end
local usage = "Usage: !"..cmdname;
if (cmd.params) then usage = usage.." "..cmd.params; end

View File

@ -13,11 +13,38 @@
local irc = require("irc");
mt_irc.callbacks = { };
mt_irc._callback = function ( name, breakonreturn, ... )
local list = mt_irc.callbacks[name];
if (not list) then return; end
for n = 1, #list do
local r = list[n](...);
if (breakonreturn and (r ~= nil)) then return r; end
end
end
mt_irc.register_callback = function ( name, func )
local list = mt_irc.callbacks[name];
if (not list) then
list = { };
mt_irc.callbacks[name] = list;
end
list[#list + 1] = func;
end
minetest.register_on_joinplayer(function ( player )
local name = player:get_player_name();
mt_irc.connected_players[name] = mt_irc.auto_join;
if (not mt_irc.connect_ok) then return; end
mt_irc.say("*** "..name.." joined the game");
end);
mt_irc.say(mt_irc.channel, "*** "..player:get_player_name().." joined the game");
mt_irc.connected_players[player:get_player_name()] = mt_irc.auto_join;
minetest.register_on_leaveplayer(function ( player )
local name = player:get_player_name();
mt_irc.connected_players[name] = nil;
if (not mt_irc.connect_ok) then return; end
mt_irc.say("*** "..name.." left the game");
end);
irc.register_callback("connect", function ( )
@ -35,6 +62,7 @@ irc.register_callback("channel_msg", function ( channel, from, message )
channel=mt_irc.channel;
};
local text = mt_irc.message_format_in:gsub("%$%(([^)]+)%)", t)
if (mt_irc._callback("channel_msg", from, message, text)) then return; end
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
end
@ -89,7 +117,8 @@ irc.register_callback("private_msg", function ( from, message )
port=mt_irc.port;
channel=mt_irc.channel;
};
local text = mt_irc.message_format_in:gsub("%$%(([^)]+)%)", t)
local text = mt_irc.message_format_in:expandvars(t);
if (mt_irc._callback("private_msg", from, player_to, message, text)) then return; end
minetest.chat_send_player(player_to, "PRIVATE: "..text);
end);
@ -103,20 +132,34 @@ end);
irc.register_callback("nick_change", function ( from, old_nick )
if (not mt_irc.connect_ok) then return; end
end);
irc.register_callback("channel_act", function ( servinfo, from, message)
local text = "*** "..from.." "..message;
mt_irc._callback("nick_change", false, old_nick, from);
local text = "["..old_nick.." changed his nick to "..from.."]";
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
end
end);
minetest.register_on_leaveplayer(function ( player )
local name = player:get_player_name();
mt_irc.connected_players[name] = false;
irc.register_callback("join", function ( servinfo, from )
local text = "*** "..from.." joined "..mt_irc.channel;
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
end
end);
irc.register_callback("part", function ( servinfo, from, part_msg )
mt_irc._callback("part", false, from, part_msg);
local text = "*** "..from.." left "..mt_irc.channel.." ("..part_msg..")";
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
end
end);
irc.register_callback("channel_act", function ( servinfo, from, message)
if (not mt_irc.connect_ok) then return; end
irc.say(mt_irc.channel, "*** "..name.." left the game");
local text = "*** "..from.." "..message;
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
end
end);
minetest.register_on_chat_message(function ( name, message )
@ -142,12 +185,42 @@ minetest.register_on_shutdown(function ( )
end
end);
irc.handlers.on_error = function (from, respond_to)
irc.handlers.on_error = function (...) --( from, respond_to )
for k, v in pairs(mt_irc.connected_players) do
if (v) then minetest.chat_send_player(k, text); end
if (v) then minetest.chat_send_player(k, "IRC: Bot had a network error. Reconnecting in 5 seconds..."); end
end
for _, v in ipairs({...}) do
minetest.chat_send_all(dump(v));
end
irc.quit("Network error");
for n = 1, 5 do
irc.poll();
end
mt_irc.got_motd = false;
mt_irc.connect_ok = false;
irc.quit("Ping timeout");
minetest.after(5, mt_irc.connect);
end
irc.handlers.on_err_nicknameinuse = function ( from, respond_to )
irc.quit("Nick in use");
for n = 1, 5 do
irc.poll();
end
mt_irc.got_motd = false;
mt_irc.connect_ok = false;
local n = (tonumber(mt_irc.server_nick:sub(-1)) or 0) + 1;
if (n == 10) then n = 1; end
mt_irc.server_nick = mt_irc.server_nick:sub(1, -2)..n;
mt_irc.connect();
end
-- TESTING
--[[
mt_irc.register_callback("part", function ( nick, part_msg )
mt_irc.say("TEST: "..nick.." has left the building!");
end)
mt_irc.register_callback("nick_change", function ( old_nick, new_nick )
mt_irc.say("TEST: "..old_nick.." -> "..new_nick);
end)
]]

View File

@ -30,7 +30,7 @@ minetest.register_chatcommand("msg", {
name=name;
message=msg;
};
local text = mt_irc.message_format_out:gsub("%$%(([^)]+)%)", t)
local text = mt_irc.message_format_out:expandvars(t);
irc.send("PRIVMSG", name, text);
end;
});

View File

@ -61,25 +61,17 @@ mt_irc.part = function ( name )
minetest.chat_send_player(name, "IRC: You are not in the channel.");
return;
end
mt_irc.connected_players[name] = false;
mt_irc.connected_players[name] = nil;
minetest.chat_send_player(name, "IRC: You are now out of the channel.");
--irc.send(mt_irc.channel, name.." is no longer in the channel.");
irc.send(name.." is no longer in the channel.");
end
mt_irc.join = function ( name )
local function do_join ( name )
if (mt_irc.connected_players[name]) then
minetest.chat_send_player(name, "IRC: You are already in the channel.");
return;
end
mt_irc.connected_players[name] = true;
mt_irc.join(mt_irc.channel);
minetest.chat_send_player(name, "IRC: You are now in the channel.");
end
if (not pcall(do_join, name)) then
mt_irc.connected_players[name] = false;
if (mt_irc.connected_players[name]) then
minetest.chat_send_player(name, "IRC: You are already in the channel.");
return;
end
mt_irc.connected_players[name] = true;
minetest.chat_send_player(name, "IRC: You are now in the channel.");
end
mt_irc.connect = function ( )
@ -107,6 +99,7 @@ mt_irc.connect = function ( )
for _,player in ipairs(minetest.get_connected_players()) do
mt_irc.connected_players[player:get_player_name()] = mt_irc.auto_join;
end
mt_irc.players_connected = true;
end
mt_irc.cur_time = mt_irc.cur_time + dtime;
if (mt_irc.cur_time >= mt_irc.dtime) then
@ -116,7 +109,7 @@ mt_irc.connect = function ( )
name=(msg.name or "<BUG:no one is saying this>");
message=(msg.message or "<BUG:there is no message>");
};
local text = mt_irc.message_format_out:gsub("%$%(([^)]+)%)", t)
local text = mt_irc.message_format_out:expandvars(t);
irc.say(mt_irc.channel, text);
end
mt_irc.buffered_messages = nil;
@ -140,11 +133,24 @@ mt_irc.say = function ( to, msg )
end
to = to or mt_irc.channel;
msg = msg or "";
local msg2 = mt_irc._callback("msg_out", true, to, msg);
if ((type(msg2) == "boolean") and (not msg2)) then
return;
elseif (msg2 ~= nil) then
msg = tostring(msg);
end
irc.say(to, msg);
end
mt_irc.irc = irc;
-- Misc helpers
-- Requested by Exio
string.expandvars = function ( s, vars )
return s:gsub("%$%(([^)]+)%)", vars);
end
dofile(MODPATH.."/callback.lua");
dofile(MODPATH.."/chatcmds.lua");
dofile(MODPATH.."/botcmds.lua");