diff --git a/mods/irc/.gitignore b/mods/irc/.gitignore deleted file mode 100755 index 5236e1e4..00000000 --- a/mods/irc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*~ - diff --git a/mods/irc/API.md b/mods/irc/API.md deleted file mode 100755 index e518f22b..00000000 --- a/mods/irc/API.md +++ /dev/null @@ -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 to either the channel (if is nil or not specified), -or to the given user (if 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 . - 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 = { - params = " ...", -- 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. - -- 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' - -- 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. is the name - of the event, and 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 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. - diff --git a/mods/irc/LICENSE.txt b/mods/irc/LICENSE.txt deleted file mode 100755 index b1840321..00000000 --- a/mods/irc/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013, Diego Martinez (kaeza) -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/mods/irc/README.md b/mods/irc/README.md deleted file mode 100755 index f7042cfe..00000000 --- a/mods/irc/README.md +++ /dev/null @@ -1,165 +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 https://forum.minetest.net/viewtopic.php?f=11&t=3905 - - -Installing ----------- - -Quick one line install for Linux: - - cd && git clone --recursive https://github.com/kaeza/minetest-irc.git irc - -Please change `` to fit your installation of Minetest. -For more information, see [the wiki](http://wiki.minetest.net/Installing_mods). - -The IRC mod's git repository uses submodules, therefore you will have to run -`git submodule init` when first installing the mod (unless you used -`--recursive` as above), and `git submodule update` every time that a submodule -is updated. These steps can be combined into `git submodule update --init`. - -You'll need to install LuaSocket. You can do so with your package manager on -many distributions, for example: - - # # On Arch Linux: - # pacman -S lua51-socket - # # On Debian/Ubuntu: - # apt-get install lua-socket - -You will also need to add IRC to your trusted mods if you haven't disabled mod -security. Here's an example configuration line: - - secure.trusted_mods = irc - - -Settings --------- -All settings are changed in `minetest.conf`. If any of these settings -are not set, the default value is used. - - * `irc.server` (string) - The address of the IRC server to connect to. - - * `irc.channel` (string) - 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) - Nickname the server uses when it connects to IRC. - - * `irc.password` (string, default nil) - Password to use when connecting to the server. - - * `irc.NSPass` (string, default nil) - NickServ password. Don't set 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 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 in-game will send -messages to the channel, and will be visible by anyone. Also, messages sent -to the channel 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 ` - 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 so, 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 ` 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 -------- - -Copyright © 2012-2013 Diego Martínez - -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. - diff --git a/mods/irc/botcmds.lua b/mods/irc/botcmds.lua deleted file mode 100755 index 19858237..00000000 --- a/mods/irc/botcmds.lua +++ /dev/null @@ -1,173 +0,0 @@ -local whereis_interval = 120 -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 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 = "", - 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 "", - cmd.description or "") - 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 ' to get" - .." help about a specific command." - end -}) - - -irc:register_bot_command("whereis", { - params = "", - description = "Tell the location of ", - 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 function say_where_is() - local fmt = "Player %s is at (%.2f,%.2f,%.2f)" - local pos = player:getpos() - minetest.log("action","IRC user ".. user.nick.."!"..user.username.."@"..user.host.." asked for position of player "..player:get_player_name()) - minetest.chat_send_player(player:get_player_name(),"IRC user ".. user.nick.."!"..user.username.."@"..user.host.." asked for your position") - return true, fmt:format(args, pos.x, pos.y, pos.z) - end - - if not action_timers.api.get_timer("whereis_" .. user.nick) then - action_timers.api.register_timer("whereis_" .. user.nick, whereis_interval) - return say_where_is() - else - local res = action_timers.api.do_action("whereis_" .. user.nick, say_where_is) - if tonumber(res) then - local answer = "Command used too often, retry in %d seconds." - return false,answer:format(math.floor(res)) - else - print(res) - return res - end - end - 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 -}) - diff --git a/mods/irc/callback.lua b/mods/irc/callback.lua deleted file mode 100755 index 0356f914..00000000 --- a/mods/irc/callback.lua +++ /dev/null @@ -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) - diff --git a/mods/irc/chatcmds.lua b/mods/irc/chatcmds.lua deleted file mode 100755 index b8ac4665..00000000 --- a/mods/irc/chatcmds.lua +++ /dev/null @@ -1,126 +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 = " ", - 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) - if not irc.connected then - minetest.chat_send_player(name, "Not connected to IRC. Use /irc_connect to connect.") - return - end - 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 = "", - 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 - diff --git a/mods/irc/config.lua b/mods/irc/config.lua deleted file mode 100755 index 52067537..00000000 --- a/mods/irc/config.lua +++ /dev/null @@ -1,52 +0,0 @@ --- This file is licensed under the terms of the BSD 2-clause license. --- See LICENSE.txt for details. - - -irc.config = {} - -local function setting(stype, name, default, required) - local value - if stype == "bool" then - value = minetest.setting_getbool("irc."..name) - elseif stype == "string" then - value = minetest.setting_get("irc."..name) - elseif stype == "number" then - value = tonumber(minetest.setting_get("irc."..name)) - end - if value == nil then - if required then - error("Required configuration option irc.".. - name.." missing.") - end - value = default - end - irc.config[name] = value -end - -------------------------- --- BASIC USER SETTINGS -- -------------------------- - -setting("string", "nick", nil, true) -- Nickname -setting("string", "server", nil, true) -- Server address to connect to -setting("number", "port", 6667) -- Server port to connect to -setting("string", "NSPass") -- NickServ password -setting("string", "sasl.user", irc.config.nick) -- SASL username -setting("string", "sasl.pass") -- SASL password -setting("string", "channel", nil, true) -- Channel to join -setting("string", "key") -- Key for the channel -setting("bool", "send_join_part", true) -- Whether to send player join and part messages to the channel - ------------------------ --- ADVANCED SETTINGS -- ------------------------ - -setting("string", "password") -- Server password -setting("bool", "secure", false) -- Enable a TLS connection, requires LuaSEC -setting("number", "timeout", 60) -- Underlying socket timeout in seconds. -setting("string", "command_prefix") -- Prefix to use for bot commands -setting("bool", "debug", false) -- Enable debug output -setting("bool", "enable_player_part", true) -- Whether to enable players joining and parting the channel -setting("bool", "auto_join", true) -- Whether to automatically show players in the channel when they join -setting("bool", "auto_connect", true) -- Whether to automatically connect to the server on mod load - diff --git a/mods/irc/core.so b/mods/irc/core.so deleted file mode 100755 index 41fb027a..00000000 Binary files a/mods/irc/core.so and /dev/null differ diff --git a/mods/irc/depends.txt b/mods/irc/depends.txt deleted file mode 100755 index d06a3848..00000000 --- a/mods/irc/depends.txt +++ /dev/null @@ -1 +0,0 @@ -action_timers diff --git a/mods/irc/hooks.lua b/mods/irc/hooks.lua deleted file mode 100755 index c27ba5d9..00000000 --- a/mods/irc/hooks.lua +++ /dev/null @@ -1,276 +0,0 @@ --- This file is licensed under the terms of the BSD 2-clause license. --- See LICENSE.txt for details. - -local ie = ... - --- MIME is part of LuaSocket -local b64e = ie.require("mime").b64 - -irc.hooks = {} -irc.registered_hooks = {} - -local accent_chars = { {"À", "A"},{"Á", "A"},{"Â", "A"},{"Ã", "A"},{"Ä", "A"},{"Å", "A"},{"Ç", "C"},{"È", "E"},{"É", "E"},{"Ê", "E"}, - {"Ë", "E"},{"�", "I"},{"Í", "I"},{"�", "I"},{"Ï", "I"},{"Ñ", "N"},{"Ò", "O"},{"Ó", "O"},{"Ô", "O"},{"Õ", "O"}, - {"Ö", "O"},{"�", "O"},{"Ù", "U"},{"Ú", "U"},{"Û", "U"},{"Ü", "U"},{"�", "Y"},{"à", "a"},{"á", "a"},{"â", "a"}, - {"ã", "a"},{"ä", "a"},{"å", "a"},{"ç", "c"},{"è", "e"},{"é", "e"},{"ê", "e"},{"ë", "e"},{"ì", "i"},{"í", "i"}, - {"î", "i"},{"ï", "i"},{"ñ", "n"},{"ò", "o"},{"ó", "o"},{"ô", "o"},{"õ", "o"},{"ö", "o"},{"�", "o"},{"ù", "u"}, - {"ú", "u"},{"û", "u"},{"ü", "u"},{"�", "Y"} - } - -local function subaccent(text) - for _, c in pairs(accent_chars) do - text = text:gsub(c[1], c[2]) - end - return text -end - --- 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,]*", "") - text = subaccent(text) - 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]) - - irc:check_botcmd(msg) - - -- Don't let a user impersonate someone else by using the nick "IRC" - if msg.user.nick == "IRC" then - irc:sendLocal(" "..text) - return - end - - -- Support multiple servers in a channel better by converting: - -- " message" into " message" - -- " *** player joined/left the game" into "*** player joined/left server" - -- and " * 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]+) (.*)$") - - 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) - conn: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) - diff --git a/mods/irc/init.lua b/mods/irc/init.lua deleted file mode 100755 index 99d38f1e..00000000 --- a/mods/irc/init.lua +++ /dev/null @@ -1,169 +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()) - --- Handle mod security if needed -local ie, req_ie = _G, minetest.request_insecure_environment -if req_ie then ie = req_ie() end -if not ie then - error("The IRC mod requires access to insecure functions in order ".. - "to work. Please add the irc mod to your secure.trusted_mods ".. - "setting or disable the irc mod.") -end - -ie.package.path = - -- To find LuaIRC's init.lua - modpath.."/?/init.lua;" - -- For LuaIRC to find its files - ..modpath.."/?.lua;" - ..ie.package.path - ..";/usr/lib/*/lua/5.1/socket/*.so" - --- 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 rawget(_G, "jit") and package.config:sub(1, 1) == "/" then - ie.package.path = ie.package.path.. - ";/usr/share/lua/5.1/?.lua".. - ";/usr/share/lua/5.1/?/init.lua" - ie.package.path = ie.package.path.. - ";/usr/lib/lua/5.1/?.so" -end - --- Temporarily set require so that LuaIRC can access it -local old_require = require -require = ie.require -local lib = ie.require("irc") -require = old_require - -irc = { - version = "0.2.0", - connected = false, - cur_time = 0, - message_buffer = {}, - recent_message_count = 0, - joined_players = {}, - modpath = modpath, - lib = lib, -} - --- Compatibility -mt_irc = irc - -dofile(modpath.."/config.lua") -dofile(modpath.."/messages.lua") -loadfile(modpath.."/hooks.lua")(ie) -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 - diff --git a/mods/irc/irc/.gitignore b/mods/irc/irc/.gitignore deleted file mode 100755 index 3ad5d87a..00000000 --- a/mods/irc/irc/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/gh-pages/ -*~ - diff --git a/mods/irc/irc/.travis.yml b/mods/irc/irc/.travis.yml deleted file mode 100755 index f0720708..00000000 --- a/mods/irc/irc/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: lua - -notifications: - email: false - -env: - global: - - secure: "kFhU+DZjhq/KbDt0DIDWnlskXMa12miNelmhhy30fQGgVIdiibDGKMNGyLahWp8CnPu1DARb5AZWK2TDfARdnURT2pgcsG83M7bYIY6cR647BWjL7oAhJ6CYEzTWJTBjeUjpN/o4vIgfXSDR0c7vboDi7Xz8ilfrBujPL2Oi/og=" - -install: - - sudo apt-get -y update - - sudo apt-get -y install lua5.1 luadoc - -script: - - ./push-luadoc.sh diff --git a/mods/irc/irc/LICENSE.txt b/mods/irc/irc/LICENSE.txt deleted file mode 100755 index 0a68ca1f..00000000 --- a/mods/irc/irc/LICENSE.txt +++ /dev/null @@ -1,26 +0,0 @@ ---[[ - Lua IRC library - - Copyright (c) 2010 Jakob Ovrum - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE.]] - diff --git a/mods/irc/irc/README.markdown b/mods/irc/irc/README.markdown deleted file mode 100755 index 8cff1d22..00000000 --- a/mods/irc/irc/README.markdown +++ /dev/null @@ -1,19 +0,0 @@ -[![Build Status](https://travis-ci.org/JakobOvrum/LuaIRC.svg?branch=master)](https://travis-ci.org/JakobOvrum/LuaIRC) -LuaIRC -============ - -IRC client library for Lua. - -Dependencies -------------- - - * [LuaSocket](http://w3.impa.br/~diego/software/luasocket/) - -**Only required if you want to make use of the TLS support** - - * [LuaSec](http://www.inf.puc-rio.br/~brunoos/luasec/) - -Documentation -------------- -Documentation can be automatically generated by passing irc.luadoc (in doc/) to [LuaDoc](http://luadoc.luaforge.net/), or pre-generated documentation can be found in the 'gh-pages' branch, which can also be browsed [online](http://jakobovrum.github.com/LuaIRC/doc/modules/irc.html). - diff --git a/mods/irc/irc/asyncoperations.lua b/mods/irc/irc/asyncoperations.lua deleted file mode 100755 index 7531b284..00000000 --- a/mods/irc/irc/asyncoperations.lua +++ /dev/null @@ -1,92 +0,0 @@ -local msgs = require("irc.messages") - -local meta = {} - -function meta:send(msg, ...) - if type(msg) == "table" then - msg = msg:toRFC1459() - else - if select("#", ...) > 0 then - msg = msg:format(...) - end - end - self:invoke("OnSend", msg) - - local bytes, err = self.socket:send(msg .. "\r\n") - - if not bytes and err ~= "timeout" and err ~= "wantwrite" then - self:invoke("OnDisconnect", err, true) - self:shutdown() - error(err, errlevel) - end -end - -function meta:queue(msg) - table.insert(self.messageQueue, msg) -end - -local function verify(str, errLevel) - if str:find("^:") or str:find("%s%z") then - error(("malformed parameter '%s' to irc command"):format(str), errLevel) - end - - return str -end - -function meta:sendChat(target, msg) - -- Split the message into segments if it includes newlines. - for line in msg:gmatch("([^\r\n]+)") do - self:queue(msgs.privmsg(verify(target, 3), line)) - end -end - -function meta:sendNotice(target, msg) - -- Split the message into segments if it includes newlines. - for line in msg:gmatch("([^\r\n]+)") do - self:queue(msgs.notice(verify(target, 3), line)) - end -end - -function meta:join(channel, key) - self:queue(msgs.join( - verify(channel, 3), - key and verify(key, 3) or nil)) -end - -function meta:part(channel, reason) - channel = verify(channel, 3) - self:queue(msgs.part(channel, reason)) - if self.track_users then - self.channels[channel] = nil - end -end - -function meta:trackUsers(b) - self.track_users = b - if not b then - for k,v in pairs(self.channels) do - self.channels[k] = nil - end - end -end - -function meta:setMode(t) - local target = t.target or self.nick - local mode = "" - local add, rem = t.add, t.remove - - assert(add or rem, "table contains neither 'add' nor 'remove'") - - if add then - mode = table.concat{"+", verify(add, 3)} - end - - if rem then - mode = table.concat{mode, "-", verify(rem, 3)} - end - - self:queue(msgs.mode(verify(target, 3), mode)) -end - -return meta - diff --git a/mods/irc/irc/doc/irc.luadoc b/mods/irc/irc/doc/irc.luadoc deleted file mode 100755 index c33a0b19..00000000 --- a/mods/irc/irc/doc/irc.luadoc +++ /dev/null @@ -1,198 +0,0 @@ ---- LuaIRC is a low-level IRC library for Lua. --- All functions raise Lua exceptions on error. --- --- Use new to create a new Connection object.
--- Example:

