Skip to content
Select theme
  • Auto
  • Dark
  • Light

Messages and logging

Plex gives modules two services for text. MessageApi turns MiniMessage text into components and sends broadcasts. LoggingApi writes lines to the server console and log.

Get each service from the Plex API. In your module class and in a command that extends SimplePlexCommand, call api(). In other classes, keep a reference to your module and call module.api(). See the API overview for more about api().

MessageApi messages = api().messages();
LoggingApi logging = api().logging();

Javadoc: MessageApi

Method What it does
messageComponent(String entry, TagResolver... placeholders) Reads the key entry from the Plex messages.yml and returns it as a component. Plex fills each tag from the placeholders.
messageString(String entry) Returns the raw MiniMessage text of the key entry from the Plex messages.yml. Plex does not parse it.
miniMessage(String input, TagResolver... placeholders) Parses your own MiniMessage text into a component.
playerText(String input) Parses text that a player wrote. Plex allows only visual formatting.
chatLine(Player player, Component message) Builds the public chat line of a player, with the configured chat format, prefix, and display name. It does not send the line.
broadcast(String miniMessage) Parses MiniMessage text and sends it to every online player and the console.
broadcast(Component component) Sends a component to every online player and the console.
captureActionBroadcast(CommandSender sender) Records who may see an announcement about an action by sender. Returns an ActionBroadcast.
sendAdminChat(String senderName, Component prefix, Component message) Sends a message to staff chat on this server.

Plex messages use named MiniMessage tags, such as <player>. Numbered placeholders such as {0} do not work in messages. Give one TagResolver for each tag:

  • Placeholder.unparsed("player", name) inserts plain text. Tags in the value stay as literal text.
  • Placeholder.component("reason", component) inserts a component that you already built.

messageComponent and messageString read only the Plex messages.yml. To read your module’s own message file, use messageComponent on your module. That method falls back to the Plex file when your file does not have the key. See Configuration and messages. The keys and tags of the Plex file are on the Messages page.

If the key does not exist in the Plex messages.yml, messageComponent and messageString throw a NullPointerException.

import dev.plex.api.message.MessageApi;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
MessageApi messages = module.api().messages();
staff.sendMessage(messages.messageComponent("bannedPlayerJoined",
Placeholder.unparsed("player", bannedName)));

miniMessage and messageComponent accept every MiniMessage tag, which includes click, hover, and insertion tags. Do not add player text to the input string. A player could add a click event that runs a command. Pass player text in a placeholder instead.

Use playerText when a player may color their own text, for example a nickname or a report reason. It allows colors, gradients, rainbow text, fonts, and the bold, italic, underlined, and strikethrough decorations. It keeps all other tags as literal text. If the text has legacy & color codes, Plex reads the legacy codes instead of MiniMessage and removes obfuscation.

MessageApi messages = module.api().messages();
Component line = messages.miniMessage("<gold><reporter></gold> <gray>reported:</gray> <reason>",
Placeholder.unparsed("reporter", reporter),
Placeholder.component("reason", messages.playerText(reason)));
staff.sendMessage(line);

chatLine gives the same line that Plex shows in public chat for that player. It uses chat.format from the Plex config.yml. Plex calls PlayerPrefixEvent with the CHAT target while it builds the line, so prefixes from other modules are included. See Events. Call chatLine on a thread that can read the player, for example the command thread of that player.

broadcast sends to every online player and the console.

module.api().messages().broadcast("<green>The build contest starts in 5 minutes.");

Javadoc: ActionBroadcast

Use an ActionBroadcast to announce a staff action, such as “Alice put out Bob”. It keeps a vanished staff member hidden.

Method What it does
send(Component message) Sends the announcement to the audience that captureActionBroadcast recorded.

captureActionBroadcast(sender) decides the audience when you call it:

  • If the sender is the console, or a player who is not vanished, send goes to every online player and the console.
  • If the sender is a vanished player, send goes to that player, the console, and the online players who can see that player at the time of the capture. Players who join later do not receive it.
  • If the server has no SuperVanish or PremiumVanish, send goes to everyone.

Call captureActionBroadcast on the command thread of the sender, before you schedule work on another entity or region, or start asynchronous work. You can call send from any thread, including the completion of a future. Call send only after the action succeeds. Use one ActionBroadcast for one action.

import dev.plex.api.message.ActionBroadcast;
private Component extinguish(CommandSender sender, Player target)
{
// Capture on the command thread, before the work moves to the target's thread.
ActionBroadcast announcement = api().messages().captureActionBroadcast(sender);
Component message = api().messages().miniMessage("<aqua><actor> put out <target>.",
Placeholder.unparsed("actor", sender.getName()),
Placeholder.unparsed("target", target.getName()));
ownTask(target.getScheduler().run(taskOwner(), task ->
{
target.setFireTicks(0);
announcement.send(message);
}, null));
return null;
}

sendAdminChat sends a message to staff chat on this server. Plex formats it with the adminChatFormat message, which has the <sender>, <prefix>, and <message> tags. Online players with the plex.adminchat permission receive it. Plex does not send it to the console or to other servers.

Before Plex sends the message, it calls StaffChatMessageEvent with the source API. If a listener cancels the event, Plex sends nothing. See Events.

MessageApi messages = module.api().messages();
messages.sendAdminChat(reporter,
messages.miniMessage("<red>[Report]"),
messages.playerText(reason));

Javadoc: LoggingApi

LoggingApi writes to the server console and log through the Plex logger. Each line starts with a Plex label, such as [Plex] or [Plex Error]. You can call these methods from any thread.

Method What it does
info(String message, Object... args) Writes an information line with the [Plex] label.
debug(String message, Object... args) Writes a line with the [Plex Debug] label, only when debug is true in the Plex config.yml.
warn(String message, Object... args) Writes a warning line with the [Plex Warning] label.
error(String message, Object... args) Writes an error line with the [Plex Error] label.

Log messages use numbered placeholders. Plex replaces {0} with the first argument, {1} with the second, and so on. Plex then parses the full line as MiniMessage, so you can add color tags.

LoggingApi log = api().logging();
log.info("Loaded {0} homes in {1} ms", count, millis);
log.debug("Time zone: {0}", zone);

LoggingApi has no exception parameter. If you pass an exception as an argument, Plex does not write its stack trace. To log an exception with its stack trace, use your module logger. getLogger() on your module returns a Log4j Logger with the name of your module. Put the exception last.

try
{
homes.save();
}
catch (IllegalStateException ex)
{
getLogger().error("Could not save data/homes.yml", ex);
}