2015-09-25 02:00:15 +03:00
|
|
|
---
|
2015-09-25 02:01:52 +03:00
|
|
|
title: Chat and Commands
|
2015-09-25 02:00:15 +03:00
|
|
|
layout: default
|
2018-07-15 21:36:35 +03:00
|
|
|
root: ../..
|
2018-07-15 17:28:10 +03:00
|
|
|
idx: 4.2
|
|
|
|
description: Registering a chatcommand and handling chat messages with register_on_chat_message
|
2018-07-15 21:13:16 +03:00
|
|
|
redirect_from: /en/chapters/chat.html
|
2018-07-20 22:51:31 +03:00
|
|
|
cmd_online:
|
|
|
|
level: warning
|
|
|
|
title: Offline players can run commands
|
|
|
|
message: <p>A player name is passed instead of a player object, because mods
|
|
|
|
can run commands on behalf of offline players. For example, the IRC
|
|
|
|
bridge allows players to run commands without joining the game.</p>
|
|
|
|
|
|
|
|
<p>So make sure that you don't assume that the player is online.
|
|
|
|
You can check by seeing if minetest.get_player_by_name returns a player.</p>
|
|
|
|
|
|
|
|
cb_cmdsprivs:
|
|
|
|
level: warning
|
|
|
|
title: Privileges and Chat Commands
|
|
|
|
message: The shout privilege isn't needed for a player to trigger this callback.
|
|
|
|
This is because chat commands are implemented in Lua, and are just
|
|
|
|
chat messages that begin with a /.
|
|
|
|
|
2015-09-25 02:00:15 +03:00
|
|
|
---
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
Mods can interact with player chat, including
|
2015-09-25 02:00:15 +03:00
|
|
|
sending messages, intercepting messages and registering chat commands.
|
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
* [Sending Messages to All Players](#sending-messages-to-all-players)
|
|
|
|
* [Sending Messages to Specific Players](#sending-messages-to-specific-players)
|
|
|
|
* [Chat Commands](#chat-commands)
|
|
|
|
* [Complex Subcommands](#complex-subcommands)
|
|
|
|
* [Intercepting Messages](#intercepting-messages)
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
## Sending Messages to All Players
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
To send a message to every player in the game, call the chat_send_all function.
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
minetest.chat_send_all("This is a chat message to all players")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
Here is an example of how this appears in-game:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-26 21:01:51 +03:00
|
|
|
<player1> Look at this entrance
|
|
|
|
This is a chat message to all players
|
|
|
|
<player2> What about it?
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
The message appears on a separate line to distinguish it from in-game player chat.
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
## Sending Messages to Specific Players
|
2017-08-29 13:41:24 +03:00
|
|
|
|
|
|
|
To send a message to a specific player, call the chat_send_player function:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
minetest.chat_send_player("player1", "This is a chat message for player1")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
This message displays in the same manner as messages to all players, but is
|
|
|
|
only visible to the named player, in this case player1.
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
## Chat Commands
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
To register a chat command, for example /foo, use register_chatcommand:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
minetest.register_chatcommand("foo", {
|
2017-08-26 21:01:51 +03:00
|
|
|
privs = {
|
|
|
|
interact = true
|
|
|
|
},
|
|
|
|
func = function(name, param)
|
|
|
|
return true, "You said " .. param .. "!"
|
|
|
|
end
|
2015-09-25 02:00:15 +03:00
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
Calling /foo bar will display `You said bar!` in the chat console.
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
You can restrict which players are able to run commands:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
privs = {
|
2017-08-26 21:01:51 +03:00
|
|
|
interact = true
|
2015-09-25 02:00:15 +03:00
|
|
|
},
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
This means only players with the `interact` [privilege](privileges.html) can run the
|
|
|
|
command. Other players will see an error message informing them of which
|
|
|
|
privilege they're missing. If the player has the necessary privileges, the command
|
|
|
|
will run and the message will be sent:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
return true, "You said " .. param .. "!"
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-07-16 01:04:55 +03:00
|
|
|
This returns two values, a Boolean which shows the command succeeded
|
2017-08-29 13:41:24 +03:00
|
|
|
and the chat message to send to the player.
|
|
|
|
|
2018-07-20 22:51:31 +03:00
|
|
|
{% include notice.html notice=page.cmd_online %}
|
2016-01-08 17:01:10 +03:00
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
## Complex Subcommands
|
2016-06-17 03:08:44 +03:00
|
|
|
|
|
|
|
It is often required to make complex chat commands, such as:
|
|
|
|
|
2018-02-25 03:25:46 +03:00
|
|
|
* `/msg <to> <message>`
|
|
|
|
* `/team join <teamname>`
|
|
|
|
* `/team leave <teamname>`
|
|
|
|
* `/team list`
|
|
|
|
|
|
|
|
This is usually done using [Lua patterns](https://www.lua.org/pil/20.2.html).
|
|
|
|
Patterns are a way of extracting stuff from text using rules.
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2018-02-25 03:25:46 +03:00
|
|
|
local to, msg = string.match(param, "^([%a%d_-]+) (*+)$")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2018-02-25 03:25:46 +03:00
|
|
|
|
2018-07-16 01:04:55 +03:00
|
|
|
The above implements `/msg <to> <message>`. Let's go through left to right:
|
2018-02-25 03:25:46 +03:00
|
|
|
|
|
|
|
* `^` means match the start of the string.
|
|
|
|
* `()` is a matching group - anything that matches stuff in here will be
|
|
|
|
returned from string.match.
|
|
|
|
* `[]` means accept characters in this list.
|
|
|
|
* `%a` means accept any letter and `%d` means any digit.
|
|
|
|
* `[%d%a_-]` means accept any letter or digit or `_` or `-`.
|
|
|
|
* `+` means match the last thing one or more times.
|
|
|
|
* `*` means match any character in this context.
|
|
|
|
* `$` means match the end of the string.
|
|
|
|
|
|
|
|
Put simply, this matches the name (a word with only letters/numbers/-/_),
|
|
|
|
then a space, then the message (one of more of any character). The name and
|
|
|
|
message are returned, as they're surrounded in parentheses.
|
|
|
|
|
|
|
|
That's how most mods implement complex chat commands. A better guide to Lua
|
|
|
|
Patterns would probably be the
|
|
|
|
[lua-users.org tutorial](http://lua-users.org/wiki/PatternsTutorial)
|
|
|
|
or the [PIL documentation](https://www.lua.org/pil/20.2.html).
|
|
|
|
|
|
|
|
There is also a library written by the author of this book which can be used
|
|
|
|
to make complex chat commands without Patterns called
|
|
|
|
[ChatCmdBuilder](chat_complex.html).
|
2016-06-17 03:08:44 +03:00
|
|
|
|
|
|
|
|
2017-10-16 18:56:31 +03:00
|
|
|
## Intercepting Messages
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
To intercept a message, use register_on_chat_message:
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
minetest.register_on_chat_message(function(name, message)
|
2017-08-26 21:01:51 +03:00
|
|
|
print(name .. " said " .. message)
|
|
|
|
return false
|
2015-09-25 02:00:15 +03:00
|
|
|
end)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-29 13:41:24 +03:00
|
|
|
By returning false, you allow the chat message to be sent by the default
|
|
|
|
handler. You can actually remove the line `return false`, and it would still
|
2015-09-25 02:00:15 +03:00
|
|
|
work the same.
|
|
|
|
|
2018-07-20 22:51:31 +03:00
|
|
|
{% include notice.html notice=page.cb_cmdsprivs %}
|
|
|
|
|
|
|
|
You should make sure you take into account that it may be a chat command,
|
|
|
|
or the user may not have `shout`.
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-09-25 02:00:15 +03:00
|
|
|
minetest.register_on_chat_message(function(name, message)
|
2017-08-26 21:01:51 +03:00
|
|
|
if message:sub(1, 1) == "/" then
|
|
|
|
print(name .. " ran chat command")
|
2018-07-20 22:51:31 +03:00
|
|
|
elseif minetest.check_player_privs(name, { shout = true }) then
|
|
|
|
print(name .. " said " .. message)
|
|
|
|
else
|
2018-09-24 19:16:00 +03:00
|
|
|
print(name .. " tried to say " .. message ..
|
|
|
|
" but doesn't have shout")
|
2017-08-26 21:01:51 +03:00
|
|
|
end
|
2015-09-25 02:00:15 +03:00
|
|
|
|
2017-08-26 21:01:51 +03:00
|
|
|
return false
|
2015-09-25 02:00:15 +03:00
|
|
|
end)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|