--- ---require "irc"
---local sleep = require "socket".sleep
---
---local s = irc.new{nick = "example"}
---
---s:hook("OnChat", function(user, channel, message)
--- print(("[%s] %s: %s"):format(channel, user.nick, message))
---end)
---
---s:connect("irc.example.net")
---s:join("#example")
---
---while true do
--- s:think()
--- sleep(0.5)
---end
---
- -module "irc" - ---- Create a new Connection object. Use irc:connect to connect to a server. --- @param user Table with fields nick, username and realname. --- The nick field is required. --- --- @return Returns a new Connection object. --- @see Connection -function new(user) - ---- Hook a function to an event. --- @param name Name of event. --- @param id Unique tag. --- @param f Callback function. [defaults to id] --- @see Hooks -function irc:hook(name, id, f) - ---- Remove previous hooked callback. --- @param name Name of event. --- @param id Unique tag. -function irc:unhook(name, id) - ---- Connect irc to an IRC server. --- @param host Host address. --- @param port Server port. [default 6667] -function irc:connect(host, port) - --- @param table Table of connection details --- @see ConnectOptions -function irc:connect(table) - ---- Disconnect irc from the server. --- @param message Quit message. -function irc:disconnect(message) - ---- Handle incoming data for irc, and invoke previously hooked callbacks based on new server input. --- You should call this in some kind of main loop, or at least often enough to not time out. -function irc:think() - ---- Look up user info. --- @param nick Nick of user to query. --- @return Table with fields userinfo, node, channels and account. -function irc:whois(nick) - ---- Look up topic. --- Use this to invoke the hooks OnTopic and OnTopicInfo at any time. --- @param channel Channel to query. -function irc:topic(channel) - ---- Send a IRC message to the server. --- @param msg Message or raw line to send, excluding newline characters. --- @param ... Format parameters for msg, with string.format semantics. [optional] -function irc:send(msg, ...) - ---- Queue Message to be sent to the server. --- @param msg Message to be sent. -function irc:queue(msg) - ---- Send a message to a channel or user. --- @param target Nick or channel to send to. --- @param message Message text. -function irc:sendChat(target, message) - ---- Send a notice to a channel or user. --- @param target Nick or channel to send to. --- @param message Notice text. -function irc:sendNotice(target, message) - ---- Join a channel. --- @param channel Channel to join. --- @param key Channel key. [optional] -function irc:join(channel, key) - ---- Leave a channel. --- @param channel Channel to leave. -function irc:part(channel) - ---- Turn user information tracking on or off. User tracking is enabled by default. --- @param b Boolean whether or not to track user information. -function irc:trackUsers(b) - ---- Add/remove modes for a channel or nick. --- @param t Table with fields target, nick, add and/or rem. target or nick --- specifies the user or channel to add/remove modes. add is a list of modes to add to the user or channel. --- rem is a list of modes to remove from the user or channel. --- @usage Example which sets +m (moderated) for #channel:
--- irc:setMode{target = "#channel", add = "m"} -function irc:setMode(t) - ---internal -function irc:invoke(name, ...) -function irc:handle(msg) -function irc:shutdown() - ---- Table with connection information. --- @name ConnectOptions --- @class table --- @field host Server host name. --- @field port Server port. [defaults to 6667] --- @field timeout Connect timeout. [defaults to 30] --- @field password Server password. --- @field secure Boolean to enable TLS connection, pass a params table (described, [luasec]) to control --- [luasec]: http://www.inf.puc-rio.br/~brunoos/luasec/reference.html - ---- Class representing a connection. --- @name Connection --- @class table --- @field authed Boolean indicating whether the connection has completed registration. --- @field connected Whether the connection is currently connected. --- @field motd The server's message of the day. Can be nil. --- @field nick The current nickname. --- @field realname The real name sent to the server. --- @field username The username/ident sent to the server. --- @field socket Raw socket used by the library. --- @field supports What the server claims to support in it's ISUPPORT message. - ---- Class representing an IRC message. --- @name Message --- @class table --- @field args A list of the command arguments --- @field command The IRC command --- @field prefix The prefix of the message --- @field raw A raw IRC line for this message --- @field tags A table of IRCv3 tags --- @field user A User object describing the sender of the message --- Fields may be missing. --- Messages have the following methods: ---
    ---
  • toRFC1459() - Returns the message serialized in RFC 1459 format.
  • ---
