irc_modpack/irc/botcmds.lua

177 lines
4.5 KiB
Lua
Raw Normal View History

2015-09-17 20:51:25 +02:00
irc.bot_commands = {}
-- From RFC1459:
-- "Because of IRCs scandanavian origin, the characters {}| are
-- considered to be the lower case equivalents of the characters
-- []\, respectively."
local irctolower = { ["["]="{", ["\\"]="|", ["]"]="}" }
local function irclower(s)
return (s:lower():gsub("[%[%]\\]", irctolower))
end
local function nickequals(nick1, nick2)
return irclower(nick1) == irclower(nick2)
end
function irc.check_botcmd(msg)
2015-09-17 20:51:25 +02:00
local prefix = irc.config.command_prefix
local nick = irc.conn.nick
2015-09-17 20:51:25 +02:00
local text = msg.args[2]
local nickpart = text:sub(1, #nick)
local suffix = text:sub(#nick+1, #nick+2)
2015-09-17 20:51:25 +02:00
-- First check for a nick prefix
if nickequals(nickpart, nick)
and (suffix == ": " or suffix == ", ") then
irc.bot_command(msg, text:sub(#nick + 3))
2015-09-17 20:51:25 +02:00
return true
-- Then check for the configured prefix
elseif prefix and text:sub(1, #prefix):lower() == prefix:lower() then
irc.bot_command(msg, text:sub(#prefix + 1))
2015-09-17 20:51:25 +02:00
return true
end
return false
end
function irc.bot_command(msg, text)
-- Remove leading whitespace
text = text:match("^%s*(.*)")
2015-09-17 20:51:25 +02:00
if text:sub(1, 1) == "@" then
local _, _, player_to, message = text:find("^.([^%s]+)%s(.+)$")
if not player_to then
return
elseif not minetest.get_player_by_name(player_to) then
irc.reply("User '"..player_to.."' is not in the game.")
2015-09-17 20:51:25 +02:00
return
elseif not irc.joined_players[player_to] then
irc.reply("User '"..player_to.."' is not using IRC.")
2015-09-17 20:51:25 +02:00
return
end
minetest.chat_send_player(player_to,
minetest.colorize(irc.config.pm_color,
"PM from "..msg.user.nick.."@IRC: "..message, false))
irc.reply("Message sent!")
2015-09-17 20:51:25 +02:00
return
end
local pos = text:find(" ", 1, true)
local cmd, args
if pos then
cmd = text:sub(1, pos - 1)
args = text:sub(pos + 1)
else
cmd = text
args = ""
end
2015-09-23 20:54:57 +02:00
if not irc.bot_commands[cmd] then
irc.reply("Unknown command '"..cmd.."'. Try 'help'."
2015-09-17 20:51:25 +02:00
.." Or use @playername <message> to send a private message")
return
end
2015-09-23 20:54:57 +02:00
local _, message = irc.bot_commands[cmd].func(msg.user, args)
2015-09-17 20:51:25 +02:00
if message then
irc.reply(message)
2015-09-17 20:51:25 +02:00
end
end
function irc.register_bot_command(name, def)
2015-09-17 20:51:25 +02:00
if (not def.func) or (type(def.func) ~= "function") then
error("Erroneous bot command definition. def.func missing.", 2)
elseif name:sub(1, 1) == "@" then
error("Erroneous bot command name. Command name begins with '@'.", 2)
end
irc.bot_commands[name] = def
2015-09-17 20:51:25 +02:00
end
irc.register_bot_command("help", {
2015-09-17 20:51:25 +02:00
params = "<command>",
description = "Get help about a command",
func = function(_, args)
2015-09-17 20:51:25 +02:00
if args == "" then
local cmdlist = { }
for name in pairs(irc.bot_commands) do
cmdlist[#cmdlist+1] = name
end
return true, "Available commands: "..table.concat(cmdlist, ", ")
.." -- Use 'help <command name>' to get"
.." help about a specific command."
2015-09-17 20:51:25 +02:00
end
local cmd = irc.bot_commands[args]
if not cmd then
2017-01-20 03:01:28 +01:00
return false, "Unknown command '"..args.."'."
2015-09-17 20:51:25 +02:00
end
return true, ("Usage: %s%s %s -- %s"):format(
irc.config.command_prefix or "",
2015-09-17 20:51:25 +02:00
args,
cmd.params or "<no parameters>",
cmd.description or "<no description>")
end
})
irc.register_bot_command("list", {
2015-09-17 20:51:25 +02:00
params = "",
description = "List available commands.",
func = function()
return false, "The `list` command has been merged into `help`."
.." Use `help` with no arguments to get a list."
2015-09-17 20:51:25 +02:00
end
})
irc.register_bot_command("whereis", {
2015-09-17 20:51:25 +02:00
params = "<player>",
description = "Tell the location of <player>",
func = function(_, args)
2015-09-17 20:51:25 +02:00
if args == "" then
return false, "Player name required."
end
local player = minetest.get_player_by_name(args)
if not player then
return false, "There is no player named '"..args.."'"
end
local fmt = "Player %s is at (%.2f,%.2f,%.2f)"
local pos = player:get_pos()
2015-09-17 20:51:25 +02:00
return true, fmt:format(args, pos.x, pos.y, pos.z)
end
})
local starttime = os.time()
irc.register_bot_command("uptime", {
2015-09-17 20:51:25 +02:00
description = "Tell how much time the server has been up",
func = function()
2015-09-17 20:51:25 +02:00
local cur_time = os.time()
local diff = os.difftime(cur_time, starttime)
local fmt = "Server has been running for %d:%02d:%02d"
return true, fmt:format(
math.floor(diff / 60 / 60),
math.floor(diff / 60) % 60,
math.floor(diff) % 60
)
end
})
irc.register_bot_command("players", {
2015-09-17 20:51:25 +02:00
description = "List the players on the server",
func = function()
2015-09-17 20:51:25 +02:00
local players = minetest.get_connected_players()
local names = {}
for _, player in pairs(players) do
table.insert(names, player:get_player_name())
end
return true, "Connected players: "
..table.concat(names, ", ")
end
})