diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordRelayEvent.java b/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordRelayEvent.java
new file mode 100644
index 00000000000..565202b061c
--- /dev/null
+++ b/EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordRelayEvent.java
@@ -0,0 +1,111 @@
+package net.essentialsx.api.v2.events.discord;
+
+import net.essentialsx.api.v2.services.discord.InteractionChannel;
+import net.essentialsx.api.v2.services.discord.InteractionMember;
+import org.bukkit.Bukkit;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Fired before a message is relayed to Minecraft.
+ *
+ * Note: This event has no guarantee of the thread it is fired on, please use {@link #isAsynchronous()}} to see if this event is off the main Bukkit thread.
+ */
+public class DiscordRelayEvent extends Event implements Cancellable {
+ private static final HandlerList handlers = new HandlerList();
+
+ private final InteractionMember member;
+ private final InteractionChannel channel;
+ private final List groupNames;
+ private final String rawMessage;
+ private String formattedMessage;
+ private boolean cancelled = false;
+
+ /**
+ * @param member The member that sent the message.
+ * @param channel The channel the message was sent in.
+ * @param groupNames The message type keys which will be used to determine which player group the message should be sent to.
+ * @param rawMessage The raw message sent from Discord.
+ * @param formattedMessage The formatted message that will be sent to Minecraft.
+ */
+ public DiscordRelayEvent(final InteractionMember member, final InteractionChannel channel, final List groupNames, final String rawMessage, final String formattedMessage) {
+ super(!Bukkit.isPrimaryThread());
+ this.member = member;
+ this.channel = channel;
+ this.groupNames = groupNames;
+ this.rawMessage = rawMessage;
+ this.formattedMessage = formattedMessage;
+ }
+
+ /**
+ * Gets the Discord member that sent the message.
+ * @return The member that sent the message.
+ */
+ public InteractionMember getMember() {
+ return member;
+ }
+
+ /**
+ * Gets the Discord channel the message was sent in.
+ * @return The channel the message was sent in.
+ */
+ public InteractionChannel getChannel() {
+ return channel;
+ }
+
+ /**
+ * Gets the message type group keys.
+ * @return The message type group keys.
+ */
+ public List getGroupNames() {
+ return groupNames;
+ }
+
+ /**
+ * Gets the raw message sent from Discord.
+ * @return The raw message sent from Discord.
+ */
+ public String getRawMessage() {
+ return rawMessage;
+ }
+
+ /**
+ * Gets the formatted message that will be sent to Minecraft.
+ * @return The formatted message.
+ */
+ public String getFormattedMessage() {
+ return formattedMessage;
+ }
+
+ /**
+ * Sets the formatted message that will be sent to Minecraft.
+ * @param formattedMessage The formatted message.
+ */
+ public void setFormattedMessage(final String formattedMessage) {
+ this.formattedMessage = formattedMessage;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java
index cdb3746975c..616888c66ed 100644
--- a/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java
+++ b/EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/DiscordListener.java
@@ -8,12 +8,17 @@
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.ess3.api.IUser;
+import net.essentialsx.api.v2.events.discord.DiscordRelayEvent;
import net.essentialsx.discord.JDADiscordService;
+import net.essentialsx.discord.interactions.InteractionChannelImpl;
+import net.essentialsx.discord.interactions.InteractionMemberImpl;
import net.essentialsx.discord.util.DiscordUtil;
import net.essentialsx.discord.util.MessageUtil;
import org.apache.commons.lang.StringUtils;
+import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -88,7 +93,7 @@ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
return;
}
- final String formattedMessage = EmojiParser.parseToAliases(MessageUtil.formatMessage(plugin.getPlugin().getSettings().getDiscordToMcFormat(),
+ String formattedMessage = EmojiParser.parseToAliases(MessageUtil.formatMessage(plugin.getPlugin().getSettings().getDiscordToMcFormat(),
event.getChannel().getName(), user.getName(), user.getDiscriminator(), user.getAsTag(),
effectiveName, DiscordUtil.getRoleColorFormat(member), finalMessage, DiscordUtil.getRoleFormat(member)), EmojiParser.FitzpatrickAction.REMOVE);
@@ -99,6 +104,18 @@ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
}
}
+ // Do not create the event specific objects if there are no listeners
+ if (DiscordRelayEvent.getHandlerList().getRegisteredListeners().length != 0) {
+ final DiscordRelayEvent relayEvent = new DiscordRelayEvent(
+ new InteractionMemberImpl(member), new InteractionChannelImpl(event.getChannel()),
+ Collections.unmodifiableList(keys), event.getMessage().getContentRaw(), formattedMessage);
+ Bukkit.getPluginManager().callEvent(relayEvent);
+ if (relayEvent.isCancelled()) {
+ return;
+ }
+ formattedMessage = relayEvent.getFormattedMessage();
+ }
+
for (IUser essUser : plugin.getPlugin().getEss().getOnlineUsers()) {
for (String group : keys) {
final String perm = "essentials.discord.receive." + group;