Update README.md
parent
ad129c6828
commit
9b4c4aba9a
|
@ -21,5 +21,4 @@ $RECYCLE.BIN/
|
|||
|
||||
# Minetest stuff
|
||||
debug.txt
|
||||
mods/irc/irc/*
|
||||
mods/irc/config.lua
|
||||
mods/irc/*
|
||||
|
|
13
README.md
13
README.md
|
@ -14,7 +14,7 @@ Mod | Summary
|
|||
3d_armor | Craftable and wearable armour. |
|
||||
_misc | Contains rules, commands and other stuff. | Edited frequently
|
||||
areas | Area protecting mod. |
|
||||
arrow_signs | Adds arrow signs. | **Experimental** - old signs might need replacing
|
||||
arrow_signs | Adds arrow signs. | Old signs might need replacing
|
||||
bitchange | A money mod, mostly rewritten for compatibility issues. | You can convert your old money over still
|
||||
boost_cart | Improved version of the original cart mod. | **Experimental** - can cause considerable lag
|
||||
bucket | The one, the only, bucket mod. |
|
||||
|
@ -35,20 +35,21 @@ gloopblocks | Some more blocks and evil tools. | Tools to be removed/rep
|
|||
home_gui | Set your home via the inventory. |
|
||||
homedecor | Makes a house a home. | **Many crafts don't work** - feel free to submit pull requests if you want to be able to craft certain blocks from this mod. (We don't use mods such as technic and building_blocks - this causes the crafts to not work)
|
||||
industry_pack | Rubber trees ect. | **Extremely Experiemental** If the whole server ends up crashing whenever you join - this is the reason. Needs to be replaced with another similar mod sometime.
|
||||
inventory_plus | Tool used by other mods to add buttons to the inventory.
|
||||
itemframes | Showcase your items on a frame or pedestal.
|
||||
locked_sign | A locked sign which only the placer can edit. | **Experimental** - old signs might need replacing
|
||||
inventory_plus | Tool used by other mods to add buttons to the inventory. |
|
||||
itemframes | Showcase your items on a frame or pedestal. |
|
||||
irc | Connects the server to an IRC channel |
|
||||
locked_sign | A locked sign which only the placer can edit. | Old signs might need replacing
|
||||
lrfurn | Living room furniture.
|
||||
markers | Helpful way to protect areas using the areas mod. | Occasional crashes
|
||||
memorandum | Write on paper and it will stay on the paper when you pick it back up again.
|
||||
money | Old money mod. | **Not to be used anymore**
|
||||
more_chests | More chests. | **Experimental** Old wifi chests have some issues
|
||||
more_chests | More chests. | Old wifi chests have some issues
|
||||
moreblocks | More blocks. |
|
||||
moreores | More ores. |
|
||||
replacer | A tool to help you replace items. |
|
||||
screwdriver | Screwdrivers can turn blocks at different directions. |
|
||||
shields | Equip this and be cool. |
|
||||
skins | Change what your character looks like. | Takes a long time to load all the textures. Skin choice to be reduced soon.
|
||||
simple_skins | Change your characters skin. |
|
||||
stairs | Stairs and slab blocks. Stairsplus can be found in the moreblocks mod.
|
||||
streets | Blocks to make modern city roads with lighting and all. | Mod, not a modpack
|
||||
travelnet | Teleporting! |
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
IRC Mod API
|
||||
===========
|
||||
|
||||
This file documents the Minetest IRC mod API.
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
In order to allow your mod to interface with this mod, you must add `irc`
|
||||
to your mod's `depends.txt` file.
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
irc:say([name,] message)
|
||||
Sends <message> to either the channel (if <name> is nil or not specified),
|
||||
or to the given user (if <name> is specified).
|
||||
Example:
|
||||
irc:say("Hello, Channel!")
|
||||
irc:say("john1234", "How are you?")
|
||||
|
||||
irc:register_bot_command(name, cmdDef)
|
||||
Registers a new bot command named <name>.
|
||||
When an user sends a private message to the bot with the command name, the
|
||||
command's function is called.
|
||||
Here's the format of a command definition (<cmdDef>):
|
||||
cmdDef = {
|
||||
params = "<param1> ...", -- A description of the command's parameters
|
||||
description = "My command", -- A description of what the command does. (one-liner)
|
||||
func = function(user, args)
|
||||
-- This function gets called when the command is invoked.
|
||||
-- <user> is a user table for the user that ran the command.
|
||||
-- (See the LuaIRC documentation for details.)
|
||||
-- It contains fields such as 'nick' and 'ident'
|
||||
-- <args> is a string of arguments to the command (may be "")
|
||||
-- This function should return boolean success and a message.
|
||||
end,
|
||||
};
|
||||
Example:
|
||||
irc:register_bot_command("hello", {
|
||||
params = "",
|
||||
description = "Greet user",
|
||||
func = function(user, param)
|
||||
return true, "Hello!"
|
||||
end,
|
||||
});
|
||||
|
||||
irc.joined_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 irc.joined_players["joe"] then
|
||||
-- Joe is talking on IRC
|
||||
end
|
||||
|
||||
irc:register_hook(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 HOOKS below
|
||||
for more information
|
||||
Example:
|
||||
irc:register_hook("OnSend", function(line)
|
||||
print("SEND: "..line)
|
||||
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"})
|
||||
assert(s == "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 might crash the server!
|
||||
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
The `irc:register_hook` function can register functions to be called
|
||||
when some events happen. The events supported are the same as the LuaIRC
|
||||
ones with a few added (mostly for internal use).
|
||||
See src/LuaIRC/doc/irc.luadoc for more information.
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
IRC Mod for Minetest
|
||||
====================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
This mod is just a glue between IRC and Minetest. It provides 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
|
||||
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
Quick one line install for linux:
|
||||
|
||||
cd <Mod directory> && git clone https://github.com/kaeza/minetest-irc.git irc && cd irc && git submodule update --init
|
||||
|
||||
Please change `<Mod directory>` to fit your installation of minetest.
|
||||
For more information, see [the wiki](http://wiki.minetest.net/Installing_mods).
|
||||
|
||||
The Minetest IRC mod uses submodules, therefore you will have to run
|
||||
`git submodule init` when first installing the mod, and `git submodule update`
|
||||
every time that a submodule is updated. These steps can be combined as
|
||||
`git submodule update --init`.
|
||||
|
||||
The Minetest IRC mod also requires LuaSocket. This can be installed using your
|
||||
package manager on many distributions, for example on Arch Linux:
|
||||
|
||||
# pacman -S lua51-socket
|
||||
|
||||
|
||||
Settings
|
||||
--------
|
||||
All settings are changed in `minetest.conf`. If any of these settings
|
||||
are not set, the default value is used.
|
||||
|
||||
* `irc.server` (string, default "irc.freenode.net")
|
||||
This is the IRC server the mod connects to.
|
||||
|
||||
* `irc.channel` (string, default "##mt-irc-mod")
|
||||
The IRC channel to join.
|
||||
|
||||
* `irc.interval` (number, default 2.0)
|
||||
This prevents the server from flooding. It should be at
|
||||
least 2.0 but can be higher. After four messages this much
|
||||
time must pass between folowing messages.
|
||||
|
||||
* `irc.nick` (string, default "MT-FFFFFF")
|
||||
Nickname used as "proxy" for the in-game chat.
|
||||
'F' stands for a random base-16 number.
|
||||
|
||||
* `irc.password` (string, default "")
|
||||
Password to use when connecting to the server.
|
||||
|
||||
* `irc.NSPass` (string, default nil)
|
||||
NickServ password. Don't use this if you use SASL authentication.
|
||||
|
||||
* `irc.sasl.pass` (string, default nil)
|
||||
SASL password, same as nickserv password.
|
||||
You should use this instead of NickServ authentication
|
||||
if the server supports it.
|
||||
|
||||
* `irc.sasl.user` (string, default `irc.nick`)
|
||||
The SASL username. This should normaly be set to your main NickServ account name.
|
||||
|
||||
* `irc.debug` (boolean, default false)
|
||||
Whether to output debug information.
|
||||
|
||||
* `irc.disable_auto_connect` (boolean, default false)
|
||||
If false, the bot is connected by default. If true, a player with
|
||||
the 'irc_admin' privilege has to use the /irc_connect command to
|
||||
connect to the server.
|
||||
|
||||
* `irc.disable_auto_join` (boolean, default false)
|
||||
If false, players join the channel automatically upon entering the
|
||||
game. If true, each user must manually use the /join command to
|
||||
join the channel. In any case, the players may use the /part
|
||||
command to opt-out of being in the channel.
|
||||
|
||||
* `irc.send_join_part` (boolean, default true)
|
||||
Determines whether to send player join and part messages to the channel.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Once the game is connected to the IRC channel, chatting using the 'T' or
|
||||
F10 hotkeys will send the messages to the channel, and will be visible
|
||||
by anyone. Also, when someone sends a message to the channel, that text
|
||||
will be visible in-game.
|
||||
|
||||
Messages that begin with `[off]` from in-game or IRC are not sent to the
|
||||
other side.
|
||||
|
||||
This mod also adds a few chat commands:
|
||||
|
||||
* `/irc_msg <nick> <message>`
|
||||
Sends a private message to a IRC user.
|
||||
|
||||
* `/join`
|
||||
Join the IRC chat.
|
||||
|
||||
* `/part`
|
||||
Part the IRC chat.
|
||||
|
||||
* `/irc_connect`
|
||||
Connect the bot manually to the IRC network.
|
||||
|
||||
* `/irc_disconnect`
|
||||
Disconnect the bot manually from the IRC network (this does not
|
||||
shutdown the game).
|
||||
|
||||
* `/irc_reconnect`
|
||||
Equivilant to `/irc_disconnect` followed by `/irc_connect`.
|
||||
|
||||
You can also send private messages from IRC to in-game players.
|
||||
|
||||
To do it, you must send a private message to the bot (set with
|
||||
the `irc.nick` option above), in the following format:
|
||||
|
||||
@playername message
|
||||
|
||||
For example, if there's a player named `mtuser`, you can send him/her
|
||||
a private message from IRC with:
|
||||
|
||||
/msg server_nick @mtuser Hello!
|
||||
|
||||
To avoid possible misunderstandings (since all in-game players use the
|
||||
same IRC user to converse with you), the "proxy" user will reject any
|
||||
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 `!list` 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:
|
||||
|
||||
0gb.us, ShadowNinja, 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
|
||||
-------
|
||||
|
||||
(C) 2012-2013 Diego Martínez <kaeza@users.sf.net>
|
||||
|
||||
See LICENSE.txt for licensing information.
|
||||
|
||||
The files in the irc directory are part of the LuaIRC project.
|
||||
See irc/LICENSE.txt for licensing information.
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
|
||||
irc.bot_commands = {}
|
||||
|
||||
function irc:check_botcmd(msg)
|
||||
local prefix = irc.config.command_prefix
|
||||
local nick = irc.conn.nick: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(msg, text:sub(#nick + 3))
|
||||
return true
|
||||
-- Then check for the configured prefix
|
||||
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 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
|
||||
irc:reply("User '"..player_to.."' is not in the game.")
|
||||
return
|
||||
elseif not irc.joined_players[player_to] then
|
||||
irc:reply("User '"..player_to.."' is not using IRC.")
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(player_to,
|
||||
"PM from "..msg.user.nick.."@IRC: "..message, false)
|
||||
irc:reply("Message sent!")
|
||||
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
|
||||
|
||||
if not self.bot_commands[cmd] then
|
||||
self:reply("Unknown command '"..cmd.."'. Try 'list'."
|
||||
.." Or use @playername <message> to send a private message")
|
||||
return
|
||||
end
|
||||
|
||||
local success, message = self.bot_commands[cmd].func(msg.user, args)
|
||||
if message then
|
||||
self:reply(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc:register_bot_command(name, def)
|
||||
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
|
||||
self.bot_commands[name] = def
|
||||
end
|
||||
|
||||
|
||||
irc:register_bot_command("help", {
|
||||
params = "<command>",
|
||||
description = "Get help about a command",
|
||||
func = function(user, args)
|
||||
if args == "" then
|
||||
return false, "No command name specified. Use 'list' for a list of commands."
|
||||
end
|
||||
|
||||
local cmd = irc.bot_commands[args]
|
||||
if not cmd then
|
||||
return false, "Unknown command '"..cmdname.."'."
|
||||
end
|
||||
|
||||
return true, ("Usage: %c%s %s -- %s"):format(
|
||||
irc.config.command_prefix,
|
||||
args,
|
||||
cmd.params or "<no parameters>",
|
||||
cmd.description or "<no description>")
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
irc:register_bot_command("list", {
|
||||
params = "",
|
||||
description = "List available commands.",
|
||||
func = function(user, args)
|
||||
local cmdlist = "Available commands: "
|
||||
for name, cmd in pairs(irc.bot_commands) do
|
||||
cmdlist = cmdlist..name..", "
|
||||
end
|
||||
return true, cmdlist.." -- Use 'help <command name>' to get"
|
||||
.." help about a specific command."
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
irc:register_bot_command("whereis", {
|
||||
params = "<player>",
|
||||
description = "Tell the location of <player>",
|
||||
func = function(user, args)
|
||||
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:getpos()
|
||||
return true, fmt:format(args, pos.x, pos.y, pos.z)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local starttime = os.time()
|
||||
irc:register_bot_command("uptime", {
|
||||
description = "Tell how much time the server has been up",
|
||||
func = function(user, args)
|
||||
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", {
|
||||
description = "List the players on the server",
|
||||
func = function(user, args)
|
||||
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
|
||||
})
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
if irc.connected and irc.config.send_join_part then
|
||||
irc:say("*** "..name.." joined the game")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
if irc.connected and irc.config.send_join_part then
|
||||
irc:say("*** "..name.." left the game")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
if not irc.connected
|
||||
or message:sub(1, 1) == "/"
|
||||
or message:sub(1, 5) == "[off]"
|
||||
or not irc.joined_players[name]
|
||||
or (not minetest.check_player_privs(name, {shout=true})) then
|
||||
return
|
||||
end
|
||||
local nl = message:find("\n", 1, true)
|
||||
if nl then
|
||||
message = message:sub(1, nl - 1)
|
||||
end
|
||||
irc:say(irc:playerMessage(name, message))
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
irc:disconnect("Game shutting down.")
|
||||
end)
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
-- Note: This file does NOT conatin every chat command, only general ones.
|
||||
-- Feature-specific commands (like /join) are in their own files.
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_msg", {
|
||||
params = "<name> <message>",
|
||||
description = "Send a private message to an IRC user",
|
||||
privs = {shout=true},
|
||||
func = function(name, param)
|
||||
if not irc.connected then
|
||||
minetest.chat_send_player(name, "Not connected to IRC. Use /irc_connect to connect.")
|
||||
return
|
||||
end
|
||||
local found, _, toname, message = param:find("^([^%s]+)%s(.+)")
|
||||
if not found then
|
||||
minetest.chat_send_player(name, "Invalid usage, see /help irc_msg.")
|
||||
return
|
||||
end
|
||||
local toname_l = toname:lower()
|
||||
local validNick = false
|
||||
for nick, user in pairs(irc.conn.channels[irc.config.channel].users) do
|
||||
if nick:lower() == toname_l then
|
||||
validNick = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if toname_l:find("serv$") or toname_l:find("bot$") then
|
||||
validNick = false
|
||||
end
|
||||
if not validNick then
|
||||
minetest.chat_send_player(name,
|
||||
"You can not message that user. (Hint: They have to be in the channel)")
|
||||
return
|
||||
end
|
||||
irc:say(toname, irc:playerMessage(name, message))
|
||||
minetest.chat_send_player(name, "Message sent!")
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_names", {
|
||||
params = "",
|
||||
description = "List the users in IRC.",
|
||||
func = function(name, params)
|
||||
local users = { }
|
||||
for k, v in pairs(irc.conn.channels[irc.config.channel].users) do
|
||||
table.insert(users, k)
|
||||
end
|
||||
minetest.chat_send_player(name, "Users in IRC: "..table.concat(users, ", "))
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_connect", {
|
||||
description = "Connect to the IRC server.",
|
||||
privs = {irc_admin=true},
|
||||
func = function(name, param)
|
||||
if irc.connected then
|
||||
minetest.chat_send_player(name, "You are already connected to IRC.")
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(name, "IRC: Connecting...")
|
||||
irc:connect()
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_disconnect", {
|
||||
params = "[message]",
|
||||
description = "Disconnect from the IRC server.",
|
||||
privs = {irc_admin=true},
|
||||
func = function(name, param)
|
||||
if not irc.connected then
|
||||
minetest.chat_send_player(name, "You are not connected to IRC.")
|
||||
return
|
||||
end
|
||||
if params == "" then
|
||||
params = "Manual disconnect by "..name
|
||||
end
|
||||
irc:disconnect(param)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_reconnect", {
|
||||
description = "Reconnect to the IRC server.",
|
||||
privs = {irc_admin=true},
|
||||
func = function(name, param)
|
||||
if not irc.connected then
|
||||
minetest.chat_send_player(name, "You are not connected to IRC.")
|
||||
return
|
||||
end
|
||||
irc:disconnect("Reconnecting...")
|
||||
irc:connect()
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("irc_quote", {
|
||||
params = "<command>",
|
||||
description = "Send a raw command to the IRC server.",
|
||||
privs = {irc_admin=true},
|
||||
func = function(name, param)
|
||||
if not irc.connected then
|
||||
minetest.chat_send_player(name, "You are not connected to IRC.")
|
||||
return
|
||||
end
|
||||
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, ...)
|
||||
irc:say(("* %s %s"):format(name, param))
|
||||
end
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
-- MIME is part of LuaSocket
|
||||
local b64e = require("mime").b64
|
||||
|
||||
irc.hooks = {}
|
||||
irc.registered_hooks = {}
|
||||
|
||||
|
||||
-- TODO: Add proper conversion from CP1252 to UTF-8.
|
||||
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
|
||||
|
||||
|
||||
function irc:doHook(conn)
|
||||
for name, hook in pairs(self.registered_hooks) do
|
||||
for _, func in pairs(hook) do
|
||||
conn:hook(name, func)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc:register_hook(name, func)
|
||||
self.registered_hooks[name] = self.registered_hooks[name] or {}
|
||||
table.insert(self.registered_hooks[name], func)
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.raw(line)
|
||||
if irc.config.debug then
|
||||
print("RECV: "..line)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.send(line)
|
||||
if irc.config.debug then
|
||||
print("SEND: "..line)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.chat(msg)
|
||||
local channel, text = msg.args[1], msg.args[2]
|
||||
if text:sub(1, 1) == string.char(1) then
|
||||
irc.conn:invoke("OnCTCP", msg)
|
||||
return
|
||||
end
|
||||
|
||||
if channel == irc.conn.nick then
|
||||
irc.last_from = msg.user.nick
|
||||
irc.conn:invoke("PrivateMessage", msg)
|
||||
else
|
||||
irc.last_from = channel
|
||||
irc.conn:invoke("OnChannelChat", msg)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function get_core_version()
|
||||
local status = minetest.get_server_status()
|
||||
local start_pos = select(2, status:find("version=", 1, true))
|
||||
local end_pos = status:find(",", start_pos, true)
|
||||
return status:sub(start_pos + 1, end_pos - 1)
|
||||
end
|
||||
|
||||
|
||||
function 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)
|
||||
irc:queue(irc.msgs.notice(msg.user.nick,
|
||||
("\1%s %s\1"):format(command, s)))
|
||||
end
|
||||
|
||||
if command == "ACTION" and msg.args[1] == irc.config.channel then
|
||||
local action = text:sub(8, -1)
|
||||
irc:sendLocal(("* %s@IRC %s"):format(msg.user.nick, action))
|
||||
elseif command == "VERSION" then
|
||||
reply(("Minetest version %s, IRC mod version %s.")
|
||||
:format(get_core_version(), irc.version))
|
||||
elseif command == "PING" then
|
||||
reply(args[2])
|
||||
elseif command == "TIME" then
|
||||
reply(os.date())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.channelChat(msg)
|
||||
local text = normalize(msg.args[2])
|
||||
|
||||
-- Support multiple servers in a channel better by converting:
|
||||
-- "<server@IRC> <player> message" into "<player@server> message"
|
||||
-- "<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"
|
||||
local foundchat, _, chatnick, chatmessage =
|
||||
text:find("^<([^>]+)> (.*)$")
|
||||
local foundjoin, _, joinnick =
|
||||
text:find("^%*%*%* ([^%s]+) joined the game$")
|
||||
local foundleave, _, leavenick =
|
||||
text:find("^%*%*%* ([^%s]+) left the game$")
|
||||
local foundaction, _, actionnick, actionmessage =
|
||||
text:find("^%* ([^%s]+) (.*)$")
|
||||
|
||||
irc:check_botcmd(msg)
|
||||
|
||||
if text:sub(1, 5) == "[off]" then
|
||||
return
|
||||
elseif foundchat then
|
||||
irc:sendLocal(("<%s@%s> %s")
|
||||
:format(chatnick, msg.user.nick, chatmessage))
|
||||
elseif foundjoin then
|
||||
irc:sendLocal(("*** %s joined %s")
|
||||
:format(joinnick, msg.user.nick))
|
||||
elseif foundleave then
|
||||
irc:sendLocal(("*** %s left %s")
|
||||
:format(leavenick, msg.user.nick))
|
||||
elseif foundaction then
|
||||
irc:sendLocal(("* %s@%s %s")
|
||||
:format(actionnick, msg.user.nick, actionmessage))
|
||||
else
|
||||
irc:sendLocal(("<%s@IRC> %s"):format(msg.user.nick, text))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.pm(msg)
|
||||
-- Trim prefix if it is found
|
||||
local text = msg.args[2]
|
||||
local prefix = irc.config.command_prefix
|
||||
if prefix and text:sub(1, #prefix) == prefix then
|
||||
text = text:sub(#prefix + 1)
|
||||
end
|
||||
irc:bot_command(msg, text)
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.kick(channel, target, prefix, reason)
|
||||
if target == irc.conn.nick then
|
||||
minetest.chat_send_all("IRC: kicked from "..channel.." by "..prefix.nick..".")
|
||||
irc:disconnect("Kicked")
|
||||
else
|
||||
irc:sendLocal(("-!- %s was kicked from %s by %s [%s]")
|
||||
:format(target, channel, prefix.nick, reason))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.notice(user, target, message)
|
||||
if user.nick and target == irc.config.channel then
|
||||
irc:sendLocal("-"..user.nick.."@IRC- "..message)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.mode(user, target, modes, ...)
|
||||
local by = ""
|
||||
if user.nick then
|
||||
by = " by "..user.nick
|
||||
end
|
||||
local options = ""
|
||||
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
|
||||
|
||||
|
||||
function irc.hooks.nick(user, newNick)
|
||||
irc:sendLocal(("-!- %s is now known as %s")
|
||||
:format(user.nick, newNick))
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.join(user, channel)
|
||||
irc:sendLocal(("-!- %s joined %s")
|
||||
:format(user.nick, channel))
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.part(user, channel, reason)
|
||||
reason = reason or ""
|
||||
irc:sendLocal(("-!- %s has left %s [%s]")
|
||||
:format(user.nick, channel, reason))
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.quit(user, reason)
|
||||
irc:sendLocal(("-!- %s has quit [%s]")
|
||||
:format(user.nick, reason))
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.disconnect(message, isError)
|
||||
irc.connected = false
|
||||
if isError then
|
||||
minetest.log("error", "IRC: Error: Disconnected, reconnecting in one minute.")
|
||||
minetest.chat_send_all("IRC: Error: Disconnected, reconnecting in one minute.")
|
||||
minetest.after(60, irc.connect, irc)
|
||||
else
|
||||
minetest.log("action", "IRC: Disconnected.")
|
||||
minetest.chat_send_all("IRC: Disconnected.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc.hooks.preregister(conn)
|
||||
if not (irc.config["sasl.user"] and irc.config["sasl.pass"]) then return end
|
||||
local authString = b64e(
|
||||
("%s\x00%s\x00%s"):format(
|
||||
irc.config["sasl.user"],
|
||||
irc.config["sasl.user"],
|
||||
irc.config["sasl.pass"])
|
||||
)
|
||||
conn:send("CAP REQ sasl")
|
||||
conn:send("AUTHENTICATE PLAIN")
|
||||
conn:send("AUTHENTICATE "..authString)
|
||||
--LuaIRC will send CAP END
|
||||
end
|
||||
|
||||
|
||||
irc:register_hook("PreRegister", irc.hooks.preregister)
|
||||
irc:register_hook("OnRaw", irc.hooks.raw)
|
||||
irc:register_hook("OnSend", irc.hooks.send)
|
||||
irc:register_hook("DoPrivmsg", irc.hooks.chat)
|
||||
irc:register_hook("OnPart", irc.hooks.part)
|
||||
irc:register_hook("OnKick", irc.hooks.kick)
|
||||
irc:register_hook("OnJoin", irc.hooks.join)
|
||||
irc:register_hook("OnQuit", irc.hooks.quit)
|
||||
irc:register_hook("NickChange", irc.hooks.nick)
|
||||
irc:register_hook("OnCTCP", irc.hooks.ctcp)
|
||||
irc:register_hook("PrivateMessage", irc.hooks.pm)
|
||||
irc:register_hook("OnNotice", irc.hooks.notice)
|
||||
irc:register_hook("OnChannelChat", irc.hooks.channelChat)
|
||||
irc:register_hook("OnModeChange", irc.hooks.mode)
|
||||
irc:register_hook("OnDisconnect", irc.hooks.disconnect)
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
package.path =
|
||||
-- To find LuaIRC's init.lua
|
||||
modpath.."/?/init.lua;"
|
||||
-- For LuaIRC to find its files
|
||||
..modpath.."/?.lua;"
|
||||
..package.path
|
||||
|
||||
-- The build of Lua that Minetest comes with only looks for libraries under
|
||||
-- /usr/local/share and /usr/local/lib but LuaSocket is often installed under
|
||||
-- /usr/share and /usr/lib.
|
||||
if not jit and package.config:sub(1, 1) == "/" then
|
||||
package.path = package.path..
|
||||
";/usr/share/lua/5.1/?.lua"..
|
||||
";/usr/share/lua/5.1/?/init.lua"
|
||||
package.cpath = package.cpath..
|
||||
";/usr/lib/lua/5.1/?.so"
|
||||
end
|
||||
|
||||
irc = {
|
||||
version = "0.2.0",
|
||||
connected = false,
|
||||
cur_time = 0,
|
||||
message_buffer = {},
|
||||
recent_message_count = 0,
|
||||
joined_players = {},
|
||||
modpath = modpath,
|
||||
lib = require("irc"),
|
||||
}
|
||||
|
||||
-- Compatibility
|
||||
mt_irc = irc
|
||||
|
||||
dofile(modpath.."/config.lua")
|
||||
dofile(modpath.."/messages.lua")
|
||||
dofile(modpath.."/hooks.lua")
|
||||
dofile(modpath.."/callback.lua")
|
||||
dofile(modpath.."/chatcmds.lua")
|
||||
dofile(modpath.."/botcmds.lua")
|
||||
if irc.config.enable_player_part then
|
||||
dofile(modpath.."/player_part.lua")
|
||||
else
|
||||
setmetatable(irc.joined_players, {__index = function(index) return true end})
|
||||
end
|
||||
|
||||
minetest.register_privilege("irc_admin", {
|
||||
description = "Allow IRC administrative tasks to be performed.",
|
||||
give_to_singleplayer = true
|
||||
})
|
||||
|
||||
local stepnum = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime) return irc:step(dtime) end)
|
||||
|
||||
function irc:step(dtime)
|
||||
if stepnum == 3 then
|
||||
if self.config.auto_connect then
|
||||
self:connect()
|
||||
end
|
||||
end
|
||||
stepnum = stepnum + 1
|
||||
|
||||
if not self.connected then return end
|
||||
|
||||
-- Hooks will manage incoming messages and errors
|
||||
local good, err = xpcall(function() self.conn:think() end, debug.traceback)
|
||||
if not good then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc:connect()
|
||||
if self.connected then
|
||||
minetest.log("error", "IRC: Ignoring attempt to connect when already connected.")
|
||||
return
|
||||
end
|
||||
self.conn = irc.lib.new({
|
||||
nick = self.config.nick,
|
||||
username = "Minetest",
|
||||
realname = "Minetest",
|
||||
})
|
||||
self:doHook(self.conn)
|
||||
local good, message = pcall(function()
|
||||
self.conn:connect({
|
||||
host = self.config.server,
|
||||
port = self.config.port,
|
||||
password = self.config.password,
|
||||
timeout = self.config.timeout,
|
||||
secure = self.config.secure
|
||||
})
|
||||
end)
|
||||
|
||||
if not good then
|
||||
minetest.log("error", ("IRC: Connection error: %s: %s -- Reconnecting in ten minutes...")
|
||||
:format(self.config.server, message))
|
||||
minetest.after(600, function() self:connect() end)
|
||||
return
|
||||
end
|
||||
|
||||
if self.config.NSPass then
|
||||
self:say("NickServ", "IDENTIFY "..self.config.NSPass)
|
||||
end
|
||||
|
||||
self.conn:join(self.config.channel, self.config.key)
|
||||
self.connected = true
|
||||
minetest.log("action", "IRC: Connected!")
|
||||
minetest.chat_send_all("IRC: Connected!")
|
||||
end
|
||||
|
||||
|
||||
function irc:disconnect(message)
|
||||
if self.connected then
|
||||
--The OnDisconnect hook will clear self.connected and print a disconnect message
|
||||
self.conn:disconnect(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function irc:say(to, message)
|
||||
if not message then
|
||||
message = to
|
||||
to = self.config.channel
|
||||
end
|
||||
to = to or self.config.channel
|
||||
|
||||
self:queue(irc.msgs.privmsg(to, message))
|
||||
end
|
||||
|
||||
|
||||
function irc:reply(message)
|
||||
if not self.last_from then
|
||||
return
|
||||
end
|
||||
message = message:gsub("[\r\n%z]", " \\n ")
|
||||
self:say(self.last_from, message)
|
||||
end
|
||||
|
||||
function irc:send(msg)
|
||||
if not self.connected then return end
|
||||
self.conn:send(msg)
|
||||
end
|
||||
|
||||
function irc:queue(msg)
|
||||
if not self.connected then return end
|
||||
self.conn:queue(msg)
|
||||
end
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
irc.msgs = irc.lib.msgs
|
||||
|
||||
function irc:sendLocal(message)
|
||||
minetest.chat_send_all(message)
|
||||
end
|
||||
|
||||
function irc:playerMessage(name, message)
|
||||
return ("<%s> %s"):format(name, message)
|
||||
end
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
-- This file is licensed under the terms of the BSD 2-clause license.
|
||||
-- See LICENSE.txt for details.
|
||||
|
||||
|
||||
function irc:player_part(name)
|
||||
if not self.joined_players[name] then
|
||||
minetest.chat_send_player(name, "IRC: You are not in the channel.")
|
||||
return
|
||||
end
|
||||
self.joined_players[name] = nil
|
||||
minetest.chat_send_player(name, "IRC: You are now out of the channel.")
|
||||
end
|
||||
|
||||
function irc:player_join(name)
|
||||
if self.joined_players[name] then
|
||||
minetest.chat_send_player(name, "IRC: You are already in the channel.")
|
||||
return
|
||||
end
|
||||
self.joined_players[name] = true
|
||||
minetest.chat_send_player(name, "IRC: You are now in the channel.")
|
||||
end
|
||||
|
||||
|
||||
minetest.register_chatcommand("join", {
|
||||
description = "Join the IRC channel",
|
||||
privs = {shout=true},
|
||||
func = function(name, param)
|
||||
irc:player_join(name)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("part", {
|
||||
description = "Part the IRC channel",
|
||||
privs = {shout=true},
|
||||
func = function(name, param)
|
||||
irc:player_part(name)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("who", {
|
||||
description = "Tell who is currently on the channel",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
local s = ""
|
||||
for name, _ in pairs(irc.joined_players) do
|
||||
s = s..", "..name
|
||||
end
|
||||
minetest.chat_send_player(name, "Players On Channel:"..s)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
irc.joined_players[name] = irc.config.auto_join
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
irc.joined_players[name] = nil
|
||||
end)
|
||||
|
||||
function irc:sendLocal(message)
|
||||
for name, _ in pairs(self.joined_players) do
|
||||
minetest.chat_send_player(name, message)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue