encore.addCommand registers a chat command and does the tedious parts for you. It parses and checks arguments before your handler runs, shows the player a usage message when they get it wrong, grants ACE permissions for restricted commands, and only suggests a command in chat to players who are allowed to use it.
For the commands EndCore itself ships, see Commands.
Signature
encore.addCommand(names, properties, handler)| Argument | Type | Meaning |
|---|---|---|
names | string or string[] | The command name, or a list of names. Every name in the list registers the same command, so extra names act as aliases |
properties | table | Help text, restriction and parameters (below) |
handler | function(source, args, raw) | Runs after the arguments parse. args is keyed by parameter name. raw is the full command line as typed |
Properties
| Key | Type | Side | Meaning |
|---|---|---|---|
help | string? | both | Shown in the chat suggestion |
restricted | string, string[] or false | server only | ACE principal or principals allowed to run it, for example 'group.admin' |
params | CommandParam[]? | both | Parameters, in order |
Parameters
Each entry in params is { name, type?, help?, optional? }.
type | Parses as | Notes |
|---|---|---|
'string' (or omitted) | the raw word | Any other type name is also kept as a raw string |
'number' | tonumber(word) | A word that isn't a number is rejected |
'playerId' | a server id | On the server, me means the caller (not from the console), and the id must belong to a connected player |
'longString' | the rest of the line | Every remaining word from this position, joined with single spaces. Put it last |
Set optional = true for parameters players may leave out. A missing optional parameter is nil in args.
What players see
Arguments are parsed before your handler is called. If they don't parse, the handler doesn't run and the player gets an error notification titled /<name>:
| Problem | Message |
|---|---|
| A required parameter is missing | Usage: /setjob <target> <job> [grade] |
| A value doesn't parse | "abc" is not a valid grade. Usage: /setjob <target> <job> [grade] |
A playerId isn't online (server) | No player online with ID 42 |
In the usage string, required parameters are shown as <name> and optional ones as [name]. When the command runs from the server console (source 0), the message prints to the console instead.
If your handler throws, the error is logged as /<name> errored: ... and the command system carries on.
Restricted commands
On the server, setting restricted:
- Registers the command as restricted, so FiveM checks the ACE
command.<name>before running it. - Runs
add_ace <principal> command.<name> allowfor each principal you list. - Sends the chat suggestion only to players for whom
IsPlayerAceAllowed(player, 'command.<name>')is true. Suggestions are re-sent to each player as they join, and to everyone about a second after new commands are registered.
You can grant a restricted command to more principals in server.cfg:
add_ace group.moderator command.givexp allowClient commands
On the client, encore.addCommand registers an unrestricted command and adds a chat suggestion. restricted is ignored, because a player controls their own client.
On the client, playerId parameters take a number only; me is not accepted.
A client command is a convenience, not a permission check. If it triggers anything on the server, the server must validate the request as if the command didn't exist.
Security
- Put anything that changes money, items, jobs or other players in a server command with
restricted. - A
playerIdparameter proves the id belongs to a connected player. It doesn't prove the caller may act on that player. numberparameters accept negatives and decimals. Check the range before using them, for example withencore.math.clamp.longStringvalues are typed by the player. Display them as text only.
Examples
Admin command with an alias
-- server/commands.lua
encore.addCommand({ 'givexp', 'gxp' }, {
help = 'Give survivor XP',
restricted = 'group.admin',
params = {
{ name = 'target', type = 'playerId', help = 'Player ID, or "me"' },
{ name = 'amount', type = 'number' },
{ name = 'reason', type = 'longString', optional = true },
},
}, function(source, args)
local amount = math.floor(encore.math.clamp(args.amount, 1, 100000))
encore.party.shareXP(args.target, amount, args.reason or 'Admin grant')
encore.notify(source, { description = ('Gave %d XP'):format(amount), type = 'success' })
end)Several principals
encore.addCommand('clearzone', {
help = 'Clear zombies around you',
restricted = { 'group.admin', 'group.moderator' },
params = { { name = 'radius', type = 'number', optional = true } },
}, function(source, args)
local radius = encore.math.clamp(args.radius or 50, 5, 300)
TriggerEvent('my-admin:clearZombies', source, radius)
end)Client command
-- client/main.lua
encore.addCommand('compass', {
help = 'Say which way you are facing',
}, function()
local heading = GetEntityHeading(PlayerPedId())
encore.notify({ description = 'Facing ' .. encore.getCardinalDirection(heading) })
end)