forked from minetest-mods/irc
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			351a86cbf2
			...
			split_mess
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5d53641a09 | 
							
								
								
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,3 @@ | ||||
| [submodule "irc"] | ||||
| [submodule "src/LuaIRC"] | ||||
| 	path = irc | ||||
| 	url = https://sys4.fr/gitea/Minetest/LuaIRC.git | ||||
| 	url = https://github.com/ShadowNinja/LuaIRC.git | ||||
|   | ||||
							
								
								
									
										14
									
								
								.luacheckrc
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.luacheckrc
									
									
									
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
|  | ||||
| allow_defined_top = true | ||||
|  | ||||
| read_globals = { | ||||
| 	"minetest", | ||||
| } | ||||
|  | ||||
| exclude_files = { | ||||
| 	"irc/*", | ||||
| } | ||||
|  | ||||
| globals = { | ||||
| 	"irc", | ||||
| } | ||||
							
								
								
									
										16
									
								
								API.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								API.md
									
									
									
									
									
								
							| @@ -13,14 +13,14 @@ to your mod's `depends.txt` file. | ||||
| Reference | ||||
| --------- | ||||
|  | ||||
| irc.say([name,] message) | ||||
| 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:say("Hello, Channel!") | ||||
| 	irc:say("john1234", "How are you?") | ||||
|  | ||||
| irc.register_bot_command(name, cmdDef) | ||||
| 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. | ||||
| @@ -38,7 +38,7 @@ irc.register_bot_command(name, cmdDef) | ||||
| 			end, | ||||
| 		}; | ||||
| 	Example: | ||||
| 		irc.register_bot_command("hello", { | ||||
| 		irc:register_bot_command("hello", { | ||||
| 			params = "", | ||||
| 			description = "Greet user", | ||||
| 			func = function(user, param) | ||||
| @@ -55,12 +55,12 @@ irc.joined_players[name] | ||||
| 		-- Joe is talking on IRC | ||||
| 	end | ||||
|  | ||||
| irc.register_hook(name, func) | ||||
| 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) | ||||
| 	irc:register_hook("OnSend", function(line) | ||||
| 		print("SEND: "..line) | ||||
| 	end) | ||||
|  | ||||
| @@ -83,7 +83,7 @@ not modify these settings at runtime or you might crash the server! | ||||
| Hooks | ||||
| ----- | ||||
|  | ||||
| The `irc.register_hook` function can register functions to be called | ||||
| 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. | ||||
|   | ||||
							
								
								
									
										165
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,16 +1,12 @@ | ||||
|  | ||||
| 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 [here][forum]. | ||||
|  | ||||
| [forum]: https://forum.minetest.net/viewtopic.php?f=11&t=3905 | ||||
| The forum topic is at https://forum.minetest.net/viewtopic.php?f=11&t=3905 | ||||
|  | ||||
|  | ||||
| Installing | ||||
| @@ -18,121 +14,109 @@ Installing | ||||
|  | ||||
| Quick one line install for Linux: | ||||
|  | ||||
| 	cd <Mods directory> && git clone --recursive https://github.com/minetest-mods/irc.git | ||||
| 	cd <Mods directory> && git clone --recursive https://github.com/kaeza/minetest-irc.git irc | ||||
|  | ||||
| Please change `<Mods directory>` to fit your installation of Minetest. | ||||
| For more information, see [the wiki][wiki]. | ||||
| 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`. | ||||
| 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 | ||||
| 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: | ||||
| 	# # Debian/Ubuntu's LuaSocket packages are broken, so use LuaRocks. | ||||
| 	# apt-get install luarocks | ||||
| 	# luarocks install luasocket | ||||
|  | ||||
| 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 | ||||
|  | ||||
| [wiki]: https://wiki.minetest.net/Installing_mods | ||||
| 	# apt-get install lua-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): | ||||
|   The address of the IRC server to connect to. | ||||
|   * `irc.server` (string) | ||||
| 	The address of the IRC server to connect to. | ||||
|  | ||||
| * `irc.channel` (string): | ||||
|   The IRC channel to join. | ||||
|   * `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.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.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.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.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.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.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.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_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. | ||||
|   * `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 | ||||
| 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. | ||||
| 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>`: | ||||
|   Send a private message to a IRC user. | ||||
|   * `/irc_msg <nick> <message>` | ||||
| 	Sends a private message to a IRC user. | ||||
|  | ||||
| * `/join`: | ||||
|   Join the IRC chat. | ||||
|   * `/join` | ||||
| 	Join the IRC chat. | ||||
|  | ||||
| * `/part`: | ||||
|   Part the IRC chat. | ||||
|   * `/part` | ||||
| 	Part the IRC chat. | ||||
|  | ||||
| * `/irc_connect`: | ||||
|   Connect the bot manually to the IRC network. | ||||
|   * `/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_disconnect` | ||||
| 	Disconnect the bot manually from the IRC network (this does not | ||||
| 	shutdown the game). | ||||
|  | ||||
| * `/irc_reconnect`: | ||||
|   Equivalent to `/irc_disconnect` followed by `/irc_connect`. | ||||
|   * `/irc_reconnect` | ||||
| 	Equivilant to `/irc_disconnect` followed by `/irc_connect`. | ||||
|  | ||||
| You can also send private messages from IRC to in-game players | ||||
| by sending a private message to the bot (set with the `irc.nick` | ||||
| option above), in the following format: | ||||
| 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 | ||||
|  | ||||
| @@ -141,29 +125,21 @@ a private message from IRC with: | ||||
|  | ||||
| 	/msg server_nick @mtuser Hello! | ||||
|  | ||||
| The bot also supports some basic commands, which are invoked by saying | ||||
| the bot name followed by either a colon or a comma and the command, or | ||||
| sending a private message to it. For example: `ServerBot: help whereis`. | ||||
| 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. | ||||
|  | ||||
| * `help [<command>]`: | ||||
|   Prints help about a command, or a list of supported commands if no | ||||
|   command is given. | ||||
|  | ||||
| * `uptime`: | ||||
|   Prints the server's running time. | ||||
|  | ||||
| * `whereis <player>`: | ||||
|   Prints the coordinates of the given player. | ||||
|  | ||||
| * `players`: | ||||
|   Lists players currently in the server. | ||||
| 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: | ||||
| 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, | ||||
| @@ -175,7 +151,10 @@ forum topic. Thanks to you all! | ||||
| License | ||||
| ------- | ||||
|  | ||||
| See `LICENSE.txt` for details. | ||||
| Copyright © 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. | ||||
|  | ||||
| The files in the `irc` directory are part of the LuaIRC project. | ||||
| See `irc/LICENSE.txt` for details. | ||||
|   | ||||
							
								
								
									
										102
									
								
								botcmds.lua
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								botcmds.lua
									
									
									
									
									
								
							| @@ -1,59 +1,39 @@ | ||||
|  | ||||
| irc.bot_commands = {} | ||||
|  | ||||
| -- From RFC1459: | ||||
| -- "Because of IRC’s scandanavian origin, the characters {}| are | ||||
| --  considered to be the lower case equivalents of the characters | ||||
| --  []\, respectively." | ||||
| local irctolower = { ["["]="{", ["\\"]="|", ["]"]="}" } | ||||
|  | ||||
| local function irclower(s) | ||||
| 	return (s:lower():gsub("[%[%]\\]", irctolower)) | ||||
| end | ||||
|  | ||||
| local function nickequals(nick1, nick2) | ||||
| 	return irclower(nick1) == irclower(nick2) | ||||
| end | ||||
|  | ||||
| function irc.check_botcmd(msg) | ||||
| function irc:check_botcmd(msg) | ||||
| 	local prefix = irc.config.command_prefix | ||||
| 	local nick = irc.conn.nick | ||||
| 	local nick = irc.conn.nick:lower() | ||||
| 	local text = msg.args[2] | ||||
| 	local nickpart = text:sub(1, #nick) | ||||
| 	local suffix = text:sub(#nick+1, #nick+2) | ||||
| 	local nickpart = text:sub(1, #nick + 2):lower() | ||||
|  | ||||
| 	-- First check for a nick prefix | ||||
| 	if nickequals(nickpart, nick) | ||||
| 			and (suffix == ": " or suffix == ", ") then | ||||
| 		irc.bot_command(msg, text:sub(#nick + 3)) | ||||
| 	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 | ||||
| 		irc.bot_command(msg, text:sub(#prefix + 1)) | ||||
| 		self:bot_command(msg, text:sub(#prefix + 1)) | ||||
| 		return true | ||||
| 	end | ||||
| 	return false | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.bot_command(msg, text) | ||||
| 	-- Remove leading whitespace | ||||
| 	text = text:match("^%s*(.*)") | ||||
| function irc:bot_command(msg, text) | ||||
| 	if text:sub(1, 1) == "@" then | ||||
| 		local _, _, player_to, message = text:find("^.([^%s]+)%s(.+)$") | ||||
| 		if not player_to then | ||||
| 			return | ||||
| 		elseif not minetest.get_player_by_name(player_to) then | ||||
| 			irc.reply("User '"..player_to.."' is not in the game.") | ||||
| 		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.") | ||||
| 			irc:reply("User '"..player_to.."' is not using IRC.") | ||||
| 			return | ||||
| 		end | ||||
| 		minetest.chat_send_player(player_to, | ||||
| 				minetest.colorize(irc.config.pm_color, | ||||
| 				"PM from "..msg.user.nick.."@IRC: "..message, false)) | ||||
| 		irc.reply("Message sent!") | ||||
| 				"PM from "..msg.user.nick.."@IRC: "..message, false) | ||||
| 		irc:reply("Message sent!") | ||||
| 		return | ||||
| 	end | ||||
| 	local pos = text:find(" ", 1, true) | ||||
| @@ -66,50 +46,44 @@ function irc.bot_command(msg, text) | ||||
| 		args = "" | ||||
| 	end | ||||
|   | ||||
| 	if not irc.bot_commands[cmd] then | ||||
| 		irc.reply("Unknown command '"..cmd.."'. Try 'help'." | ||||
| 	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 _, message = irc.bot_commands[cmd].func(msg.user, args) | ||||
| 	local success, message = self.bot_commands[cmd].func(msg.user, args) | ||||
| 	if message then | ||||
| 		irc.reply(message) | ||||
| 		self:reply(message) | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.register_bot_command(name, def) | ||||
| 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 | ||||
| 	irc.bot_commands[name] = def | ||||
| 	self.bot_commands[name] = def | ||||
| end | ||||
|  | ||||
|  | ||||
| irc.register_bot_command("help", { | ||||
| irc:register_bot_command("help", { | ||||
| 	params = "<command>", | ||||
| 	description = "Get help about a command", | ||||
| 	func = function(_, args) | ||||
| 	func = function(user, args) | ||||
| 		if args == "" then | ||||
| 			local cmdlist = { } | ||||
| 			for name in pairs(irc.bot_commands) do | ||||
| 				cmdlist[#cmdlist+1] = name | ||||
| 			end | ||||
| 			return true, "Available commands: "..table.concat(cmdlist, ", ") | ||||
| 					.." -- Use 'help <command name>' to get" | ||||
| 					.." help about a specific command." | ||||
| 			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 '"..args.."'." | ||||
| 			return false, "Unknown command '"..cmdname.."'." | ||||
| 		end | ||||
|  | ||||
| 		return true, ("Usage: %s%s %s -- %s"):format( | ||||
| 				irc.config.command_prefix or "", | ||||
| 		return true, ("Usage: %c%s %s -- %s"):format( | ||||
| 				irc.config.command_prefix, | ||||
| 				args, | ||||
| 				cmd.params or "<no parameters>", | ||||
| 				cmd.description or "<no description>") | ||||
| @@ -117,20 +91,24 @@ irc.register_bot_command("help", { | ||||
| }) | ||||
|  | ||||
|  | ||||
| irc.register_bot_command("list", { | ||||
| irc:register_bot_command("list", { | ||||
| 	params = "", | ||||
| 	description = "List available commands.", | ||||
| 	func = function() | ||||
| 		return false, "The `list` command has been merged into `help`." | ||||
| 				.." Use `help` with no arguments to get a list." | ||||
| 	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", { | ||||
| irc:register_bot_command("whereis", { | ||||
| 	params = "<player>", | ||||
| 	description = "Tell the location of <player>", | ||||
| 	func = function(_, args) | ||||
| 	func = function(user, args) | ||||
| 		if args == "" then | ||||
| 			return false, "Player name required." | ||||
| 		end | ||||
| @@ -146,9 +124,9 @@ irc.register_bot_command("whereis", { | ||||
|  | ||||
|  | ||||
| local starttime = os.time() | ||||
| irc.register_bot_command("uptime", { | ||||
| irc:register_bot_command("uptime", { | ||||
| 	description = "Tell how much time the server has been up", | ||||
| 	func = function() | ||||
| 	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" | ||||
| @@ -161,9 +139,9 @@ irc.register_bot_command("uptime", { | ||||
| }) | ||||
|  | ||||
|  | ||||
| irc.register_bot_command("players", { | ||||
| irc:register_bot_command("players", { | ||||
| 	description = "List the players on the server", | ||||
| 	func = function() | ||||
| 	func = function(user, args) | ||||
| 		local players = minetest.get_connected_players() | ||||
| 		local names = {} | ||||
| 		for _, player in pairs(players) do | ||||
|   | ||||
							
								
								
									
										11
									
								
								callback.lua
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								callback.lua
									
									
									
									
									
								
							| @@ -5,16 +5,15 @@ | ||||
| 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") | ||||
| 		irc:say("*** "..name.." joined the game") | ||||
| 	end | ||||
| end) | ||||
|  | ||||
|  | ||||
| minetest.register_on_leaveplayer(function(player, timed_out) | ||||
| 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".. | ||||
| 				(timed_out and " (Timed out)" or "")) | ||||
| 		irc:say("*** "..name.." left the game") | ||||
| 	end | ||||
| end) | ||||
|  | ||||
| @@ -31,11 +30,11 @@ minetest.register_on_chat_message(function(name, message) | ||||
| 	if nl then | ||||
| 		message = message:sub(1, nl - 1) | ||||
| 	end | ||||
| 	irc.say(irc.playerMessage(name, core.strip_colors(message))) | ||||
| 	irc:say(irc:playerMessage(name, message)) | ||||
| end) | ||||
|  | ||||
|  | ||||
| minetest.register_on_shutdown(function() | ||||
| 	irc.disconnect("Game shutting down.") | ||||
| 	irc:disconnect("Game shutting down.") | ||||
| end) | ||||
|  | ||||
|   | ||||
							
								
								
									
										78
									
								
								chatcmds.lua
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								chatcmds.lua
									
									
									
									
									
								
							| @@ -11,30 +11,32 @@ minetest.register_chatcommand("irc_msg", { | ||||
| 	privs = {shout=true}, | ||||
| 	func = function(name, param) | ||||
| 		if not irc.connected then | ||||
| 			return false, "Not connected to IRC. Use /irc_connect to connect." | ||||
| 			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 | ||||
| 			return false, "Invalid usage, see /help irc_msg." | ||||
| 			minetest.chat_send_player(name, "Invalid usage, see /help irc_msg.") | ||||
| 			return | ||||
| 		end | ||||
| 		local toname_l = toname:lower() | ||||
| 		local validNick = false | ||||
| 		local hint = "They have to be in the channel" | ||||
| 		for nick in pairs(irc.conn.channels[irc.config.channel].users) do | ||||
| 		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 | ||||
| 			hint = "it looks like a bot or service" | ||||
| 			validNick = false | ||||
| 		end | ||||
| 		if not validNick then | ||||
| 			return false, "You can not message that user. ("..hint..")" | ||||
| 			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)) | ||||
| 		return true, "Message sent!" | ||||
| 		irc:say(toname, irc:playerMessage(name, message)) | ||||
| 		minetest.chat_send_player(name, "Message sent!") | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -42,15 +44,16 @@ minetest.register_chatcommand("irc_msg", { | ||||
| minetest.register_chatcommand("irc_names", { | ||||
| 	params = "", | ||||
| 	description = "List the users in IRC.", | ||||
| 	func = function() | ||||
| 	func = function(name, params) | ||||
| 		if not irc.connected then | ||||
| 			return false, "Not connected to IRC. Use /irc_connect to connect." | ||||
| 			minetest.chat_send_player(name, "Not connected to IRC. Use /irc_connect to connect.") | ||||
| 			return | ||||
| 		end | ||||
| 		local users = { } | ||||
| 		for nick in pairs(irc.conn.channels[irc.config.channel].users) do | ||||
| 			table.insert(users, nick) | ||||
| 		for k, v in pairs(irc.conn.channels[irc.config.channel].users) do | ||||
| 			table.insert(users, k) | ||||
| 		end | ||||
| 		return true, "Users in IRC: "..table.concat(users, ", ") | ||||
| 		minetest.chat_send_player(name, "Users in IRC: "..table.concat(users, ", ")) | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -58,12 +61,13 @@ minetest.register_chatcommand("irc_names", { | ||||
| minetest.register_chatcommand("irc_connect", { | ||||
| 	description = "Connect to the IRC server.", | ||||
| 	privs = {irc_admin=true}, | ||||
| 	func = function(name) | ||||
| 	func = function(name, param) | ||||
| 		if irc.connected then | ||||
| 			return false, "You are already connected to IRC." | ||||
| 			minetest.chat_send_player(name, "You are already connected to IRC.") | ||||
| 			return | ||||
| 		end | ||||
| 		minetest.chat_send_player(name, "IRC: Connecting...") | ||||
| 		irc.connect() | ||||
| 		irc:connect() | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -74,12 +78,13 @@ minetest.register_chatcommand("irc_disconnect", { | ||||
| 	privs = {irc_admin=true}, | ||||
| 	func = function(name, param) | ||||
| 		if not irc.connected then | ||||
| 			return false, "Not connected to IRC. Use /irc_connect to connect." | ||||
| 			minetest.chat_send_player(name, "You are not connected to IRC.") | ||||
| 			return | ||||
| 		end | ||||
| 		if param == "" then | ||||
| 			param = "Manual disconnect by "..name | ||||
| 		if params == "" then | ||||
| 			params = "Manual disconnect by "..name | ||||
| 		end | ||||
| 		irc.disconnect(param) | ||||
| 		irc:disconnect(param) | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -87,13 +92,13 @@ minetest.register_chatcommand("irc_disconnect", { | ||||
| minetest.register_chatcommand("irc_reconnect", { | ||||
| 	description = "Reconnect to the IRC server.", | ||||
| 	privs = {irc_admin=true}, | ||||
| 	func = function(name) | ||||
| 	func = function(name, param) | ||||
| 		if not irc.connected then | ||||
| 			return false, "Not connected to IRC. Use /irc_connect to connect." | ||||
| 			minetest.chat_send_player(name, "You are not connected to IRC.") | ||||
| 			return | ||||
| 		end | ||||
| 		minetest.chat_send_player(name, "IRC: Reconnecting...") | ||||
| 		irc.disconnect("Reconnecting...") | ||||
| 		irc.connect() | ||||
| 		irc:disconnect("Reconnecting...") | ||||
| 		irc:connect() | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -104,31 +109,18 @@ minetest.register_chatcommand("irc_quote", { | ||||
| 	privs = {irc_admin=true}, | ||||
| 	func = function(name, param) | ||||
| 		if not irc.connected then | ||||
| 			return false, "Not connected to IRC. Use /irc_connect to connect." | ||||
| 			minetest.chat_send_player(name, "You are not connected to IRC.") | ||||
| 			return | ||||
| 		end | ||||
| 		irc.queue(param) | ||||
| 		irc:queue(param) | ||||
| 		minetest.chat_send_player(name, "Command sent!") | ||||
| 	end | ||||
| }) | ||||
|  | ||||
|  | ||||
| local oldme = minetest.chatcommands["me"].func | ||||
| -- luacheck: ignore | ||||
| minetest.chatcommands["me"].func = function(name, param, ...) | ||||
| 	irc.say(("* %s %s"):format(name, param)) | ||||
| 	return oldme(name, param, ...) | ||||
| 	oldme(name, param, ...) | ||||
| 	irc:say(("* %s %s"):format(name, param)) | ||||
| end | ||||
|  | ||||
| if irc.config.send_kicks and minetest.chatcommands["kick"] then | ||||
| 	local oldkick = minetest.chatcommands["kick"].func | ||||
| 	-- luacheck: ignore | ||||
| 	minetest.chatcommands["kick"].func = function(name, param, ...) | ||||
| 		local plname, reason = param:match("^(%S+)%s*(.*)$") | ||||
| 		if not plname then | ||||
| 			return false, "Usage: /kick player [reason]" | ||||
| 		end | ||||
| 		irc.say(("*** Kicked %s.%s"):format(name, | ||||
| 				reason~="" and " Reason: "..reason or "")) | ||||
| 		return oldkick(name, param, ...) | ||||
| 	end | ||||
| end | ||||
|   | ||||
							
								
								
									
										31
									
								
								config.lua
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								config.lua
									
									
									
									
									
								
							| @@ -6,24 +6,12 @@ irc.config = {} | ||||
|  | ||||
| local function setting(stype, name, default, required) | ||||
| 	local value | ||||
| 	if minetest.settings and minetest.settings.get and minetest.settings.get_bool then | ||||
| 		-- The current methods for getting settings | ||||
| 		if stype == "bool" then | ||||
| 			value = minetest.settings:get_bool("irc."..name) | ||||
| 		elseif stype == "string" then | ||||
| 			value = minetest.settings:get("irc."..name) | ||||
| 		elseif stype == "number" then | ||||
| 			value = tonumber(minetest.settings:get("irc."..name)) | ||||
| 		end | ||||
| 	else | ||||
| 		-- The old methods for getting settings for backward compatibility. Deprecated on 0.4.16+ | ||||
| 		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 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 | ||||
| @@ -44,13 +32,10 @@ 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", "username", "Minetest") -- Username/ident | ||||
| setting("string", "realname", "Minetest") -- Real name/GECOS | ||||
| 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 | ||||
| setting("bool",   "send_kicks", false) -- Whether to send player kicked messages to the channel | ||||
|  | ||||
| ----------------------- | ||||
| -- ADVANCED SETTINGS -- | ||||
| @@ -59,11 +44,9 @@ setting("bool",   "send_kicks", false) -- Whether to send player kicked messages | ||||
| 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("number", "reconnect", 600) -- Time between reconnection attempts, 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 | ||||
| setting("string", "chat_color", "#339933") -- Color of IRC chat in-game, green by default | ||||
| setting("string", "pm_color", "#8800AA") -- Color of IRC PMs in-game, purple by default | ||||
|  | ||||
|   | ||||
| @@ -1,4 +0,0 @@ | ||||
| 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. | ||||
							
								
								
									
										90
									
								
								hooks.lua
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								hooks.lua
									
									
									
									
									
								
							| @@ -1,16 +1,19 @@ | ||||
| -- 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 | ||||
| local b64e = require("mime").b64 | ||||
|  | ||||
| irc.hooks = {} | ||||
| irc.registered_hooks = {} | ||||
|  | ||||
|  | ||||
| local stripped_chars = "[\2\31]" | ||||
| -- 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 | ||||
| @@ -20,8 +23,8 @@ local function normalize(text) | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.doHook(conn) | ||||
| 	for name, hook in pairs(irc.registered_hooks) do | ||||
| function irc:doHook(conn) | ||||
| 	for name, hook in pairs(self.registered_hooks) do | ||||
| 		for _, func in pairs(hook) do | ||||
| 			conn:hook(name, func) | ||||
| 		end | ||||
| @@ -29,9 +32,9 @@ function irc.doHook(conn) | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.register_hook(name, func) | ||||
| 	irc.registered_hooks[name] = irc.registered_hooks[name] or {} | ||||
| 	table.insert(irc.registered_hooks[name], func) | ||||
| function irc:register_hook(name, func) | ||||
| 	self.registered_hooks[name] = self.registered_hooks[name] or {} | ||||
| 	table.insert(self.registered_hooks[name], func) | ||||
| end | ||||
|  | ||||
|  | ||||
| @@ -80,13 +83,13 @@ function irc.hooks.ctcp(msg) | ||||
| 	local command = args[1]:upper() | ||||
|  | ||||
| 	local function reply(s) | ||||
| 		irc.queue(irc.msgs.notice(msg.user.nick, | ||||
| 		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)) | ||||
| 		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)) | ||||
| @@ -101,12 +104,11 @@ end | ||||
| function irc.hooks.channelChat(msg) | ||||
| 	local text = normalize(msg.args[2]) | ||||
|  | ||||
| 	irc.check_botcmd(msg) | ||||
| 	irc:check_botcmd(msg) | ||||
|  | ||||
| 	-- Don't let a user impersonate someone else by using the nick "IRC" | ||||
| 	local fake = msg.user.nick:lower():match("^[il|]rc$") | ||||
| 	if fake then | ||||
| 		irc.sendLocal("<"..msg.user.nick.."@IRC> "..text) | ||||
| 	if msg.user.nick == "IRC" then | ||||
| 		irc:sendLocal("<IRC@IRC> "..text) | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| @@ -126,19 +128,19 @@ function irc.hooks.channelChat(msg) | ||||
| 	if text:sub(1, 5) == "[off]" then | ||||
| 		return | ||||
| 	elseif foundchat then | ||||
| 		irc.sendLocal(("<%s@%s> %s") | ||||
| 		irc:sendLocal(("<%s@%s> %s") | ||||
| 				:format(chatnick, msg.user.nick, chatmessage)) | ||||
| 	elseif foundjoin then | ||||
| 		irc.sendLocal(("*** %s joined %s") | ||||
| 		irc:sendLocal(("*** %s joined %s") | ||||
| 				:format(joinnick, msg.user.nick)) | ||||
| 	elseif foundleave then | ||||
| 		irc.sendLocal(("*** %s left %s") | ||||
| 		irc:sendLocal(("*** %s left %s") | ||||
| 				:format(leavenick, msg.user.nick)) | ||||
| 	elseif foundaction then | ||||
| 		irc.sendLocal(("* %s@%s %s") | ||||
| 		irc:sendLocal(("* %s@%s %s") | ||||
| 				:format(actionnick, msg.user.nick, actionmessage)) | ||||
| 	else | ||||
| 		irc.sendLocal(("<%s@IRC> %s"):format(msg.user.nick, text)) | ||||
| 		irc:sendLocal(("<%s@IRC> %s"):format(msg.user.nick, text)) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| @@ -150,16 +152,16 @@ function irc.hooks.pm(msg) | ||||
| 	if prefix and text:sub(1, #prefix) == prefix then | ||||
| 		text = text:sub(#prefix + 1) | ||||
| 	end | ||||
| 	irc.bot_command(msg, text) | ||||
| 	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") | ||||
| 		irc:disconnect("Kicked") | ||||
| 	else | ||||
| 		irc.sendLocal(("-!- %s was kicked from %s by %s [%s]") | ||||
| 		irc:sendLocal(("-!- %s was kicked from %s by %s [%s]") | ||||
| 				:format(target, channel, prefix.nick, reason)) | ||||
| 	end | ||||
| end | ||||
| @@ -167,7 +169,7 @@ end | ||||
|  | ||||
| function irc.hooks.notice(user, target, message) | ||||
| 	if user.nick and target == irc.config.channel then | ||||
| 		irc.sendLocal("-"..user.nick.."@IRC- "..message) | ||||
| 		irc:sendLocal("-"..user.nick.."@IRC- "..message) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| @@ -188,31 +190,31 @@ end | ||||
|  | ||||
|  | ||||
| function irc.hooks.nick(user, newNick) | ||||
| 	irc.sendLocal(("-!- %s is now known as %s") | ||||
| 	irc:sendLocal(("-!- %s is now known as %s") | ||||
| 			:format(user.nick, newNick)) | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.hooks.join(user, channel) | ||||
| 	irc.sendLocal(("-!- %s joined %s") | ||||
| 	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]") | ||||
| 	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]") | ||||
| 	irc:sendLocal(("-!- %s has quit [%s]") | ||||
| 			:format(user.nick, reason)) | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.hooks.disconnect(_, isError) | ||||
| function irc.hooks.disconnect(message, isError) | ||||
| 	irc.connected = false | ||||
| 	if isError then | ||||
| 		minetest.log("error",  "IRC: Error: Disconnected, reconnecting in one minute.") | ||||
| @@ -240,19 +242,19 @@ function irc.hooks.preregister(conn) | ||||
| 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) | ||||
| 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) | ||||
|  | ||||
|   | ||||
							
								
								
									
										199
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								init.lua
									
									
									
									
									
								
							| @@ -3,49 +3,24 @@ | ||||
|  | ||||
| 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 = | ||||
| package.path = | ||||
| 		-- To find LuaIRC's init.lua | ||||
| 		modpath.."/?/init.lua;" | ||||
| 		-- For LuaIRC to find its files | ||||
| 		..modpath.."/?.lua;" | ||||
| 		..ie.package.path | ||||
| 		..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 rawget(_G, "jit") and package.config:sub(1, 1) == "/" then | ||||
|  | ||||
| 	ie.package.path = ie.package.path.. | ||||
| 	package.path = package.path.. | ||||
| 			";/usr/share/lua/5.1/?.lua".. | ||||
| 			";/usr/share/lua/5.1/?/init.lua" | ||||
|  | ||||
| 	ie.package.cpath = ie.package.cpath.. | ||||
| 	package.cpath = package.cpath.. | ||||
| 			";/usr/lib/lua/5.1/?.so" | ||||
|  | ||||
| 	ie.package.cpath = "/usr/lib/x86_64-linux-gnu/lua/5.1/?.so;"..ie.package.cpath | ||||
|  | ||||
|  | ||||
| end | ||||
|  | ||||
| -- Temporarily set require so that LuaIRC can access it | ||||
| local old_require = require | ||||
| require = ie.require | ||||
|  | ||||
| -- Silence warnings about `module` in `ltn12`. | ||||
| local old_module = rawget(_G, "module") | ||||
| rawset(_G, "module", ie.module) | ||||
|  | ||||
| local lib = ie.require("irc") | ||||
|  | ||||
| irc = { | ||||
| 	version = "0.2.0", | ||||
| 	connected = false, | ||||
| @@ -54,58 +29,22 @@ irc = { | ||||
| 	recent_message_count = 0, | ||||
| 	joined_players = {}, | ||||
| 	modpath = modpath, | ||||
| 	lib = lib, | ||||
| 	lib = require("irc"), | ||||
| } | ||||
|  | ||||
| -- Compatibility | ||||
| rawset(_G, "mt_irc", irc) | ||||
|  | ||||
| local getinfo = debug.getinfo | ||||
| local warned = { } | ||||
|  | ||||
| local function warn_deprecated(k) | ||||
| 	local info = getinfo(3) | ||||
| 	local loc = info.source..":"..info.currentline | ||||
| 	if warned[loc] then return end | ||||
| 	warned[loc] = true | ||||
| 	print("COLON: "..tostring(k)) | ||||
| 	minetest.log("warning", "Deprecated use of colon notation when calling" | ||||
| 			.." method `"..tostring(k).."` at "..loc) | ||||
| end | ||||
|  | ||||
| -- This is a hack. | ||||
| setmetatable(irc, { | ||||
| 	__newindex = function(t, k, v) | ||||
| 		if type(v) == "function" then | ||||
| 			local f = v | ||||
| 			v = function(me, ...) | ||||
| 				if rawequal(me, t) then | ||||
| 					warn_deprecated(k) | ||||
| 					return f(...) | ||||
| 				else | ||||
| 					return f(me, ...) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 		rawset(t, k, v) | ||||
| 	end, | ||||
| }) | ||||
| mt_irc = irc | ||||
|  | ||||
| dofile(modpath.."/config.lua") | ||||
| dofile(modpath.."/messages.lua") | ||||
| loadfile(modpath.."/hooks.lua")(ie) | ||||
| dofile(modpath.."/hooks.lua") | ||||
| dofile(modpath.."/callback.lua") | ||||
| dofile(modpath.."/chatcmds.lua") | ||||
| dofile(modpath.."/botcmds.lua") | ||||
|  | ||||
| -- Restore old (safe) functions | ||||
| require = old_require | ||||
| rawset(_G, "module", old_module) | ||||
|  | ||||
| if irc.config.enable_player_part then | ||||
| 	dofile(modpath.."/player_part.lua") | ||||
| else | ||||
| 	setmetatable(irc.joined_players, {__index = function() return true end}) | ||||
| 	setmetatable(irc.joined_players, {__index = function(index) return true end}) | ||||
| end | ||||
|  | ||||
| minetest.register_privilege("irc_admin", { | ||||
| @@ -115,20 +54,20 @@ minetest.register_privilege("irc_admin", { | ||||
|  | ||||
| local stepnum = 0 | ||||
|  | ||||
| minetest.register_globalstep(function(dtime) return irc.step(dtime) end) | ||||
| minetest.register_globalstep(function(dtime) return irc:step(dtime) end) | ||||
|  | ||||
| function irc.step() | ||||
| function irc:step(dtime) | ||||
| 	if stepnum == 3 then | ||||
| 		if irc.config.auto_connect then | ||||
| 			irc.connect() | ||||
| 		if self.config.auto_connect then | ||||
| 			self:connect() | ||||
| 		end | ||||
| 	end | ||||
| 	stepnum = stepnum + 1 | ||||
|  | ||||
| 	if not irc.connected then return end | ||||
| 	if not self.connected then return end | ||||
|  | ||||
| 	-- Hooks will manage incoming messages and errors | ||||
| 	local good, err = xpcall(function() irc.conn:think() end, debug.traceback) | ||||
| 	local good, err = xpcall(function() self.conn:think() end, debug.traceback) | ||||
| 	if not good then | ||||
| 		print(err) | ||||
| 		return | ||||
| @@ -136,90 +75,104 @@ function irc.step() | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.connect() | ||||
| 	if irc.connected then | ||||
| function irc:connect() | ||||
| 	if self.connected then | ||||
| 		minetest.log("error", "IRC: Ignoring attempt to connect when already connected.") | ||||
| 		return | ||||
| 	end | ||||
| 	irc.conn = irc.lib.new({ | ||||
| 		nick = irc.config.nick, | ||||
| 		username = irc.config.username, | ||||
| 		realname = irc.config.realname, | ||||
| 	self.conn = irc.lib.new({ | ||||
| 		nick = self.config.nick, | ||||
| 		username = "Minetest", | ||||
| 		realname = "Minetest", | ||||
| 	}) | ||||
| 	irc.doHook(irc.conn) | ||||
|  | ||||
| 	-- We need to swap the `require` function again since | ||||
| 	-- LuaIRC `require`s `ssl` if `irc.secure` is true. | ||||
| 	old_require = require | ||||
| 	require = ie.require | ||||
|  | ||||
| 	self:doHook(self.conn) | ||||
| 	local good, message = pcall(function() | ||||
| 		irc.conn:connect({ | ||||
| 			host = irc.config.server, | ||||
| 			port = irc.config.port, | ||||
| 			password = irc.config.password, | ||||
| 			timeout = irc.config.timeout, | ||||
| 			reconnect = irc.config.reconnect, | ||||
| 			secure = irc.config.secure | ||||
| 		self.conn:connect({ | ||||
| 			host = self.config.server, | ||||
| 			port = self.config.port, | ||||
| 			password = self.config.password, | ||||
| 			timeout = self.config.timeout, | ||||
| 			secure = self.config.secure | ||||
| 		}) | ||||
| 	end) | ||||
|  | ||||
| 	require = old_require | ||||
|  | ||||
| 	if not good then | ||||
| 		minetest.log("error", ("IRC: Connection error: %s: %s -- Reconnecting in %d seconds...") | ||||
| 					:format(irc.config.server, message, irc.config.reconnect)) | ||||
| 		minetest.after(irc.config.reconnect, function() irc.connect() end) | ||||
| 		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 irc.config.NSPass then | ||||
| 		irc.conn:queue(irc.msgs.privmsg( | ||||
| 				"NickServ", "IDENTIFY "..irc.config.NSPass)) | ||||
| 	if self.config.NSPass then | ||||
| 		self:say("NickServ", "IDENTIFY "..self.config.NSPass) | ||||
| 	end | ||||
|  | ||||
| 	irc.conn:join(irc.config.channel, irc.config.key) | ||||
| 	irc.connected = true | ||||
| 	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 irc.connected then | ||||
| 		--The OnDisconnect hook will clear irc.connected and print a disconnect message | ||||
| 		irc.conn:disconnect(message) | ||||
| 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) | ||||
| -- Split messages into smaller messages of this size to avoid cutting | ||||
| -- off large messages at the end. | ||||
| -- Note: RFC 2812 specifies a maximum of 512 characters per "line" | ||||
| -- (that includes the command, parameter(s), and the "\r\n" at the | ||||
| -- end). We just use a smaller number to avoid having to compute the | ||||
| -- actual max length ourselves, and because it makes it a nice round | ||||
| -- number :) | ||||
| local MESSAGE_CHUNK_SIZE = 400 | ||||
|  | ||||
| -- Maximum message size processed. | ||||
| local MESSAGE_MAX_SIZE = MESSAGE_CHUNK_SIZE * 4 | ||||
|  | ||||
| function irc:say(to, message) | ||||
| 	if not message then | ||||
| 		message = to | ||||
| 		to = irc.config.channel | ||||
| 		to = self.config.channel | ||||
| 	end | ||||
| 	to = to or irc.config.channel | ||||
| 	to = to or self.config.channel | ||||
|  | ||||
| 	irc.queue(irc.msgs.privmsg(to, message)) | ||||
| 	message = message:sub(1, MESSAGE_MAX_SIZE) | ||||
|  | ||||
| 	-- Split the message into MESSAGE_CHUNK_SIZE chunks and queue each | ||||
| 	-- chunk as a separate message. The message is split into at most | ||||
| 	-- MAX_CHUNKS chunks. The rest of the message is dropped to prevent | ||||
| 	-- flooding and/or locking up the server. | ||||
| 	local msglen = #message | ||||
| 	for pos = 1, msglen, MESSAGE_CHUNK_SIZE do | ||||
| 		-- If we have more text to show, indicate so by appending an | ||||
| 		-- ellipsis to this line. | ||||
| 		local endl = (pos <= (msglen - MESSAGE_CHUNK_SIZE)) and "\2[…more…]\2" or "" | ||||
| 		self:queue(irc.msgs.privmsg(to, | ||||
| 				message:sub(pos, pos + MESSAGE_CHUNK_SIZE - 1)..endl)) | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| function irc.reply(message) | ||||
| 	if not irc.last_from then | ||||
| function irc:reply(message) | ||||
| 	if not self.last_from then | ||||
| 		return | ||||
| 	end | ||||
| 	message = message:gsub("[\r\n%z]", " \\n ") | ||||
| 	irc.say(irc.last_from, message) | ||||
| 	self:say(self.last_from, message) | ||||
| end | ||||
|  | ||||
| function irc.send(msg) | ||||
| 	if not irc.connected then return end | ||||
| 	irc.conn:send(msg) | ||||
| function irc:send(msg) | ||||
| 	if not self.connected then return end | ||||
| 	self.conn:send(msg) | ||||
| end | ||||
|  | ||||
| function irc.queue(msg) | ||||
| 	if not irc.connected then return end | ||||
| 	irc.conn:queue(msg) | ||||
| function irc:queue(msg) | ||||
| 	if not self.connected then return end | ||||
| 	self.conn:queue(msg) | ||||
| end | ||||
|  | ||||
| minetest.log("action", "[irc] loaded.") | ||||
|   | ||||
							
								
								
									
										2
									
								
								irc
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								irc
									
									
									
									
									
								
							 Submodule irc updated: b8d594e651...e49a52ede1
									
								
							
							
								
								
									
										12
									
								
								messages.lua
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								messages.lua
									
									
									
									
									
								
							| @@ -3,15 +3,11 @@ | ||||
|  | ||||
| irc.msgs = irc.lib.msgs | ||||
|  | ||||
| function irc.logChat(message) | ||||
| 	minetest.log("action", "IRC CHAT: "..message) | ||||
| function irc:sendLocal(message) | ||||
| 	minetest.chat_send_all(message) | ||||
| end | ||||
|  | ||||
| function irc.sendLocal(message) | ||||
| 	minetest.chat_send_all(minetest.colorize(irc.config.chat_color, message)) | ||||
| 	irc.logChat(message) | ||||
| end | ||||
|  | ||||
| function irc.playerMessage(name, message) | ||||
| function irc:playerMessage(name, message) | ||||
| 	return ("<%s> %s"):format(name, message) | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -2,52 +2,50 @@ | ||||
| -- See LICENSE.txt for details. | ||||
|  | ||||
|  | ||||
| function irc.player_part(name) | ||||
| 	if not irc.joined_players[name] then | ||||
| 		return false, "You are not in the channel" | ||||
| 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 | ||||
| 	irc.joined_players[name] = nil | ||||
| 	return true, "You left the channel" | ||||
| 	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 irc.joined_players[name] then | ||||
| 		return false, "You are already in the channel" | ||||
| 	elseif not minetest.get_player_by_name(name) then | ||||
| 		return false, "You need to be in-game to join the channel" | ||||
| 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 | ||||
| 	irc.joined_players[name] = true | ||||
| 	return true, "You joined the channel" | ||||
| 	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) | ||||
| 		return irc.player_join(name) | ||||
| 	func = function(name, param) | ||||
| 		irc:player_join(name) | ||||
| 	end | ||||
| }) | ||||
|   | ||||
| minetest.register_chatcommand("part", { | ||||
| 	description = "Part the IRC channel", | ||||
| 	privs = {shout=true}, | ||||
| 	func = function(name) | ||||
| 		return irc.player_part(name) | ||||
| 	func = function(name, param) | ||||
| 		irc:player_part(name) | ||||
| 	end | ||||
| }) | ||||
|   | ||||
| minetest.register_chatcommand("who", { | ||||
| 	description = "Tell who is currently on the channel", | ||||
| 	privs = {}, | ||||
| 	func = function() | ||||
| 		local out, n = { }, 0 | ||||
| 		for plname in pairs(irc.joined_players) do | ||||
| 			n = n + 1 | ||||
| 			out[n] = plname | ||||
| 	func = function(name, param) | ||||
| 		local s = "" | ||||
| 		for name, _ in pairs(irc.joined_players) do | ||||
| 			s = s..", "..name | ||||
| 		end | ||||
| 		table.sort(out) | ||||
| 		return true, "Players in channel: "..table.concat(out, ", ") | ||||
| 		minetest.chat_send_player(name, "Players On Channel:"..s) | ||||
| 	end | ||||
| }) | ||||
|  | ||||
| @@ -63,10 +61,9 @@ minetest.register_on_leaveplayer(function(player) | ||||
| 	irc.joined_players[name] = nil | ||||
| end) | ||||
|  | ||||
| function irc.sendLocal(message) | ||||
| 	for name, _ in pairs(irc.joined_players) do | ||||
| 		minetest.chat_send_player(name, | ||||
| 					minetest.colorize(irc.config.chat_color, message)) | ||||
| function irc:sendLocal(message) | ||||
|         for name, _ in pairs(self.joined_players) do | ||||
| 		minetest.chat_send_player(name, message) | ||||
| 	end | ||||
| 	irc.logChat(message) | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -1,75 +0,0 @@ | ||||
|  | ||||
| [Basic] | ||||
|  | ||||
| # Whether to automatically connect to the server on mod load. | ||||
| # If false, you must use /irc_connect to connect. | ||||
| irc.auto_connect (Auto-connect on load) bool true | ||||
|  | ||||
| # Nickname for the bot. May only contain characters A-Z, 0-9 | ||||
| # '{', '}', '[', ']', '|', '^', '-', or '_'. | ||||
| irc.nick (Bot nickname) string Minetest | ||||
|  | ||||
| # Server to connect to. | ||||
| irc.server (IRC server) string irc.freenode.net | ||||
|  | ||||
| # Server port. | ||||
| # The standard IRC protocol port is 6667 for regular servers, | ||||
| # or 6697 for SSL-enabled servers. | ||||
| # If unsure, leave at 6667. | ||||
| irc.port (IRC server port) int 6667 1 65535 | ||||
|  | ||||
| # Channel the bot joins after connecting. | ||||
| irc.channel (Channel to join) string ##mt-irc-mod | ||||
|  | ||||
| [Authentication] | ||||
|  | ||||
| # Password for authenticating to NickServ. | ||||
| # Leave empty to not authenticate with NickServ. | ||||
| irc.NSPass (NickServ password) string | ||||
|  | ||||
| # IRC server password. | ||||
| # Leave empty for no password. | ||||
| irc.password (Server password) string | ||||
|  | ||||
| # Password for joining the channel. | ||||
| # Leave empty if your channel is not protected. | ||||
| irc.key (Channel key) string | ||||
|  | ||||
| # Enable TLS connection. | ||||
| # Requires LuaSEC <https://github.com/brunoos/luasec>. | ||||
| irc.secure (Use TLS) bool false | ||||
|  | ||||
| # Username for SASL authentication. | ||||
| # Leave empty to use the nickname. | ||||
| irc.sasl.user (SASL username) string | ||||
|  | ||||
| # Password for SASL authentication. | ||||
| # Leave empty to not authenticate via SASL. | ||||
| irc.sasl.pass (SASL password) string | ||||
|  | ||||
| [Advanced] | ||||
|  | ||||
| # Enable this to make the bot send messages when players join | ||||
| # or leave the game server. | ||||
| irc.send_join_part (Send join and part messages) bool true | ||||
|  | ||||
| # Enable this to make the bot send messages when players are kicked. | ||||
| irc.send_kicks (Send kick messages) bool false | ||||
|  | ||||
| # Underlying socket timeout in seconds. | ||||
| irc.timeout (Timeout) int 60 1 | ||||
|  | ||||
| # Time between reconnection attempts, in seconds. | ||||
| irc.reconnect (Reconnect delay) int 600 1 | ||||
|  | ||||
| # Prefix to use for bot commands. | ||||
| irc.command_prefix (Command prefix) string | ||||
|  | ||||
| # Enable debug output. | ||||
| irc.debug (Debug mode) bool false | ||||
|  | ||||
| # Whether to enable players joining and parting the channel. | ||||
| irc.enable_player_part (Allow player join/part) bool true | ||||
|  | ||||
| # Whether to automatically show players in the channel when they join. | ||||
| irc.auto_join (Auto join players) bool true | ||||
		Reference in New Issue
	
	Block a user