Spigot chat arguments
Chat color argument
The ChatColorArgument
class is used to represent a given chat color (e.g. red or green). This argument returns the ChatColor
object.
Example - Username color changing plugin
Say we want to create a plugin to change the color of a player's username. We want to create a command of the following form:
/namecolor <chatcolor>
We then use the ChatColorArgument
to change the player's name color:
new CommandAPICommand("namecolor")
.withArguments(new ChatColorArgument("chatcolor"))
.executesPlayer((player, args) -> {
ChatColor color = (ChatColor) args.get("chatcolor");
player.setDisplayName(color + player.getName());
})
.register();
CommandAPICommand("namecolor")
.withArguments(ChatColorArgument("chatColor"))
.executesPlayer(PlayerCommandExecutor { player, args ->
val color = args["chatColor"] as ChatColor
player.setDisplayName("$color${player.name}")
})
.register()
commandAPICommand("namecolor") {
chatColorArgument("chatcolor")
playerExecutor { player, args ->
val color = args["chatcolor"] as ChatColor
player.setDisplayName("$color${player.name}")
}
}
Developer's Note:
The two following classes,
ChatComponentArgument
andChatArgument
depend on a Spigot based server. This means that these arguments will not work on a non-Spigot based server, such as CraftBukkit. If you use this class on a non-Spigot based server, it will throw aSpigotNotFoundException
Chat component argument
The ChatComponentArgument
class accepts raw chat-based JSON as valid input. Despite being regular JSON, it must conform to the standard declared here, which consists of JSON that has a limited subset of specific keys (In other words, you can have a JSON object that has the key text
, but not one that has the key blah
).
This is converted into Spigot's BaseComponent[]
, which can be used for the following:
-
Broadcasting messages to all players on the server using:
Bukkit.getServer().spigot().broadcast(BaseComponent[]);
-
Adding and setting pages to books using
BookMeta
:BookMeta meta = // ... meta.spigot().setPages(BaseComponent[]);
-
Sending messages to
Player
objects:Player player = // ... player.spigot().sendMessage(BaseComponent[]);
-
Sending messages to
CommandSender
objects:CommandSender sender = // ... sender.spigot().sendMessage(BaseComponent[]);
Example - Book made from raw JSON
Say we want to generate a book using raw JSON. For this example, we'll use the following JSON (generated from minecraftjson.com) to generate our book:
["", {
"text": "Once upon a time, there was a guy call "
}, {
"text": "Skepter",
"color": "light_purple",
"hoverEvent": {
"action": "show_entity",
"value": "Skepter"
}
}, {
"text": " and he created the "
}, {
"text": "CommandAPI",
"underlined": true,
"clickEvent": {
"action": "open_url",
"value": "https://github.com/JorelAli/CommandAPI"
}
}]
Since we're writing a book, we must ensure that all quotes have been escaped. This can also be performed on the minecraftjson.com website by selecting "book":
["[\"\",{\"text\":\"Once upon a time, there was a guy call \"},{\"text\":\"Skepter\",\"color\":\"light_purple\",\"hoverEvent\":{\"action\":\"show_entity\",\"value\":\"Skepter\"}},{\"text\":\" and he created the \"},{\"text\":\"CommandAPI\",\"underlined\":true,\"clickEvent\":{\"action\":\"open_url\",\"value\":\"https://github.com/JorelAli/CommandAPI\"}}]"]
Now let's define our command. Since book text is typically very large - too large to be entered into a chat, we'll make a command block compatible command by providing a player parameter:
/makebook <player> <contents>
Now we can create our book command. We use the player as the main target by using their name for the author field, as well as their inventory to place the book. We finally construct our book using the .setPages(BaseComponent[])
method:
new CommandAPICommand("makebook")
.withArguments(new PlayerArgument("player"))
.withArguments(new ChatComponentArgument("contents"))
.executes((sender, args) -> {
Player player = (Player) args.get("player");
BaseComponent[] arr = (BaseComponent[]) args.get("contents");
// Create book
ItemStack is = new ItemStack(Material.WRITTEN_BOOK);
BookMeta meta = (BookMeta) is.getItemMeta();
meta.setTitle("Custom Book");
meta.setAuthor(player.getName());
meta.spigot().setPages(arr);
is.setItemMeta(meta);
// Give player the book
player.getInventory().addItem(is);
})
.register();
CommandAPICommand("makebook")
.withArguments(PlayerArgument("player"))
.withArguments(ChatComponentArgument("contents"))
.executes(CommandExecutor { _, args ->
val player = args["player"] as Player
val arr = args["contents"] as Array<BaseComponent>
// Create book
val item = ItemStack(Material.WRITTEN_BOOK)
val meta = item.itemMeta as BookMeta
meta.title = "Custom Book"
meta.author = player.name
meta.spigot().setPages(arr)
item.itemMeta = meta
// Give player the book
player.inventory.addItem(item)
})
.register()
commandAPICommand("makebook") {
playerArgument("player")
chatComponentArgument("contents")
anyExecutor { _, args ->
val player = args["player"] as Player
val array = args["contents"] as Array<BaseComponent>
// Create book
val item = ItemStack(Material.WRITTEN_BOOK)
val meta = item.itemMeta as BookMeta
meta.title = "Custom Book"
meta.author = player.name
meta.spigot().setPages(array)
item.itemMeta = meta
// Give player the book
player.inventory.addItem(item)
}
}
Chat argument
Note:
The
ChatArgument
class is an argument similar to theGreedyStringArgument
, in the sense that it has no terminator and must be defined at the end of yourList
of arguments. For more information on this, please read the section on Greedy arguments.
The ChatArgument
is identical to the GreedyStringArgument
, with the added functionality of enabling entity selectors, such as @e
, @p
and so on. The ChatArgument
also returns a BaseComponent[]
, similar to the ChatComponentArgument
.
Example - Sending personalized messages to players
Say we wanted to broadcast a "personalized" message to players on the server. By "personalized", we mean a command which changes its output depending on who we are sending the output to. Simply put, we want a command of the following syntax:
/pbroadcast <message>
Say we're on a server with 2 players: Bob and Michael. If I were to use the following command:
/pbroadcast Hello @p
Bob would receive the message "Hello Bob", whereas Michael would receive the message "Hello Michael". We can use the ChatArgument
to create this "personalized" broadcast:
new CommandAPICommand("pbroadcast")
.withArguments(new ChatArgument("message"))
.executes((sender, args) -> {
BaseComponent[] message = (BaseComponent[]) args.get("message");
// Broadcast the message to everyone on the server
Bukkit.getServer().spigot().broadcast(message);
})
.register();
CommandAPICommand("pbroadcast")
.withArguments(ChatArgument("message"))
.executes(CommandExecutor { _, args ->
val message = args["message"] as Array<BaseComponent>
// Broadcast the message to everyone on the server
Bukkit.getServer().spigot().broadcast(*message)
})
.register()
commandAPICommand("pbroadcast") {
chatArgument("message")
anyExecutor { _, args ->
val message = args["message"] as Array<BaseComponent>
// Broadcast the message to everyone on the server
Bukkit.getServer().spigot().broadcast(*message)
}
}