2012-12-22 04:16:28 +01:00
|
|
|
|
2013-01-08 16:50:47 +01:00
|
|
|
-- IRC Mod for Minetest
|
|
|
|
-- By Diego Martínez <kaeza@users.sf.net>
|
|
|
|
--
|
|
|
|
-- This mod allows to tie a Minetest server to an IRC channel.
|
|
|
|
--
|
|
|
|
-- This program is free software. It comes without any warranty, to
|
|
|
|
-- the extent permitted by applicable law. You can redistribute it
|
|
|
|
-- and/or modify it under the terms of the Do What The Fuck You Want
|
|
|
|
-- To Public License, Version 2, as published by Sam Hocevar. See
|
|
|
|
-- http://sam.zoy.org/wtfpl/COPYING for more details.
|
|
|
|
--
|
|
|
|
|
|
|
|
local irc = require("irc");
|
|
|
|
|
2013-01-11 17:20:30 +01:00
|
|
|
mt_irc.callbacks = { };
|
|
|
|
|
|
|
|
mt_irc._callback = function ( name, ... )
|
|
|
|
local list = mt_irc.callbacks[name];
|
|
|
|
if (not list) then return; end
|
|
|
|
for n = 1, #list do
|
|
|
|
local r = list[n](...);
|
|
|
|
if (r) 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
|
|
|
|
|
2012-12-22 04:16:28 +01:00
|
|
|
minetest.register_on_joinplayer(function ( player )
|
|
|
|
|
2013-01-08 16:50:47 +01:00
|
|
|
mt_irc.say(mt_irc.channel, "*** "..player:get_player_name().." joined the game");
|
2012-12-29 10:10:26 +01:00
|
|
|
mt_irc.connected_players[player:get_player_name()] = mt_irc.auto_join;
|
2012-12-22 04:16:28 +01:00
|
|
|
|
|
|
|
end);
|
|
|
|
|
|
|
|
irc.register_callback("connect", function ( )
|
2013-01-05 15:48:35 +01:00
|
|
|
mt_irc.got_motd = true;
|
2012-12-22 04:16:28 +01:00
|
|
|
irc.join(mt_irc.channel);
|
|
|
|
end);
|
|
|
|
|
|
|
|
irc.register_callback("channel_msg", function ( channel, from, message )
|
|
|
|
if (not mt_irc.connect_ok) then return; end
|
|
|
|
local t = {
|
|
|
|
name=(from or "<BUG:no one is saying this>");
|
|
|
|
message=(message or "<BUG:there is no message>");
|
|
|
|
server=mt_irc.server;
|
|
|
|
port=mt_irc.port;
|
|
|
|
channel=mt_irc.channel;
|
|
|
|
};
|
|
|
|
local text = mt_irc.message_format_in:gsub("%$%(([^)]+)%)", t)
|
2013-01-11 17:20:30 +01:00
|
|
|
if (mt_irc._callback("channel_msg", from, message, text)) then return; end
|
2012-12-22 04:16:28 +01:00
|
|
|
for k, v in pairs(mt_irc.connected_players) do
|
|
|
|
if (v) then minetest.chat_send_player(k, text); end
|
|
|
|
end
|
|
|
|
end);
|
|
|
|
|
2012-12-23 06:31:52 +01:00
|
|
|
local function bot_command ( from, message )
|
|
|
|
|
|
|
|
local pos = message:find(" ", 1, true);
|
|
|
|
local cmd, args;
|
|
|
|
if (pos) then
|
|
|
|
cmd = message:sub(1, pos - 1);
|
|
|
|
args = message:sub(pos + 1);
|
|
|
|
else
|
|
|
|
cmd = message;
|
|
|
|
args = "";
|
|
|
|
end
|
|
|
|
|
|
|
|
if (not mt_irc.bot_commands[cmd]) then
|
2013-01-08 16:50:47 +01:00
|
|
|
mt_irc.say(from, "Unknown command `"..cmd.."'. Try `!help'.");
|
2012-12-26 20:56:21 +01:00
|
|
|
return;
|
2012-12-23 06:31:52 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
mt_irc.bot_commands[cmd].func(from, args);
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2012-12-22 04:16:28 +01:00
|
|
|
irc.register_callback("private_msg", function ( from, message )
|
|
|
|
if (not mt_irc.connect_ok) then return; end
|
|
|
|
local player_to;
|
|
|
|
local msg;
|
|
|
|
if (message:sub(1, 1) == ">") then
|
|
|
|
local pos = message:find(" ", 1, true);
|
|
|
|
if (not pos) then return; end
|
|
|
|
player_to = message:sub(2, pos - 1);
|
|
|
|
msg = message:sub(pos + 1);
|
2012-12-23 06:31:52 +01:00
|
|
|
elseif (message:sub(1, 1) == "!") then
|
|
|
|
bot_command(from, message:sub(2));
|
|
|
|
return;
|
2012-12-22 04:16:28 +01:00
|
|
|
else
|
2012-12-23 06:31:52 +01:00
|
|
|
irc.say(from, 'Message not sent! Please use "!help" to see possible commands.');
|
2012-12-26 22:13:00 +01:00
|
|
|
irc.say(from, ' Or use the ">playername Message" syntax to send a private message.');
|
2012-12-22 04:16:28 +01:00
|
|
|
return;
|
|
|
|
end
|
|
|
|
if (not mt_irc.connected_players[player_to]) then
|
|
|
|
irc.say(from, "User `"..player_to.."' is not connected to IRC.");
|
|
|
|
return;
|
|
|
|
end
|
|
|
|
local t = {
|
|
|
|
name=(from or "<BUG:no one is saying this>");
|
|
|
|
message=(msg or "<BUG:there is no message>");
|
|
|
|
server=mt_irc.server;
|
|
|
|
port=mt_irc.port;
|
|
|
|
channel=mt_irc.channel;
|
|
|
|
};
|
2013-01-11 17:20:30 +01:00
|
|
|
local text = mt_irc.message_format_in:expandvars(t);
|
|
|
|
if (mt_irc._callback("private_msg", from, player_to, message, text)) then return; end
|
2012-12-22 04:16:28 +01:00
|
|
|
minetest.chat_send_player(player_to, "PRIVATE: "..text);
|
|
|
|
end);
|
|
|
|
|
2013-01-06 10:15:16 +01:00
|
|
|
irc.register_callback("kick", function ( chaninfo, to, from )
|
2013-01-08 16:50:47 +01:00
|
|
|
minetest.chat_send_all("IRC: Bot was kicked by "..from..". Reconnecting bot in 5 seconds...");
|
|
|
|
mt_irc.got_motd = false;
|
|
|
|
mt_irc.connect_ok = false;
|
|
|
|
irc.quit("Kicked");
|
|
|
|
minetest.after(5, mt_irc.connect);
|
2013-01-06 10:15:16 +01:00
|
|
|
end);
|
|
|
|
|
2012-12-22 04:16:28 +01:00
|
|
|
irc.register_callback("nick_change", function ( from, old_nick )
|
|
|
|
if (not mt_irc.connect_ok) then return; end
|
2013-01-09 01:45:55 +01:00
|
|
|
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
|
2012-12-22 04:16:28 +01:00
|
|
|
end);
|
|
|
|
|
2013-01-09 01:50:56 +01:00
|
|
|
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 )
|
|
|
|
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);
|
|
|
|
|
2013-01-09 01:22:45 +01:00
|
|
|
irc.register_callback("channel_act", function ( servinfo, from, message)
|
2013-01-09 01:45:55 +01:00
|
|
|
if (not mt_irc.connect_ok) then return; end
|
2013-01-09 01:22:45 +01:00
|
|
|
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);
|
|
|
|
|
2012-12-22 04:16:28 +01:00
|
|
|
minetest.register_on_leaveplayer(function ( player )
|
|
|
|
local name = player:get_player_name();
|
|
|
|
mt_irc.connected_players[name] = false;
|
|
|
|
if (not mt_irc.connect_ok) then return; end
|
|
|
|
irc.say(mt_irc.channel, "*** "..name.." left the game");
|
|
|
|
end);
|
|
|
|
|
|
|
|
minetest.register_on_chat_message(function ( name, message )
|
2013-01-08 17:13:41 +01:00
|
|
|
if (not mt_irc.connect_ok) then return; end
|
2013-01-02 00:15:45 +01:00
|
|
|
if (message:sub(1, 1) == "/") then return; end
|
2013-01-09 01:22:45 +01:00
|
|
|
if (not mt_irc.connected_players[name]) then return; end
|
|
|
|
if (not minetest.check_player_privs(name, {shout=true})) then
|
2013-01-08 17:13:41 +01:00
|
|
|
return;
|
|
|
|
end
|
2012-12-22 04:16:28 +01:00
|
|
|
if (not mt_irc.buffered_messages) then
|
|
|
|
mt_irc.buffered_messages = { };
|
|
|
|
end
|
|
|
|
mt_irc.buffered_messages[#mt_irc.buffered_messages + 1] = {
|
|
|
|
name = name;
|
|
|
|
message = message;
|
|
|
|
};
|
|
|
|
end);
|
2013-01-02 00:15:45 +01:00
|
|
|
|
|
|
|
minetest.register_on_shutdown(function ( )
|
|
|
|
irc.quit("Game shutting down.");
|
2013-01-06 10:15:16 +01:00
|
|
|
for n = 1, 5 do
|
|
|
|
irc.poll();
|
|
|
|
end
|
2013-01-02 00:15:45 +01:00
|
|
|
end);
|
2013-01-08 16:50:47 +01:00
|
|
|
|
2013-01-19 07:59:38 +01:00
|
|
|
irc.handlers.on_error = function (...) --( from, respond_to )
|
2013-01-09 01:22:45 +01:00
|
|
|
for k, v in pairs(mt_irc.connected_players) do
|
2013-01-19 07:59:38 +01:00
|
|
|
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();
|
2013-01-09 01:22:45 +01:00
|
|
|
end
|
2013-01-08 16:50:47 +01:00
|
|
|
mt_irc.got_motd = false;
|
|
|
|
mt_irc.connect_ok = false;
|
|
|
|
minetest.after(5, mt_irc.connect);
|
|
|
|
end
|
2013-01-19 07:59:38 +01:00
|
|
|
|
|
|
|
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;
|
2013-01-26 21:50:18 +01:00
|
|
|
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;
|
2013-01-19 07:59:38 +01:00
|
|
|
mt_irc.connect();
|
|
|
|
end
|