Skip to content

Messages

Phinner edited this page Dec 13, 2024 · 2 revisions

Summary

The message API allows you to filter and process messages asynchronously.

Commands are also supported, in case you don't want to log sensitive information.

Here is a simple example showcasing how to use the API to redirect the /t command to flex.

import com.xpdustry.distributor.api.Distributor;
import com.xpdustry.distributor.api.audience.Audience;
import com.xpdustry.flex.FlexAPI;
import com.xpdustry.flex.message.MessageContext;
import mindustry.gen.Player;
import java.util.concurrent.CompletableFuture;

final Player player = /* get player */;
final var audience = Distributor.get().getAudienceProvider().getPlayer(player);
final var message = "Hello team";
FlexAPI.get()
        .getMessages()
        // The first call will filter the message (the extra boolean argument),
        // verifying if your player is muted for example
        .pump(new MessageContext(audience, Audience.empty(), message, true))
        .thenCompose(result -> {
            // If the message is blank, the message failed filtering
            if (result.isBlank()) {
                return CompletableFuture.completedFuture(null);
            }
            // We succeeded, we can now broadcast the message to the player teammates.
            return FlexAPI.get()
                    .getMessages()
                    .broadcast(
                            audience,
                            // Notice the use of a team audience,
                            // it will call Audience#getAudiences to apply flex processing per player
                            Distributor.get().getAudienceProvider().getTeam(player.team()),
                            message,
                            // A custom template for team messages
                            "mindustry_chat_team");
        })
        .exceptionally(throwable -> {
            player.sendMessage("An error occurred while sending the message: " + throwable.getMessage());
            return null;
        });

Built-ins

  • admin_filter: A processor using the vanilla message filter (Vars.netServer.admins#filterMessage) if the sender is a player audience.

  • translator: Uses FlexAPI#getTranslator to translate a message to the receiver language.

Register

Like placeholders processors, plus a priority parameter, so you can apply your filters first and processing last.

You don't want to translate the messages of a muted player do you ?

Here is an example where we keep dead players from talking.

import arc.Core;
import com.xpdustry.distributor.api.audience.PlayerAudience;
import com.xpdustry.flex.FlexAPI;
import com.xpdustry.flex.message.MessageContext;

// The processor is returning a future that will run on the main thread since we are reading live data
FlexAPI.get().getMessages().register("no_deads", context -> CompletableFuture.supplyAsync(
        () -> {
            if (context.getKind() == MessageContext.Kind.CHAT
                    && context.isFiltering()
                    && context.getSender() instanceof PlayerAudience player
                    && player.getPlayer().unit().dead()) {
                player.sendMessage(text("You can't send messages while dead."));
                return null;
            } else {
                return context.getMessage();
            }
        }
        , Core.app::post));

Another example where we strip login information assuming you have a command /login instead of /login <username> <password>.

If you do the latter, please use text input to obtain the player password.

FlexAPI.get().getMessages().register("strip_login_info", context ->
        CompletableFuture.completedFuture(
                context.getKind() == MessageContext.Kind.COMMAND
                        && context.isFiltering()
                        && context.getMessage().split("\\.", 2)[0].equalsIgnoreCase("login")
                                ? "login"
                                : context.getMessage()));
Clone this wiki locally