Skip to content

Commit e5b0c4c

Browse files
brawaruJRoy
andauthored
Add support for local and global chats in Discord (#4684)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
1 parent 84fd45b commit e5b0c4c

10 files changed

Lines changed: 234 additions & 26 deletions

File tree

EssentialsDiscord/src/main/java/net/essentialsx/api/v2/events/discord/DiscordChatMessageEvent.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.essentialsx.api.v2.events.discord;
22

3+
import net.essentialsx.api.v2.ChatType;
34
import org.bukkit.entity.Player;
45
import org.bukkit.event.Cancellable;
56
import org.bukkit.event.Event;
@@ -14,20 +15,22 @@ public class DiscordChatMessageEvent extends Event implements Cancellable {
1415
private static final HandlerList handlers = new HandlerList();
1516

1617
private final Player player;
18+
private final ChatType chatType;
1719
private String message;
1820
private boolean cancelled = false;
1921

2022
/**
2123
* @param player The player which caused this event.
2224
* @param message The message of this event.
2325
*/
24-
public DiscordChatMessageEvent(Player player, String message) {
26+
public DiscordChatMessageEvent(Player player, String message, ChatType chatType) {
2527
this.player = player;
2628
this.message = message;
29+
this.chatType = chatType;
2730
}
2831

2932
/**
30-
* The player which which caused this chat message.
33+
* The player which caused this chat message.
3134
* @return the player who caused the event.
3235
*/
3336
public Player getPlayer() {
@@ -50,6 +53,14 @@ public void setMessage(String message) {
5053
this.message = message;
5154
}
5255

56+
/**
57+
* Type of chat of the original message.
58+
* @return type of chat of the original message.
59+
*/
60+
public ChatType getChatType() {
61+
return chatType;
62+
}
63+
5364
@Override
5465
public boolean isCancelled() {
5566
return cancelled;

EssentialsDiscord/src/main/java/net/essentialsx/api/v2/services/discord/DiscordService.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.essentialsx.api.v2.services.discord;
22

3+
import net.essentialsx.api.v2.ChatType;
34
import net.essentialsx.api.v2.events.discord.DiscordChatMessageEvent;
45
import org.bukkit.entity.Player;
56
import org.bukkit.plugin.Plugin;
@@ -20,7 +21,7 @@ public interface DiscordService {
2021
void sendMessage(final MessageType type, final String message, final boolean allowGroupMentions);
2122

2223
/**
23-
* Sends a chat messages to the {@link MessageType.DefaultTypes#CHAT default chat channel} with the same format
24+
* Sends a chat message to the {@link MessageType.DefaultTypes#CHAT default chat channel} with the same format
2425
* used for regular chat messages specified in the EssentialsX Discord configuration.
2526
* <p>
2627
* Note: Messages sent with this method will not fire a {@link DiscordChatMessageEvent}.
@@ -29,6 +30,16 @@ public interface DiscordService {
2930
*/
3031
void sendChatMessage(final Player player, final String chatMessage);
3132

33+
/**
34+
* Sends a chat message to the appropriate chat channel depending on the chat type with the format specified
35+
* for that type in the EssentialsX Discord configuration.
36+
* <p>
37+
* Note: Messages sent with this method will not fire a {@link DiscordChatMessageEvent}.
38+
* @param player The player who send the message.
39+
* @param chatMessage The chat message the player has sent.
40+
*/
41+
void sendChatMessage(final ChatType chatType, final Player player, final String chatMessage);
42+
3243
/**
3344
* Checks if a {@link MessageType} by the given key is already registered.
3445
* @param key The {@link MessageType} key to check.

EssentialsDiscord/src/main/java/net/essentialsx/api/v2/services/discord/MessageType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ public static final class DefaultTypes {
6565
public final static MessageType SERVER_STOP = new MessageType("server-stop", false);
6666
public final static MessageType KICK = new MessageType("kick", false);
6767
public final static MessageType MUTE = new MessageType("mute", false);
68-
private final static MessageType[] VALUES = new MessageType[]{JOIN, FIRST_JOIN, LEAVE, CHAT, DEATH, AFK, ADVANCEMENT, ACTION, SERVER_START, SERVER_STOP, KICK, MUTE};
68+
public final static MessageType LOCAL = new MessageType("local", true);
69+
public final static MessageType QUESTION = new MessageType("question", true);
70+
public final static MessageType SHOUT = new MessageType("shout", true);
71+
private final static MessageType[] VALUES = new MessageType[]{JOIN, FIRST_JOIN, LEAVE, CHAT, DEATH, AFK, ADVANCEMENT, ACTION, SERVER_START, SERVER_STOP, KICK, MUTE, LOCAL, QUESTION, SHOUT};
6972

7073
/**
7174
* Gets an array of all the default {@link MessageType MessageTypes}.

EssentialsDiscord/src/main/java/net/essentialsx/discord/DiscordSettings.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.earth2me.essentials.utils.FormatUtil;
77
import net.dv8tion.jda.api.OnlineStatus;
88
import net.dv8tion.jda.api.entities.Activity;
9+
import net.essentialsx.api.v2.ChatType;
910
import org.apache.logging.log4j.Level;
1011
import org.bukkit.entity.Player;
1112

@@ -107,6 +108,10 @@ public boolean isAlwaysReceivePrimary() {
107108
return config.getBoolean("always-receive-primary", false);
108109
}
109110

111+
public boolean isUseEssentialsEvents() {
112+
return config.getBoolean("use-essentials-events", false);
113+
}
114+
110115
public int getChatDiscordMaxLength() {
111116
return config.getInt("chat.discord-max-length", 2000);
112117
}
@@ -215,17 +220,47 @@ public MessageFormat getDiscordToMcFormat() {
215220
}
216221

217222
public MessageFormat getMcToDiscordFormat(Player player) {
218-
final String format = getFormatString("mc-to-discord");
223+
return getMcToDiscordFormat(player, ChatType.UNKNOWN);
224+
}
225+
226+
public MessageFormat getMcToDiscordFormat(Player player, ChatType chatType) {
227+
final String format = getFormatString(getMcToDiscordFormatKey(chatType));
219228
final String filled;
220229
if (plugin.isPAPI() && format != null) {
221230
filled = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, format);
222231
} else {
223232
filled = format;
224233
}
225-
return generateMessageFormat(filled, "{displayname}: {message}", false,
234+
return generateMessageFormat(filled, getMcToDiscordDefaultFormat(chatType), false,
226235
"username", "displayname", "message", "world", "prefix", "suffix");
227236
}
228237

238+
private String getMcToDiscordFormatKey(ChatType chatType) {
239+
switch (chatType) {
240+
case LOCAL:
241+
return "mc-to-discord-local";
242+
case QUESTION:
243+
return "mc-to-discord-question";
244+
case SHOUT:
245+
return "mc-to-discord-shout";
246+
default:
247+
return "mc-to-discord";
248+
}
249+
}
250+
251+
private String getMcToDiscordDefaultFormat(ChatType chatType) {
252+
switch (chatType) {
253+
case LOCAL:
254+
return "**[Local]** {displayname}: {message}";
255+
case QUESTION:
256+
return "**[Question]** {displayname}: {message}";
257+
case SHOUT:
258+
return "**[Shout]** {displayname}: {message}";
259+
default:
260+
return "{displayname}: {message}";
261+
}
262+
}
263+
229264
public String getLegacyNameFormat() {
230265
// For compatibility with old configs
231266
if (isShowDisplayName()) {

EssentialsDiscord/src/main/java/net/essentialsx/discord/EssentialsDiscord.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class EssentialsDiscord extends JavaPlugin implements IEssentialsModule {
2424
private JDADiscordService jda;
2525
private DiscordSettings settings;
2626
private boolean isPAPI = false;
27+
private boolean isEssentialsChat = false;
2728

2829
@Override
2930
public void onEnable() {
@@ -46,6 +47,8 @@ public void onEnable() {
4647

4748
isPAPI = getServer().getPluginManager().getPlugin("PlaceholderAPI") != null;
4849

50+
isEssentialsChat = getServer().getPluginManager().getPlugin("EssentialsChat") != null;
51+
4952
settings = new DiscordSettings(this);
5053
ess.addReloadListener(settings);
5154

@@ -79,6 +82,7 @@ public static Logger getWrappedLogger() {
7982

8083
public void onReload() {
8184
if (jda != null && !jda.isInvalidStartup()) {
85+
jda.updateListener();
8286
jda.updatePresence();
8387
jda.updatePrimaryChannel();
8488
jda.updateConsoleRelay();
@@ -102,6 +106,10 @@ public boolean isPAPI() {
102106
return isPAPI;
103107
}
104108

109+
public boolean isEssentialsChat() {
110+
return isEssentialsChat;
111+
}
112+
105113
@Override
106114
public void onDisable() {
107115
if (jda != null && !jda.isInvalidStartup()) {

EssentialsDiscord/src/main/java/net/essentialsx/discord/JDADiscordService.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import net.ess3.nms.refl.providers.AchievementListenerProvider;
2424
import net.ess3.nms.refl.providers.AdvancementListenerProvider;
2525
import net.ess3.provider.providers.PaperAdvancementListenerProvider;
26+
import net.essentialsx.api.v2.ChatType;
2627
import net.essentialsx.api.v2.events.discord.DiscordMessageEvent;
2728
import net.essentialsx.api.v2.services.discord.DiscordService;
2829
import net.essentialsx.api.v2.services.discord.InteractionController;
@@ -40,12 +41,15 @@
4041
import net.essentialsx.discord.listeners.BukkitListener;
4142
import net.essentialsx.discord.listeners.DiscordCommandDispatcher;
4243
import net.essentialsx.discord.listeners.DiscordListener;
44+
import net.essentialsx.discord.listeners.EssentialsChatListener;
45+
import net.essentialsx.discord.listeners.BukkitChatListener;
4346
import net.essentialsx.discord.util.ConsoleInjector;
4447
import net.essentialsx.discord.util.DiscordUtil;
4548
import net.essentialsx.discord.util.MessageUtil;
4649
import org.bukkit.Bukkit;
4750
import org.bukkit.entity.Player;
4851
import org.bukkit.event.HandlerList;
52+
import org.bukkit.event.Listener;
4953
import org.bukkit.plugin.Plugin;
5054
import org.bukkit.plugin.ServicePriority;
5155
import org.jetbrains.annotations.NotNull;
@@ -83,6 +87,7 @@ public class JDADiscordService implements DiscordService, IEssentialsModule {
8387
private ConsoleInjector injector;
8488
private DiscordCommandDispatcher commandDispatcher;
8589
private InteractionControllerImpl interactionController;
90+
private Listener chatListener;
8691
private boolean invalidStartup = false;
8792

8893
public JDADiscordService(EssentialsDiscord plugin) {
@@ -214,6 +219,8 @@ public void startup() throws LoginException, InterruptedException {
214219

215220
Bukkit.getPluginManager().registerEvents(new BukkitListener(this), plugin);
216221

222+
updateListener();
223+
217224
try {
218225
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_12_0_R01)) {
219226
try {
@@ -267,9 +274,14 @@ public void sendMessage(MessageType type, String message, boolean allowGroupMent
267274

268275
@Override
269276
public void sendChatMessage(final Player player, final String chatMessage) {
277+
sendChatMessage(ChatType.UNKNOWN, player, chatMessage);
278+
}
279+
280+
@Override
281+
public void sendChatMessage(ChatType chatType, Player player, String chatMessage) {
270282
final User user = getPlugin().getEss().getUser(player);
271283

272-
final String formattedMessage = MessageUtil.formatMessage(getSettings().getMcToDiscordFormat(player),
284+
final String formattedMessage = MessageUtil.formatMessage(getSettings().getMcToDiscordFormat(player, chatType),
273285
MessageUtil.sanitizeDiscordMarkdown(player.getName()),
274286
MessageUtil.sanitizeDiscordMarkdown(player.getDisplayName()),
275287
user.isAuthorized("essentials.discord.markdown") ? chatMessage : MessageUtil.sanitizeDiscordMarkdown(chatMessage),
@@ -287,7 +299,20 @@ public void sendChatMessage(final Player player, final String chatMessage) {
287299
FormatUtil.stripEssentialsFormat(getPlugin().getEss().getPermissionsHandler().getSuffix(player)),
288300
guild.getMember(jda.getSelfUser()).getEffectiveName());
289301

290-
DiscordUtil.dispatchDiscordMessage(this, MessageType.DefaultTypes.CHAT, formattedMessage, user.isAuthorized("essentials.discord.ping"), avatarUrl, formattedName, player.getUniqueId());
302+
DiscordUtil.dispatchDiscordMessage(this, chatTypeToMessageType(chatType), formattedMessage, user.isAuthorized("essentials.discord.ping"), avatarUrl, formattedName, player.getUniqueId());
303+
}
304+
305+
private MessageType chatTypeToMessageType(ChatType chatType) {
306+
switch (chatType) {
307+
case SHOUT:
308+
return MessageType.DefaultTypes.SHOUT;
309+
case QUESTION:
310+
return MessageType.DefaultTypes.QUESTION;
311+
case LOCAL:
312+
return MessageType.DefaultTypes.LOCAL;
313+
default:
314+
return MessageType.DefaultTypes.CHAT;
315+
}
291316
}
292317

293318
@Override
@@ -318,6 +343,19 @@ public String parseMessageEmotes(String message) {
318343
return message;
319344
}
320345

346+
public void updateListener() {
347+
if (chatListener != null) {
348+
HandlerList.unregisterAll(chatListener);
349+
chatListener = null;
350+
}
351+
352+
chatListener = getSettings().isUseEssentialsEvents() && plugin.isEssentialsChat()
353+
? new EssentialsChatListener(this)
354+
: new BukkitChatListener(this);
355+
356+
Bukkit.getPluginManager().registerEvents(chatListener, plugin);
357+
}
358+
321359
public void updatePresence() {
322360
jda.getPresence().setPresence(plugin.getSettings().getStatus(), plugin.getSettings().getStatusActivity());
323361
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.essentialsx.discord.listeners;
2+
3+
import net.essentialsx.api.v2.ChatType;
4+
import net.essentialsx.api.v2.events.discord.DiscordChatMessageEvent;
5+
import net.essentialsx.discord.JDADiscordService;
6+
import org.bukkit.Bukkit;
7+
import org.bukkit.entity.Player;
8+
import org.bukkit.event.EventHandler;
9+
import org.bukkit.event.EventPriority;
10+
import org.bukkit.event.Listener;
11+
import org.bukkit.event.player.AsyncPlayerChatEvent;
12+
13+
public class BukkitChatListener implements Listener {
14+
private final JDADiscordService jda;
15+
16+
public BukkitChatListener(JDADiscordService jda) {
17+
this.jda = jda;
18+
}
19+
20+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
21+
public void onChat(AsyncPlayerChatEvent event) {
22+
final Player player = event.getPlayer();
23+
Bukkit.getScheduler().runTask(jda.getPlugin(), () -> {
24+
final DiscordChatMessageEvent chatEvent = new DiscordChatMessageEvent(event.getPlayer(), event.getMessage(), ChatType.UNKNOWN);
25+
chatEvent.setCancelled(!jda.getSettings().isShowAllChat() && !event.getRecipients().containsAll(Bukkit.getOnlinePlayers()));
26+
Bukkit.getPluginManager().callEvent(chatEvent);
27+
if (chatEvent.isCancelled()) {
28+
return;
29+
}
30+
31+
jda.sendChatMessage(player, chatEvent.getMessage());
32+
});
33+
}
34+
}

EssentialsDiscord/src/main/java/net/essentialsx/discord/listeners/BukkitListener.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,18 @@
1111
import net.ess3.provider.AbstractAchievementEvent;
1212
import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent;
1313
import net.essentialsx.api.v2.events.UserActionEvent;
14-
import net.essentialsx.api.v2.events.discord.DiscordChatMessageEvent;
1514
import net.essentialsx.api.v2.events.discord.DiscordMessageEvent;
1615
import net.essentialsx.api.v2.services.discord.MessageType;
1716
import net.essentialsx.discord.JDADiscordService;
1817
import net.essentialsx.discord.util.DiscordUtil;
1918
import net.essentialsx.discord.util.MessageUtil;
20-
import org.bukkit.Bukkit;
2119
import org.bukkit.ChatColor;
2220
import org.bukkit.GameRule;
2321
import org.bukkit.entity.Player;
2422
import org.bukkit.event.EventHandler;
2523
import org.bukkit.event.EventPriority;
2624
import org.bukkit.event.Listener;
2725
import org.bukkit.event.entity.PlayerDeathEvent;
28-
import org.bukkit.event.player.AsyncPlayerChatEvent;
2926
import org.bukkit.event.player.PlayerKickEvent;
3027
import org.bukkit.event.player.PlayerQuitEvent;
3128

@@ -81,21 +78,6 @@ public void onMute(MuteStatusChangeEvent event) {
8178
}
8279
}
8380

84-
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
85-
public void onChat(AsyncPlayerChatEvent event) {
86-
final Player player = event.getPlayer();
87-
Bukkit.getScheduler().runTask(jda.getPlugin(), () -> {
88-
final DiscordChatMessageEvent chatEvent = new DiscordChatMessageEvent(event.getPlayer(), event.getMessage());
89-
chatEvent.setCancelled(!jda.getSettings().isShowAllChat() && !event.getRecipients().containsAll(Bukkit.getOnlinePlayers()));
90-
Bukkit.getPluginManager().callEvent(chatEvent);
91-
if (chatEvent.isCancelled()) {
92-
return;
93-
}
94-
95-
jda.sendChatMessage(player, chatEvent.getMessage());
96-
});
97-
}
98-
9981
@EventHandler(priority = EventPriority.MONITOR)
10082
public void onJoin(AsyncUserDataLoadEvent event) {
10183
// Delay join to let nickname load

0 commit comments

Comments
 (0)