- ---- List of hooks you can use with irc:hook. --- The parameter list describes the parameters passed to the callback function. ---
    ---
  • PreRegister() - Usefull for requesting capabilities.
  • ---
  • OnRaw(line) - Any non false/nil return value assumes line handled and will not be further processed.
  • ---
  • OnSend(line)
  • ---
  • OnDisconnect(message, errorOccurred)
  • ---
  • OnChat(user, channel, message)
  • ---
  • OnNotice(user, channel, message)
  • ---
  • OnJoin(user, channel)*
  • ---
  • OnPart(user, channel)*
  • ---
  • OnQuit(user, message)
  • ---
  • NickChange(user, newnick, channel)*
  • ---
  • NameList(channel, names)
  • ---
  • OnTopic(channel, topic)
  • ---
  • OnTopicInfo(channel, creator, timeCreated)
  • ---
  • OnKick(channel, nick, kicker, reason)* (kicker is a user table)
  • ---
  • OnUserMode(modes)
  • ---
  • OnChannelMode(user, channel, modes)
  • ---
  • OnModeChange(user, target, modes, ...)* ('...' contains mode options such as banmasks)
  • ---
  • OnCapabilityList(caps)
  • ---
  • OnCapabilityAvailable(cap, value) Called only when a capability becomes available or changes.
  • ---
  • OnCapabilitySet(cap, enabled)*
  • ---
  • DoX(msg)* - 'X' is any IRC command or numeric with the first letter capitalized (eg, DoPing and Do001)
  • ---
