2016-06-17 03:08:44 +03:00
|
|
|
---
|
2018-02-25 03:25:46 +03:00
|
|
|
title: Chat Command Builder
|
2016-06-17 03:08:44 +03:00
|
|
|
layout: default
|
2018-07-15 21:36:35 +03:00
|
|
|
root: ../..
|
2018-07-15 17:28:10 +03:00
|
|
|
idx: 4.3
|
|
|
|
description: Use ChatCmdBuilder to make a complex chat command
|
2018-07-15 21:13:16 +03:00
|
|
|
redirect_from: /en/chapters/chat_complex.html
|
2016-06-17 03:08:44 +03:00
|
|
|
---
|
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
## Introduction <!-- omit in toc -->
|
2016-06-17 03:08:44 +03:00
|
|
|
|
2018-02-25 03:25:46 +03:00
|
|
|
This chapter will show you how to make complex chat commands with ChatCmdBuilder,
|
|
|
|
such as `/msg <name> <message>`, `/team join <teamname>` or `/team leave <teamname>`.
|
|
|
|
|
|
|
|
Note that ChatCmdBuilder is a library created by the author of this book, and most
|
|
|
|
modders tend to use the method outlined in the
|
2019-05-31 20:32:40 +03:00
|
|
|
[Chat and Commands](chat.html#complex-subcommands) chapter.
|
2016-06-17 03:08:44 +03:00
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Why ChatCmdBuilder?](#why-chatcmdbuilder)
|
|
|
|
- [Routes](#routes)
|
|
|
|
- [Subcommand functions](#subcommand-functions)
|
|
|
|
- [Installing ChatCmdBuilder](#installing-chatcmdbuilder)
|
|
|
|
- [Admin complex command](#admin-complex-command)
|
2016-06-17 03:13:08 +03:00
|
|
|
|
2016-06-17 03:08:44 +03:00
|
|
|
## Why ChatCmdBuilder?
|
|
|
|
|
|
|
|
Traditionally mods implemented these complex commands using Lua patterns.
|
2016-06-17 03:22:13 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2016-06-17 03:22:13 +03:00
|
|
|
local name = string.match(param, "^join ([%a%d_-]+)")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2016-06-17 03:22:13 +03:00
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
I, however, find Lua patterns annoying to write and unreadable.
|
2016-06-17 03:08:44 +03:00
|
|
|
Because of this, I created a library to do this for you.
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2016-06-17 03:08:44 +03:00
|
|
|
ChatCmdBuilder.new("sethp", function(cmd)
|
2017-08-26 21:01:51 +03:00
|
|
|
cmd:sub(":target :hp:int", function(name, target, hp)
|
2019-05-31 20:32:40 +03:00
|
|
|
local player = minetest.get_player_by_name(target)
|
2017-08-26 21:01:51 +03:00
|
|
|
if player then
|
|
|
|
player:set_hp(hp)
|
|
|
|
return true, "Killed " .. target
|
|
|
|
else
|
|
|
|
return false, "Unable to find " .. target
|
|
|
|
end
|
|
|
|
end)
|
2016-06-17 03:08:44 +03:00
|
|
|
end, {
|
2017-08-26 21:01:51 +03:00
|
|
|
description = "Set hp of player",
|
|
|
|
privs = {
|
|
|
|
kick = true
|
|
|
|
-- ^ probably better to register a custom priv
|
|
|
|
}
|
2016-06-17 03:08:44 +03:00
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2016-06-17 03:08:44 +03:00
|
|
|
|
|
|
|
`ChatCmdBuilder.new(name, setup_func, def)` creates a new chat command called
|
|
|
|
`name`. It then calls the function passed to it (`setup_func`), which then creates
|
2019-05-31 20:32:40 +03:00
|
|
|
subcommands. Each `cmd:sub(route, func)` is a subcommand.
|
2016-06-17 03:08:44 +03:00
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
A subcommand is a particular response to an input param. When a player runs
|
|
|
|
the chat command, the first subcommand that matches their input will be run,
|
2018-07-16 01:04:55 +03:00
|
|
|
and no others. If no subcommands match, then the user will be told of the invalid
|
2016-06-17 03:08:44 +03:00
|
|
|
syntax. For example, in the above code snippet if a player
|
|
|
|
types something of the form `/sethp username 12` then the function passed
|
2018-07-16 01:04:55 +03:00
|
|
|
to cmd:sub will be called. If they type `/sethp 12 bleh`, then a wrong
|
2016-06-17 03:08:44 +03:00
|
|
|
input message will appear.
|
|
|
|
|
|
|
|
`:name :hp:int` is a route. It describes the format of the param passed to /teleport.
|
|
|
|
|
|
|
|
## Routes
|
|
|
|
|
|
|
|
A route is made up of terminals and variables. Terminals must always be there.
|
|
|
|
For example, `join` in `/team join :username :teamname`. The spaces also count
|
|
|
|
as terminals.
|
|
|
|
|
|
|
|
Variables can change value depending on what the user types. For example, `:username`
|
|
|
|
and `:teamname`.
|
|
|
|
|
2018-07-16 01:04:55 +03:00
|
|
|
Variables are defined as `:name:type`. The `name` is used in the help documentation.
|
2016-06-17 03:08:44 +03:00
|
|
|
The `type` is used to match the input. If the type is not given, then the type is
|
|
|
|
`word`.
|
|
|
|
|
|
|
|
Valid types are:
|
|
|
|
|
|
|
|
* `word` - default. Any string without spaces.
|
|
|
|
* `int` - Any integer/whole number, no decimals.
|
|
|
|
* `number` - Any number, including ints and decimals.
|
|
|
|
* `pos` - 1,2,3 or 1.1,2,3.4567 or (1,2,3) or 1.2, 2 ,3.2
|
|
|
|
* `text` - Any string. There can only ever be one text variable,
|
|
|
|
no variables or terminals can come afterwards.
|
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
In `:name :hp:int`, there are two variables:
|
2016-06-17 03:08:44 +03:00
|
|
|
|
|
|
|
* `name` - type of `word` as no type is specified. Accepts any string without spaces.
|
|
|
|
* `hp` - type of `int`
|
|
|
|
|
|
|
|
## Subcommand functions
|
|
|
|
|
|
|
|
The first argument is the caller's name. The variables are then passed to the
|
|
|
|
function in order.
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2016-06-17 03:08:44 +03:00
|
|
|
cmd:sub(":target :hp:int", function(name, target, hp)
|
2017-08-26 21:01:51 +03:00
|
|
|
-- subcommand function
|
2016-06-17 03:08:44 +03:00
|
|
|
end)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2016-06-17 03:08:44 +03:00
|
|
|
|
|
|
|
## Installing ChatCmdBuilder
|
|
|
|
|
2018-02-25 03:25:46 +03:00
|
|
|
The source code can be found and downloaded on
|
|
|
|
[Github](https://github.com/rubenwardy/ChatCmdBuilder/).
|
|
|
|
|
2016-06-17 03:08:44 +03:00
|
|
|
There are two ways to install:
|
|
|
|
|
|
|
|
1. Install ChatCmdBuilder as a mod and depend on it.
|
|
|
|
2. Include the init.lua file in ChatCmdBuilder as chatcmdbuilder.lua in your mod,
|
|
|
|
and dofile it.
|
|
|
|
|
|
|
|
## Admin complex command
|
|
|
|
|
|
|
|
Here is an example that creates a chat command that allows us to do this:
|
|
|
|
|
|
|
|
* `/admin kill <username>` - kill user
|
|
|
|
* `/admin move <username> to <pos>` - teleport user
|
|
|
|
* `/admin log <username>` - show report log
|
|
|
|
* `/admin log <username> <message>` - log to report log
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2016-06-17 03:08:44 +03:00
|
|
|
local admin_log
|
|
|
|
local function load()
|
2017-08-26 21:01:51 +03:00
|
|
|
admin_log = {}
|
2016-06-17 03:08:44 +03:00
|
|
|
end
|
|
|
|
local function save()
|
2017-08-26 21:01:51 +03:00
|
|
|
-- todo
|
2016-06-17 03:08:44 +03:00
|
|
|
end
|
|
|
|
load()
|
|
|
|
|
|
|
|
ChatCmdBuilder.new("admin", function(cmd)
|
2017-08-26 21:01:51 +03:00
|
|
|
cmd:sub("kill :name", function(name, target)
|
|
|
|
local player = minetest.get_player_by_name(target)
|
|
|
|
if player then
|
|
|
|
player:set_hp(0)
|
|
|
|
return true, "Killed " .. target
|
|
|
|
else
|
|
|
|
return false, "Unable to find " .. target
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
cmd:sub("move :name to :pos:pos", function(name, target, pos)
|
|
|
|
local player = minetest.get_player_by_name(target)
|
|
|
|
if player then
|
|
|
|
player:setpos(pos)
|
2018-09-24 19:16:00 +03:00
|
|
|
return true, "Moved " .. target .. " to " ..
|
|
|
|
minetest.pos_to_string(pos)
|
2017-08-26 21:01:51 +03:00
|
|
|
else
|
|
|
|
return false, "Unable to find " .. target
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
cmd:sub("log :username", function(name, target)
|
|
|
|
local log = admin_log[target]
|
|
|
|
if log then
|
|
|
|
return true, table.concat(log, "\n")
|
|
|
|
else
|
|
|
|
return false, "No entries for " .. target
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
cmd:sub("log :username :message", function(name, target, message)
|
|
|
|
local log = admin_log[target] or {}
|
|
|
|
table.insert(log, message)
|
|
|
|
admin_log[target] = log
|
|
|
|
save()
|
|
|
|
return true, "Logged"
|
|
|
|
end)
|
2016-06-17 03:08:44 +03:00
|
|
|
end, {
|
2017-08-26 21:01:51 +03:00
|
|
|
description = "Admin tools",
|
|
|
|
privs = {
|
|
|
|
kick = true,
|
|
|
|
ban = true
|
|
|
|
}
|
2016-06-17 03:08:44 +03:00
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|