Commands¶
Commands are how players talk to your plugin, so almost every plugin has some. You've already made a few, but none of them cared about what the player typed after the command. In this lesson you'll learn to read that, and you'll finish with a /heal that can heal you, heal another player, and even work from the console.
Part 1: Read what the player typed¶
Everything typed after the command name is called the arguments. Try this command to see them:
plugin.addCommand({
name = "echo",
description = "Show what you typed",
usage = "/echo <words>"
}, function(event)
local sender = event.getSender()
local args = event.getArgs()
sender:sendMessage("You typed " .. #args .. " word(s).")
sender:sendMessage("The first word was: " .. tostring(args[1]))
end)
event.getArgs() gives you the arguments as a list with one word in each spot. If someone types /echo hello there, the list holds hello and there. Putting # in front of the list counts how many words it holds, and args[1] is the first word, because Lua starts counting at 1 instead of 0.
If the player types nothing, args[1] is nil, which is Lua's way of saying "there's nothing here". The tostring part turns nil into text, so the message can still be sent.
Try /echo hello there and then just /echo to see both cases.
Part 2: Player or console?¶
Commands can be run by players, by the console, and by command blocks, so it's worth knowing who you're dealing with:
plugin.addCommand({
name = "whoami",
description = "Tell me who ran this command",
usage = "/whoami"
}, function(event)
local sender = event.getSender()
if event.isPlayerSender() then
sender:sendMessage("You are a player.")
else
sender:sendMessage("You are not a player, so you're probably the console.")
end
end)
event.isPlayerSender() is true when a player ran the command and false otherwise. This is why the /heal from earlier didn't work in the console: the console isn't a player, so it has no health to fill. Try /whoami in game and then from the server console.
Part 3: Find another player¶
To act on a different player, you need to look them up by name:
plugin.addCommand({
name = "isonline",
description = "Check if a player is online",
usage = "/isonline <player>",
minArgs = 1,
maxArgs = 1
}, function(event)
local sender = event.getSender()
local args = event.getArgs()
local target = plugin.getServer():getPlayer(args[1])
if target then
sender:sendMessage(target:getName() .. " is online!")
else
sender:sendMessage("That player isn't online.")
end
end)
plugin.getServer() gives you the server, and :getPlayer(name) looks for an online player with that name. If it finds one you get the player, and if not you get nil. That's why if target then works: a player counts as "yes" and nil counts as "no".
minArgs = 1 and maxArgs = 1 tell LuaCord to check the number of arguments for you. If someone types /isonline with no name, or with two names, LuaCord replies with an error message and your function never runs.
Dot or colon, again
plugin.getServer() uses a dot because plugin belongs to LuaCord. Then :getPlayer(...) uses a colon, because the server comes from Spigot.
Putting it together¶
Now let's use all three to make a better /heal. Replace your old one with this:
plugin.addCommand({
name = "heal",
description = "Heal yourself or another player",
usage = "/heal [player]",
maxArgs = 1
}, function(event)
local sender = event.getSender()
local args = event.getArgs()
local target = nil
if args[1] then
target = plugin.getServer():getPlayer(args[1])
elseif event.isPlayerSender() then
target = sender
end
if target then
target:setHealth(20)
target:sendMessage("You were healed!")
else
sender:sendMessage("Couldn't find anyone to heal. Use /heal <player>.")
end
end)
target is the player we're going to heal, and it starts as nil, which means we haven't picked anyone yet. The first if fills it in. If a name was typed, we look that player up, and if nobody by that name is online it stays nil. If no name was typed and a player ran the command, the target is the sender, so they heal themselves. If no name was typed and it's the console, nobody is picked, so it stays nil there too.
The second if then checks whether we found anyone. If we did, we heal them and tell them. If not, we explain how to use the command.
Try these, and watch what comes back each time:
/healin game heals you./heal Steve, with a real player's name, heals them./heal Nobodysays it couldn't find anyone./healin the console says it couldn't find anyone, since the console isn't a player./heal Stevein the console works./heal a bgets LuaCord's too many arguments error.
Quick reference¶
Command options¶
This is everything you can put in the table you give to plugin.addCommand. You always need name and description, and the rest are optional.
| Option | What it does | Example |
|---|---|---|
name |
What players type after the slash | name = "heal" |
description |
A short summary of the command. Without one, the command won't register. | description = "Heal a player" |
usage |
How to use the command | usage = "/heal [player]" |
permission |
Only people with this permission can use the command | permission = "myplugin.heal" |
minArgs |
The fewest arguments allowed. LuaCord shows an error if there are fewer. | minArgs = 1 |
maxArgs |
The most arguments allowed. LuaCord shows an error if there are more. | maxArgs = 1 |
runAsync |
Runs the command in the background. Most Spigot actions aren't safe there, so leave this off for now. | runAsync = false |
What the event gives you¶
Your command function looks like function(event), and this is what you can call on that event.
| Call | What you get | Example |
|---|---|---|
event.getSender() |
Whoever ran the command. See everything you can do with it. | local sender = event.getSender() |
event.getArgs() |
A list of the words typed after the command | local args = event.getArgs() |
event.getCommand() |
The name of the command that was used | event.getCommand() |
event.isPlayerSender() |
true if a player ran it |
if event.isPlayerSender() then |
event.isConsoleSender() |
true if the console ran it |
if event.isConsoleSender() then |
event.isBlockSender() |
true if a command block ran it |
if event.isBlockSender() then |
event.isEntitySender() |
true if an entity ran it, and players count as entities |
if event.isEntitySender() then |
Next up is events.