--- * Event also invoked for yourself. --- Channel passed only when user tracking is enabled --- @name Hooks --- @class table - ---- Table with information about a user. ---
    ---
  • server - Server name.
  • ---
  • nick - User nickname.
  • ---
  • username - User username.
  • ---
  • host - User hostname.
  • ---
  • realname - User real name.
  • ---
  • access - User access, available in channel-oriented callbacks. A table containing boolean fields for each access mode that the server supports. Eg: 'o', and 'v'.
  • ---
--- Fields may be missing. To fill them in, enable user tracking and use irc:whois. --- @name User --- @class table - diff --git a/mods/irc/irc/handlers.lua b/mods/irc/irc/handlers.lua deleted file mode 100755 index f01936f6..00000000 --- a/mods/irc/irc/handlers.lua +++ /dev/null @@ -1,277 +0,0 @@ -local util = require("irc.util") -local msgs = require("irc.messages") -local Message = msgs.Message - -local handlers = {} - -handlers["PING"] = function(conn, msg) - conn:send(Message({command="PONG", args=msg.args})) -end - -local function requestWanted(conn, wanted) - local args = {} - for cap, value in pairs(wanted) do - if type(value) == "string" then - cap = cap .. "=" .. value - end - if not conn.capabilities[cap] then - table.insert(args, cap) - end - end - conn:queue(Message({ - command = "CAP", - args = {"REQ", table.concat(args, " ")} - }) - ) -end - -handlers["CAP"] = function(conn, msg) - local cmd = msg.args[2] - if not cmd then - return - end - if cmd == "LS" then - local list = msg.args[3] - local last = false - if list == "*" then - list = msg.args[4] - else - last = true - end - local avail = conn.availableCapabilities - local wanted = conn.wantedCapabilities - for item in list:gmatch("(%S+)") do - local eq = item:find("=", 1, true) - local k, v - if eq then - k, v = item:sub(1, eq - 1), item:sub(eq + 1) - else - k, v = item, true - end - if not avail[k] or avail[k] ~= v then - wanted[k] = conn:invoke("OnCapabilityAvailable", k, v) - end - avail[k] = v - end - if last then - if next(wanted) then - requestWanted(conn, wanted) - end - conn:invoke("OnCapabilityList", conn.availableCapabilities) - end - elseif cmd == "ACK" then - for item in msg.args[3]:gmatch("(%S+)") do - local enabled = (item:sub(1, 1) ~= "-") - local name = enabled and item or item:sub(2) - conn:invoke("OnCapabilitySet", name, enabled) - conn.capabilities[name] = enabled - end - end -end - -handlers["001"] = function(conn, msg) - conn.authed = true - conn.nick = msg.args[1] -end - -handlers["PRIVMSG"] = function(conn, msg) - conn:invoke("OnChat", msg.user, msg.args[1], msg.args[2]) -end - -handlers["NOTICE"] = function(conn, msg) - conn:invoke("OnNotice", msg.user, msg.args[1], msg.args[2]) -end - -handlers["JOIN"] = function(conn, msg) - local channel = msg.args[1] - if conn.track_users then - if msg.user.nick == conn.nick then - conn.channels[channel] = {users = {}} - else - conn.channels[channel].users[msg.user.nick] = msg.user - end - end - - conn:invoke("OnJoin", msg.user, msg.args[1]) -end - -handlers["PART"] = function(conn, msg) - local channel = msg.args[1] - if conn.track_users then - if msg.user.nick == conn.nick then - conn.channels[channel] = nil - else - conn.channels[channel].users[msg.user.nick] = nil - end - end - conn:invoke("OnPart", msg.user, msg.args[1], msg.args[2]) -end - -handlers["QUIT"] = function(conn, msg) - if conn.track_users then - for chanName, chan in pairs(conn.channels) do - chan.users[msg.user.nick] = nil - end - end - conn:invoke("OnQuit", msg.user, msg.args[1], msg.args[2]) -end - -handlers["NICK"] = function(conn, msg) - local newNick = msg.args[1] - if conn.track_users then - for chanName, chan in pairs(conn.channels) do - local users = chan.users - local oldinfo = users[msg.user.nick] - if oldinfo then - users[newNick] = oldinfo - users[msg.user.nick] = nil - conn:invoke("NickChange", msg.user, newNick, chanName) - end - end - else - conn:invoke("NickChange", msg.user, newNick) - end - if msg.user.nick == conn.nick then - conn.nick = newNick - end -end - -local function needNewNick(conn, msg) - local newnick = conn.nickGenerator(msg.args[2]) - conn:queue(irc.msgs.nick(newnick)) -end - --- ERR_ERRONEUSNICKNAME (Misspelt but remains for historical reasons) -handlers["432"] = needNewNick - --- ERR_NICKNAMEINUSE -handlers["433"] = needNewNick - --- ERR_UNAVAILRESOURCE -handlers["437"] = function(conn, msg) - if not conn.authed then - needNewNick(conn, msg) - end -end - --- RPL_ISUPPORT -handlers["005"] = function(conn, msg) - local arglen = #msg.args - -- Skip first and last parameters (nick and info) - for i = 2, arglen - 1 do - local item = msg.args[i] - local pos = item:find("=") - if pos then - conn.supports[item:sub(1, pos - 1)] = item:sub(pos + 1) - else - conn.supports[item] = true - end - end -end - --- RPL_MOTDSTART -handlers["375"] = function(conn, msg) - conn.motd = "" -end - --- RPL_MOTD -handlers["372"] = function(conn, msg) - -- MOTD lines have a "- " prefix, strip it. - conn.motd = conn.motd .. msg.args[2]:sub(3) .. '\n' -end - --- NAMES list -handlers["353"] = function(conn, msg) - local chanType = msg.args[2] - local channel = msg.args[3] - local names = msg.args[4] - if conn.track_users then - conn.channels[channel] = conn.channels[channel] or {users = {}, type = chanType} - - local users = conn.channels[channel].users - for nick in names:gmatch("(%S+)") do - local access, name = util.parseNick(conn, nick) - users[name] = {access = access} - end - end -end - --- End of NAMES list -handlers["366"] = function(conn, msg) - if conn.track_users then - conn:invoke("NameList", msg.args[2], msg.args[3]) - end -end - --- No topic -handlers["331"] = function(conn, msg) - conn:invoke("OnTopic", msg.args[2], nil) -end - -handlers["TOPIC"] = function(conn, msg) - conn:invoke("OnTopic", msg.args[1], msg.args[2]) -end - -handlers["332"] = function(conn, msg) - conn:invoke("OnTopic", msg.args[2], msg.args[3]) -end - --- Topic creation info -handlers["333"] = function(conn, msg) - conn:invoke("OnTopicInfo", msg.args[2], msg.args[3], tonumber(msg.args[4])) -end - -handlers["KICK"] = function(conn, msg) - conn:invoke("OnKick", msg.args[1], msg.args[2], msg.user, msg.args[3]) -end - --- RPL_UMODEIS --- To answer a query about a client's own mode, RPL_UMODEIS is sent back -handlers["221"] = function(conn, msg) - conn:invoke("OnUserMode", msg.args[2]) -end - --- RPL_CHANNELMODEIS --- The result from common irc servers differs from that defined by the rfc -handlers["324"] = function(conn, msg) - conn:invoke("OnChannelMode", msg.args[2], msg.args[3]) -end - -handlers["MODE"] = function(conn, msg) - local target = msg.args[1] - local modes = msg.args[2] - local optList = {} - for i = 3, #msg.args do - table.insert(optList, msg.args[i]) - end - if conn.track_users and target ~= conn.nick then - local add = true - local argNum = 1 - util.updatePrefixModes(conn) - for c in modes:gmatch(".") do - if c == "+" then add = true - elseif c == "-" then add = false - elseif conn.modeprefix[c] then - local nick = optList[argNum] - argNum = argNum + 1 - local user = conn.channels[target].users[nick] - user.access = user.access or {} - local access = user.access - access[c] = add - if c == "o" then access.op = add - elseif c == "v" then access.voice = add - end - end - end - end - conn:invoke("OnModeChange", msg.user, target, modes, unpack(optList)) -end - -handlers["ERROR"] = function(conn, msg) - conn:invoke("OnDisconnect", msg.args[1], true) - conn:shutdown() - error(msg.args[1], 3) -end - -return handlers - diff --git a/mods/irc/irc/init.lua b/mods/irc/irc/init.lua deleted file mode 100755 index 194b6921..00000000 --- a/mods/irc/irc/init.lua +++ /dev/null @@ -1,257 +0,0 @@ -local socket = require("socket") -local util = require("irc.util") -local handlers = require("irc.handlers") -local msgs = require("irc.messages") -local Message = msgs.Message - -local meta = {} -meta.__index = meta - - -for k, v in pairs(require("irc.asyncoperations")) do - meta[k] = v -end - -local meta_preconnect = {} -function meta_preconnect.__index(o, k) - local v = rawget(meta_preconnect, k) - - if v == nil and meta[k] ~= nil then - error(("field '%s' is not accessible before connecting"):format(k), 2) - end - return v -end - -meta.connected = true -meta_preconnect.connected = false - -function new(data) - local o = { - nick = assert(data.nick, "Field 'nick' is required"); - username = data.username or "lua"; - realname = data.realname or "Lua owns"; - nickGenerator = data.nickGenerator or util.defaultNickGenerator; - hooks = {}; - track_users = true; - supports = {}; - messageQueue = {}; - lastThought = 0; - recentMessages = 0; - availableCapabilities = {}; - wantedCapabilities = {}; - capabilities = {}; - } - assert(util.checkNick(o.nick), "Erroneous nickname passed to irc.new") - return setmetatable(o, meta_preconnect) -end - -function meta:hook(name, id, f) - f = f or id - self.hooks[name] = self.hooks[name] or {} - self.hooks[name][id] = f - return id or f -end -meta_preconnect.hook = meta.hook - - -function meta:unhook(name, id) - local hooks = self.hooks[name] - - assert(hooks, "no hooks exist for this event") - assert(hooks[id], "hook ID not found") - - hooks[id] = nil -end -meta_preconnect.unhook = meta.unhook - -function meta:invoke(name, ...) - local hooks = self.hooks[name] - if hooks then - for id, f in pairs(hooks) do - local ret = f(...) - if ret then - return ret - end - end - end -end - -function meta_preconnect:connect(_host, _port) - local host, port, password, secure, timeout - - if type(_host) == "table" then - host = _host.host - port = _host.port - timeout = _host.timeout - password = _host.password - secure = _host.secure - else - host = _host - port = _port - end - - host = host or error("host name required to connect", 2) - port = port or 6667 - - local s = socket.tcp() - - s:settimeout(timeout or 30) - assert(s:connect(host, port)) - - if secure then - local work, ssl = pcall(require, "ssl") - if not work then - error("LuaSec required for secure connections", 2) - end - - local params - if type(secure) == "table" then - params = secure - else - params = {mode = "client", protocol = "tlsv1"} - end - - s = ssl.wrap(s, params) - local success, errmsg = s:dohandshake() - if not success then - error(("could not make secure connection: %s"):format(errmsg), 2) - end - end - - self.socket = s - setmetatable(self, meta) - - self:invoke("PreRegister", self) - - if password then - self:queue(Message({command="PASS", args={password}})) - end - - self:queue(msgs.nick(self.nick)) - self:queue(Message({command="USER", args={self.username, "0", "*", self.realname}})) - - self.channels = {} - - s:settimeout(0) - - repeat - self:think() - socket.sleep(0.1) - until self.authed -end - -function meta:disconnect(message) - message = message or "Bye!" - - self:invoke("OnDisconnect", message, false) - self:send(msgs.quit(message)) - - self:shutdown() -end - -function meta:shutdown() - self.socket:close() - setmetatable(self, meta_preconnect) -end - -local function getline(self, errlevel) - local line, err = self.socket:receive("*l") - - if not line and err ~= "timeout" and err ~= "wantread" then - self:invoke("OnDisconnect", err, true) - self:shutdown() - error(err, errlevel) - end - - return line -end - -function meta:think() - while true do - local line = getline(self, 3) - if line and #line > 0 then - if not self:invoke("OnRaw", line) then - self:handle(Message({raw=line})) - end - else - break - end - end - - -- Handle outgoing message queue - local diff = socket.gettime() - self.lastThought - self.recentMessages = self.recentMessages - (diff * 2) - if self.recentMessages < 0 then - self.recentMessages = 0 - end - for i = 1, #self.messageQueue do - if self.recentMessages > 4 then - break - end - self:send(table.remove(self.messageQueue, 1)) - self.recentMessages = self.recentMessages + 1 - end - self.lastThought = socket.gettime() -end - -function meta:handle(msg) - local handler = handlers[msg.command] - if handler then - handler(self, msg) - end - self:invoke("Do" .. util.capitalize(msg.command), msg) -end - -local whoisHandlers = { - ["311"] = "userinfo"; - ["312"] = "node"; - ["319"] = "channels"; - ["330"] = "account"; -- Freenode - ["307"] = "registered"; -- Unreal -} - -function meta:whois(nick) - self:send(msgs.whois(nick)) - - local result = {} - - while true do - local line = getline(self, 3) - if line then - local msg = Message({raw=line}) - - local handler = whoisHandlers[msg.command] - if handler then - result[handler] = msg.args - elseif msg.command == "318" then - break - else - self:handle(msg) - end - end - end - - if result.account then - result.account = result.account[3] - elseif result.registered then - result.account = result.registered[2] - end - - return result -end - -function meta:topic(channel) - self:queue(msgs.topic(channel)) -end - -return { - new = new; - - Message = Message; - msgs = msgs; - - color = util.color; - bold = util.bold; - underline = util.underline; -} - diff --git a/mods/irc/irc/messages.lua b/mods/irc/irc/messages.lua deleted file mode 100755 index 1553da8f..00000000 --- a/mods/irc/irc/messages.lua +++ /dev/null @@ -1,213 +0,0 @@ - --- Module table -local m = {} - -local msg_meta = {} -msg_meta.__index = msg_meta - -local function Message(opts) - opts = opts or {} - setmetatable(opts, msg_meta) - if opts.raw then - opts:fromRFC1459(opts.raw) - end - return opts -end - -m.Message = Message - -local tag_escapes = { - [";"] = "\\:", - [" "] = "\\s", - ["\0"] = "\\0", - ["\\"] = "\\\\", - ["\r"] = "\\r", - ["\n"] = "\\n", -} - -local tag_unescapes = {} -for x, y in pairs(tag_escapes) do tag_unescapes[y] = x end - -function msg_meta:toRFC1459() - local s = "" - - if self.tags then - s = s.."@" - for key, value in pairs(self.tags) do - s = s..key - if value ~= true then - value = value:gsub("[; %z\\\r\n]", tag_escapes) - s = s.."="..value - end - s = s..";" - end - -- Strip trailing semicolon - s = s:sub(1, -2) - s = s.." " - end - - s = s..self.command - - local argnum = #self.args - for i = 1, argnum do - local arg = self.args[i] - local startsWithColon = (arg:sub(1, 1) == ":") - local hasSpace = arg:find(" ") - if i == argnum and (hasSpace or startsWithColon) then - s = s.." :" - else - assert(not hasSpace and not startsWithColon, - "Message arguments can not be " - .."serialized to RFC1459 format") - s = s.." " - end - s = s..arg - end - - return s -end - -local function parsePrefix(prefix) - local user = {} - user.nick, user.username, user.host = prefix:match("^(.+)!(.+)@(.+)$") - if not user.nick and prefix:find(".", 1, true) then - user.server = prefix - end - return user -end - -function msg_meta:fromRFC1459(line) - -- IRCv3 tags - if line:sub(1, 1) == "@" then - self.tags = {} - local space = line:find(" ", 1, true) - -- For each semicolon-delimited section from after - -- the @ character to before the space character. - for tag in line:sub(2, space - 1):gmatch("([^;]+)") do - local eq = tag:find("=", 1, true) - if eq then - self.tags[tag:sub(1, eq - 1)] = - tag:sub(eq + 1):gsub("\\([:s0\\rn])", tag_unescapes) - else - self.tags[tag] = true - end - end - line = line:sub(space + 1) - end - - if line:sub(1, 1) == ":" then - local space = line:find(" ", 1, true) - self.prefix = line:sub(2, space - 1) - self.user = parsePrefix(self.prefix) - line = line:sub(space + 1) - end - - local pos - self.command, pos = line:match("(%S+)()") - -- /MFF BEGIN - if not pos then - minetest.log("error", "[IRC] This crash message was intended to see the value of a breaking variable. line = " .. (line or "nil")) - return - end - -- /MFF END (Mg|06/01/2015) - line = line:sub(pos) - - self.args = self.args or {} - for pos, param in line:gmatch("()(%S+)") do - if param:sub(1, 1) == ":" then - param = line:sub(pos + 1) - table.insert(self.args, param) - break - end - table.insert(self.args, param) - end -end - -function m.privmsg(to, text) - return Message({command="PRIVMSG", args={to, text}}) -end - -function m.notice(to, text) - return Message({command="NOTICE", args={to, text}}) -end - -function m.action(to, text) - return Message({command="PRIVMSG", args={to, ("\x01ACTION %s\x01"):format(text)}}) -end - -function m.ctcp(command, to, args) - s = "\x01"..command - if args then - s = ' '..args - end - s = s..'\x01' - return Message({command="PRIVMSG", args={to, s}}) -end - -function m.kick(channel, target, reason) - return Message({command="KICK", args={channel, target, reason}}) -end - -function m.join(channel, key) - return Message({command="JOIN", args={channel, key}}) -end - -function m.part(channel, reason) - return Message({command="PART", args={channel, reason}}) -end - -function m.quit(reason) - return Message({command="QUIT", args={reason}}) -end - -function m.kill(target, reason) - return Message({command="KILL", args={target, reason}}) -end - -function m.kline(time, mask, reason, operreason) - local args = nil - if time then - args = {time, mask, reason..'|'..operreason} - else - args = {mask, reason..'|'..operreason} - end - return Message({command="KLINE", args=args}) -end - -function m.whois(nick, server) - local args = nil - if server then - args = {server, nick} - else - args = {nick} - end - return Message({command="WHOIS", args=args}) -end - -function m.topic(channel, text) - return Message({command="TOPIC", args={channel, text}}) -end - -function m.invite(channel, target) - return Message({command="INVITE", args={channel, target}}) -end - -function m.nick(nick) - return Message({command="NICK", args={nick}}) -end - -function m.mode(target, modes) - -- We have to split the modes parameter because the mode string and - -- each parameter are seperate arguments (The first command is incorrect) - -- MODE foo :+ov Nick1 Nick2 - -- MODE foo +ov Nick1 Nick2 - local mt = util.split(modes) - return Message({command="MODE", args={target, unpack(mt)}}) -end - -function m.cap(cmd, ...) - return Message({command="CAP", args={cmd, ...}}) -end - -return m - diff --git a/mods/irc/irc/push-luadoc.sh b/mods/irc/irc/push-luadoc.sh deleted file mode 100755 index 6f77ff29..00000000 --- a/mods/irc/irc/push-luadoc.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -if [ "$TRAVIS_REPO_SLUG" == "JakobOvrum/LuaIRC" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then - - echo -e "Generating luadoc...\n" - - git config --global user.email "travis@travis-ci.org" - git config --global user.name "travis-ci" - git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG} gh-pages > /dev/null - - cd gh-pages - git rm -rf ./doc - sh ./generate.sh - git add -f ./doc - git commit -m "Lastest documentation on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages" - git push -fq origin gh-pages > /dev/null - - echo -e "Published luadoc to gh-pages.\n" -fi diff --git a/mods/irc/irc/set.lua b/mods/irc/irc/set.lua deleted file mode 100755 index 433afc16..00000000 --- a/mods/irc/irc/set.lua +++ /dev/null @@ -1,52 +0,0 @@ -local select = require("socket").select - -local m = {} -local set = {} -set.__index = set - -function m.new(t) - t.connections = {} - t.sockets = {} - return setmetatable(t, set) -end - -function set:add(connection) - local socket = connection.socket - insert(self.sockets, socket) - - self.connections[socket] = connection - insert(self.connections, connection) -end - -function set:remove(connection) - local socket = connection.socket - self.connections[socket] = nil - for k, s in ipairs(self.sockets) do - if socket == s then - remove(self.sockets, k) - remove(self.connections, k) - break - end - end -end - -function set:select() - local read, write, err = select(self.sockets, nil, self.timeout) - - if read then - for k, socket in ipairs(read) do - read[k] = self.connections[socket] - end - end - - return read, err -end - --- Select - but if it times out, it returns all connections. -function set:poll() - local read, err = self:select() - return err == "timeout" and self.connections or read -end - -return m - diff --git a/mods/irc/irc/util.lua b/mods/irc/irc/util.lua deleted file mode 100755 index 59168570..00000000 --- a/mods/irc/irc/util.lua +++ /dev/null @@ -1,120 +0,0 @@ - --- Module table -local m = {} - -function m.updatePrefixModes(conn) - if conn.prefixmode and conn.modeprefix then - return - end - conn.prefixmode = {} - conn.modeprefix = {} - if conn.supports.PREFIX then - local modes, prefixes = conn.supports.PREFIX:match("%(([^%)]*)%)(.*)") - for i = 1, #modes do - conn.prefixmode[prefixes:sub(i, i)] = modes:sub(i, i) - conn.modeprefix[ modes:sub(i, i)] = prefixes:sub(i, i) - end - else - conn.prefixmode['@'] = 'o' - conn.prefixmode['+'] = 'v' - conn.modeprefix['o'] = '@' - conn.modeprefix['v'] = '+' - end -end - -function m.parseNick(conn, nick) - local access = {} - m.updatePrefixModes(conn) - local namestart = 1 - for i = 1, #nick - 1 do - local c = nick:sub(i, i) - if conn.prefixmode[c] then - access[conn.prefixmode[c]] = true - else - namestart = i - break - end - end - access.op = access.o - access.voice = access.v - local name = nick:sub(namestart) - return access, name -end - --- mIRC markup scheme (de-facto standard) -m.color = { - black = 1, - blue = 2, - green = 3, - red = 4, - lightred = 5, - purple = 6, - brown = 7, - yellow = 8, - lightgreen = 9, - navy = 10, - cyan = 11, - lightblue = 12, - violet = 13, - gray = 14, - lightgray = 15, - white = 16 -} - -local colByte = string.char(3) -setmetatable(m.color, {__call = function(_, text, colornum) - colornum = (type(colornum) == "string" and - assert(color[colornum], "Invalid color '"..colornum.."'") or - colornum) - return table.concat{colByte, tostring(colornum), text, colByte} -end}) - -local boldByte = string.char(2) -function m.bold(text) - return boldByte..text..boldByte -end - -local underlineByte = string.char(31) -function m.underline(text) - return underlineByte..text..underlineByte -end - -function m.checkNick(nick) - return nick:find("^[a-zA-Z_%-%[|%]%^{|}`][a-zA-Z0-9_%-%[|%]%^{|}`]*$") ~= nil -end - -function m.defaultNickGenerator(nick) - -- LuaBot -> LuaCot -> LuaCou -> ... - -- We change a random character rather than appending to the - -- nickname as otherwise the new nick could exceed the ircd's - -- maximum nickname length. - local randindex = math.random(1, #nick) - local randchar = string.sub(nick, randindex, randindex) - local b = string.byte(randchar) - b = b + 1 - if b < 65 or b > 125 then - b = 65 - end - -- Get the halves before and after the changed character - local first = string.sub(nick, 1, randindex - 1) - local last = string.sub(nick, randindex + 1, #nick) - nick = first .. string.char(b) .. last -- Insert the new charachter - return nick -end - -function m.capitalize(text) - -- Converts first character to upercase and the rest to lowercase. - -- "PING" -> "Ping" | "hello" -> "Hello" | "123" -> "123" - return text:sub(1, 1):upper()..text:sub(2):lower() -end - -function m.split(str, sep) - local t = {} - for s in str:gmatch("%S+") do - table.insert(t, s) - end - return t -end - -return m - diff --git a/mods/irc/messages.lua b/mods/irc/messages.lua deleted file mode 100755 index 45ef4c41..00000000 --- a/mods/irc/messages.lua +++ /dev/null @@ -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 - diff --git a/mods/irc/player_part.lua b/mods/irc/player_part.lua deleted file mode 100755 index c9916c40..00000000 --- a/mods/irc/player_part.lua +++ /dev/null @@ -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 - diff --git a/mods/irc/unix.so b/mods/irc/unix.so deleted file mode 100755 index 9cce88a4..00000000 Binary files a/mods/irc/unix.so and /dev/null differ diff --git a/mods/irc_commands/.gitignore b/mods/irc_commands/.gitignore deleted file mode 100755 index b25c15b8..00000000 --- a/mods/irc_commands/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*~ diff --git a/mods/irc_commands/depends.txt b/mods/irc_commands/depends.txt deleted file mode 100755 index 3661ef94..00000000 --- a/mods/irc_commands/depends.txt +++ /dev/null @@ -1 +0,0 @@ -irc diff --git a/mods/irc_commands/init.lua b/mods/irc_commands/init.lua deleted file mode 100755 index 27da7961..00000000 --- a/mods/irc_commands/init.lua +++ /dev/null @@ -1,274 +0,0 @@ - -local irc_users = {} -local irc_tokens = {} -local tokens_file = minetest.get_worldpath() .. "/irc_tokens" - -local old_chat_send_player = minetest.chat_send_player -minetest.chat_send_player = function(name, message) - for nick, loggedInAs in pairs(irc_users) do - if name == loggedInAs and not minetest.get_player_by_name(name) then - irc:say(nick, message) - end - end - return old_chat_send_player(name, message) -end - --- Load/Save tokens -local function load_tokens() - local f = io.open(tokens_file, "r") - local tokens = {} - if f then - tokens = minetest.deserialize(f:read()) - f:close() - end - return tokens -end -irc_tokens = load_tokens() - -local function save_tokens() - local f = io.open(tokens_file, "w") - if f then - f:write(minetest.serialize(irc_tokens)) - f:close() - return true - else - minetest.log("error", "[IRC_Commands] Tokens storage file couldn't be created!") - return false - end -end - -local function generate_token(name) - local passtr = "" - for i = 1, math.random(20,40) do - passtr = passtr .. tostring(math.random(1,65535)) - end - return minetest.get_password_hash(name, passtr) -end - --- Note: You can and **should** regulary regenerate tokens -minetest.register_chatcommand("gen_token", { - description = "Generate irc token to log in", - privs = {shout = true}, - func = function(name, param) - if not minetest.get_player_by_name(name) then - return false, "You need to be logged in to the server to generate tokens" - end - local h = "" - if irc_tokens[name] then - h = " new" - end - irc_tokens[name] = generate_token(name) - minetest.chat_send_player(name, "Here is you" .. h .. " token : " .. irc_tokens[name]) - save_tokens() - - -- Disconnect any user using this login - for nick, loggedInAs in pairs(irc_users) do - if loggedInAs == name then - minetest.log("action", nick.."@IRC has been logged out from " - ..irc_users[nick] .. " (token regenerated)") - irc_users[nick] = nil - irc:say(nick, "Token regenerated. You are now logged off.") - end - end - return true - end -}) - -minetest.register_chatcommand("del_token", { - description = "Delete your entry in the token register", - privs = {shout = true}, - func = function(name) - if not minetest.get_player_by_name(name) then - return false, "You need to be logged in to the server to generate tokens" - end - if not irc_tokens[name] then - return true, "You had no entry in the tokens' register" - else - irc_tokens[name] = nil - save_tokens() - -- Disconnect any user using this login - for nick, loggedInAs in pairs(irc_users) do - if loggedInAs == name then - minetest.log("action", nick.."@IRC has been logged out from " - ..irc_users[nick] .. " (token regenerated)") - irc_users[nick] = nil - irc:say(nick, "Token regenerated. You are now logged off.") - end - end - return true, "Access for you using a token has been removed. Use /gen_token to create" .. - " a new token at any time" - end - end -}) - -irc:register_hook("NickChange", function(user, newNick) - for nick, player in pairs(irc_users) do - if nick == user.nick then - irc_users[newNick] = irc_users[user.nick] - irc_users[user.nick] = nil - end - end -end) - -irc:register_hook("OnPart", function(user, channel, reason) - irc_users[user.nick] = nil -end) - -irc:register_hook("OnKick", function(user, channel, target, reason) - irc_users[target] = nil -end) - -irc:register_hook("OnQuit", function(user, reason) - irc_users[user.nick] = nil -end) - - --- Pretty much a copypasta of the command right after this one --- We'll keep "login" until passwords are broken. When it happens, --- We'll remove "tlogin" and modify "login" to handle tokens -irc:register_bot_command("tlogin", { - params = " ", - description = "Login as an user to run commands, using a token", - func = function(user, args) - if args == "" then - return false, "You need a username and a token." - end - local playerName, token = args:match("^(%S+)%s(%S+)$") - if not playerName then - return false, "Player name and password required." - end - local inChannel = false - local users = irc.conn.channels[irc.config.channel].users - for cnick, cuser in pairs(users) do - if user.nick == cnick then - inChannel = true - break - end - end - if not inChannel then - return false, "You need to be in the server's channel to login." - end - if irc_tokens[playerName] and - irc_tokens[playerName] == token then - minetest.log("action", "User " .. user.nick - .." from IRC logs in as " .. playerName .. " using their token") - irc_users[user.nick] = playerName - return true, "You are now logged in as " .. playerName - else - minetest.log("action", user.nick.."@IRC attempted to log in as " - ..playerName.." unsuccessfully using a token") - return false, "Incorrect token or player does not exist." - end - end -}) - -irc:register_bot_command("login", { - params = " ", - description = "Login as a user to run commands", - func = function(user, args) - if args == "" then - return false, "You need a username and password." - end - local playerName, password = args:match("^(%S+)%s(%S+)$") - if not playerName then - return false, "Player name and password required." - end - local inChannel = false - local users = irc.conn.channels[irc.config.channel].users - for cnick, cuser in pairs(users) do - if user.nick == cnick then - inChannel = true - break - end - end - if not inChannel then - return false, "You need to be in the server's channel to login." - end - if minetest.auth_table[playerName] and - minetest.auth_table[playerName].password == - minetest.get_password_hash(playerName, password) then - minetest.log("action", "User "..user.nick - .." from IRC logs in as "..playerName) - irc_users[user.nick] = playerName - return true, "You are now logged in as "..playerName - else - minetest.log("action", user.nick.."@IRC attempted to log in as " - ..playerName.." unsuccessfully") - return false, "Incorrect password or player does not exist." - end - end -}) - -irc:register_bot_command("logout", { - description = "Logout", - func = function (user, args) - if irc_users[user.nick] then - minetest.log("action", user.nick.."@IRC logs out from " - ..irc_users[user.nick]) - irc_users[user.nick] = nil - return true, "You are now logged off." - else - return false, "You are not logged in." - end - end, -}) - -irc:register_bot_command("cmd", { - params = "", - description = "Run a command on the server", - func = function (user, args) - if args == "" then - return false, "You need a command." - end - if not irc_users[user.nick] then - return false, "You are not logged in." - end - local found, _, commandname, params = args:find("^([^%s]+)%s(.+)$") - if not found then - commandname = args - end - local command = minetest.chatcommands[commandname] - if not command then - return false, "Not a valid command." - end - if not minetest.check_player_privs(irc_users[user.nick], command.privs) then - return false, "Your privileges are insufficient." - end - minetest.log("action", user.nick.."@IRC runs " - ..args.." as "..irc_users[user.nick]) - return command.func(irc_users[user.nick], (params or "")) - end -}) - -irc:register_bot_command("say", { - params = "message", - description = "Say something", - func = function (user, args) - if args == "" then - return false, "You need a message." - end - if not irc_users[user.nick] then - return false, "You are not logged in." - end - if not minetest.check_player_privs(irc_users[user.nick], {shout=true}) then - minetest.log("action", ("%s@IRC tried to say %q as %s" - .." without the shout privilege.") - :format(user.nick, args, irc_users[user.nick])) - return false, "You can not shout." - end - minetest.log("action", ("%s@IRC says %q as %s.") - :format(user.nick, args, irc_users[user.nick])) - minetest.chat_send_all("<"..irc_users[user.nick].."@IRC> "..args) - return true, "Message sent successfuly." - end -}) - -irc:register_bot_command("timeofday", { - description = "Tell the in-game time of day", - func = function(user, args) - local timeofday = minetest.get_timeofday() - local hours, minutes = math.modf(timeofday * 24) - minutes = math.floor(minutes * 60) - return true, "It's " .. hours .. " h " .. minutes .. " min." - end -})