Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions api/src/main/java/dev/plex/api/event/StaffChatMessageEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package dev.plex.api.event;

import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;

/**
* Fired before Plex delivers a locally-originated staff-chat message.
*
* <p>The event covers both a player's toggled staff-chat input and the direct
* {@code /adminchat <message>} command form. It is not fired when a staff-chat
* message is received from another server through Plex's Redis transport.</p>
*
* <p>This event can be asynchronous. Listeners must check
* {@link #isAsynchronous()} before accessing APIs which require a server or
* region thread.</p>
*/
public final class StaffChatMessageEvent extends Event implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();

private final CommandSender sender;
private final Source source;
private Component message;
private boolean cancelled;

/**
* Creates a staff-chat message event.
*
* @param sender sender of the message
* @param message message to be delivered
* @param source input path which produced the message
* @param async whether the event is asynchronous
*/
public StaffChatMessageEvent(
@NotNull CommandSender sender,
@NotNull Component message,
@NotNull Source source,
boolean async)
{
super(async);
this.sender = sender;
this.message = message;
this.source = source;
}

/**
* Returns the player or console which sent the message.
*
* @return message sender
*/
public @NotNull CommandSender getSender()
{
return sender;
}

/**
* Returns the message which Plex will deliver.
*
* @return staff-chat message
*/
public @NotNull Component getMessage()
{
return message;
}

/**
* Replaces the message Plex will deliver.
*
* @param message replacement message
*/
public void setMessage(@NotNull Component message)
{
this.message = message;
}

/**
* Returns how the message entered staff chat.
*
* @return message source
*/
public @NotNull Source getSource()
{
return source;
}

@Override
public boolean isCancelled()
{
return cancelled;
}

@Override
public void setCancelled(boolean cancelled)
{
this.cancelled = cancelled;
}

@Override
public @NotNull HandlerList getHandlers()
{
return HANDLERS;
}

/**
* Returns this event's handler list.
*
* @return handler list
*/
public static @NotNull HandlerList getHandlerList()
{
return HANDLERS;
}

/**
* Identifies the Plex input path which produced a staff-chat message.
*/
public enum Source
{
/** A player spoke while staff-chat mode was enabled. */
TOGGLED_CHAT,

/** A sender used {@code /adminchat <message>} or one of its aliases. */
COMMAND
}
}
14 changes: 14 additions & 0 deletions api/src/main/java/dev/plex/api/player/PlexPlayerView.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ public interface PlexPlayerView
*/
boolean lockedUp();

/**
* Returns whether the player currently has staff-chat mode enabled.
*
* <p>When enabled, the player's normal chat input is routed to Plex staff
* chat and exposed through
* {@link dev.plex.api.event.StaffChatMessageEvent}.</p>
*
* @return whether staff-chat mode is enabled
*/
default boolean staffChat()
{
return false;
}

/**
* Returns the Bukkit player instance.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ record DefaultPlexPlayerView(PlexPlayer player, PlayerNameResolver playerNameRes
@Override public boolean frozen() { return player.isFrozen(); }
@Override public boolean muted() { return player.isMuted(); }
@Override public boolean lockedUp() { return player.isLockedUp(); }
@Override public boolean staffChat() { return player.isStaffChat(); }
@Override public Player bukkitPlayer() { return player.getPlayer(); }
}
18 changes: 16 additions & 2 deletions server/src/main/java/dev/plex/command/impl/AdminChatCMD.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.plex.command.impl;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import dev.plex.api.event.StaffChatMessageEvent;
import dev.plex.command.ServerCommand;
import dev.plex.command.ServerCommandContext;
import dev.plex.hook.VaultHook;
Expand All @@ -15,6 +16,7 @@
import io.papermc.paper.command.brigadier.CommandSourceStack;
import net.kyori.adventure.text.Component;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -68,8 +70,20 @@ protected Component execute(@NotNull ServerCommandContext context)
}
PlexLog.debug("admin chat prefix: {0}", prefix);
String message = StringUtils.join(args, " ");
plugin.getServer().getConsoleSender().sendMessage(context.messageComponent("adminChatFormat", sender.getName(), prefix, message));
MessageUtil.sendStaffChat(plugin, sender, SafeMiniMessage.mmDeserialize(message), PlexUtils.adminChat(sender.getName(), prefix, message).toArray(UUID[]::new));
StaffChatMessageEvent staffChatEvent = new StaffChatMessageEvent(
sender,
SafeMiniMessage.mmDeserialize(message),
StaffChatMessageEvent.Source.COMMAND,
!Bukkit.isPrimaryThread());
plugin.getServer().getPluginManager().callEvent(staffChatEvent);
if (staffChatEvent.isCancelled())
{
return null;
}
Component eventMessage = staffChatEvent.getMessage();
String serializedMessage = SafeMiniMessage.mmSerialize(eventMessage);
plugin.getServer().getConsoleSender().sendMessage(context.messageComponent("adminChatFormat", sender.getName(), prefix, serializedMessage));
MessageUtil.sendStaffChat(plugin, sender, eventMessage, PlexUtils.adminChat(sender.getName(), prefix, serializedMessage).toArray(UUID[]::new));
return null;
}

Expand Down
16 changes: 14 additions & 2 deletions server/src/main/java/dev/plex/listener/impl/ChatListener.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.plex.listener.impl;

import dev.plex.Plex;
import dev.plex.api.event.StaffChatMessageEvent;
import dev.plex.hook.VaultHook;
import dev.plex.listener.ServerListenerBase;
import dev.plex.meta.PlayerMeta;
Expand Down Expand Up @@ -50,9 +51,20 @@ public void onChat(AsyncChatEvent event)
if (plexPlayer.isStaffChat())
{
String prefix = PlexUtils.mmSerialize(VaultHook.getPrefix(event.getPlayer())); // Don't use PlexPlayer#getPrefix because that returns their custom set prefix and not their group's
MessageUtil.sendStaffChat(plugin, event.getPlayer(), event.message(), PlexUtils.adminChat(event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(event.message())).toArray(UUID[]::new));
plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(event.message().replaceText(URL_REPLACEMENT_CONFIG))));
StaffChatMessageEvent staffChatEvent = new StaffChatMessageEvent(
event.getPlayer(),
event.message(),
StaffChatMessageEvent.Source.TOGGLED_CHAT,
event.isAsynchronous());
plugin.getServer().getPluginManager().callEvent(staffChatEvent);
event.setCancelled(true);
if (staffChatEvent.isCancelled())
{
return;
}
Component message = staffChatEvent.getMessage();
MessageUtil.sendStaffChat(plugin, event.getPlayer(), message, PlexUtils.adminChat(event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(message)).toArray(UUID[]::new));
plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", event.getPlayer().getName(), prefix, SafeMiniMessage.mmSerialize(message.replaceText(URL_REPLACEMENT_CONFIG))));
return;
}
Component prefix = PlayerMeta.getPrefix(plexPlayer);
Expand Down
Loading