minetest_modding_book/_en/players/chat.md

179 lines
5.4 KiB
Markdown
Raw Normal View History

2015-09-25 02:00:15 +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
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
To send a message to every player in the game, call the chat_send_all function.
2015-09-25 02:00:15 +03:00
```lua
2015-09-25 02:00:15 +03:00
minetest.chat_send_all("This is a chat message to all players")
```
2015-09-25 02:00:15 +03:00
Here is an example of how this appears in-game:
2015-09-25 02:00:15 +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
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
To send a message to a specific player, call the chat_send_player function:
2015-09-25 02:00:15 +03:00
```lua
2015-09-25 02:00:15 +03:00
minetest.chat_send_player("player1", "This is a chat message for player1")
```
2015-09-25 02:00:15 +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
To register a chat command, for example /foo, use register_chatcommand:
2015-09-25 02:00:15 +03:00
```lua
2015-09-25 02:00:15 +03:00
minetest.register_chatcommand("foo", {
privs = {
interact = true
},
func = function(name, param)
return true, "You said " .. param .. "!"
end
2015-09-25 02:00:15 +03:00
})
```
2015-09-25 02:00:15 +03:00
Calling /foo bar will display `You said bar!` in the chat console.
2015-09-25 02:00:15 +03:00
You can restrict which players are able to run commands:
2015-09-25 02:00:15 +03:00
```lua
2015-09-25 02:00:15 +03:00
privs = {
interact = true
2015-09-25 02:00:15 +03:00
},
```
2015-09-25 02:00:15 +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
```lua
2015-09-25 02:00:15 +03:00
return true, "You said " .. param .. "!"
```
2015-09-25 02:00:15 +03:00
This returns two values, a Boolean which shows the command succeeded
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:
* `/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.
```lua
local to, msg = string.match(param, "^([%a%d_-]+) (*+)$")
```
The above implements `/msg <to> <message>`. Let's go through left to right:
* `^` 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
To intercept a message, use register_on_chat_message:
2015-09-25 02:00:15 +03:00
```lua
2015-09-25 02:00:15 +03:00
minetest.register_on_chat_message(function(name, message)
print(name .. " said " .. message)
return false
2015-09-25 02:00:15 +03:00
end)
```
2015-09-25 02:00:15 +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
```lua
2015-09-25 02:00:15 +03:00
minetest.register_on_chat_message(function(name, message)
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
print(name .. " tried to say " .. message .. " but doesn't have shout")
end
2015-09-25 02:00:15 +03:00
return false
2015-09-25 02:00:15 +03:00
end)
```