diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 1f9019d..4f5907a 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -44,389 +44,391 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class MCChatListener implements Listener, IListener { - private BukkitTask sendtask; - private LinkedBlockingQueue sendevents = new LinkedBlockingQueue<>(); + private BukkitTask sendtask; + private LinkedBlockingQueue sendevents = new LinkedBlockingQueue<>(); + private Runnable sendrunnable; - @EventHandler // Minecraft - public void onMCChat(TBMCChatEvent ev) { - if (ev.isCancelled()) - return; - sendevents.add(ev); - if (sendtask != null) - return; - sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { - try { // Runs forever - Not good, but most plugins don't support reloading the server anyways - while (true) { - TBMCChatEvent e; - try { - e = sendevents.take(); // Wait until an element is available - } catch (InterruptedException ex) { - sendtask.cancel(); - return; - } - final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " // - + (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") // - + (DPUtils.sanitizeString(e.getSender() instanceof Player // - ? ((Player) e.getSender()).getDisplayName() // - : e.getSender().getName())); - final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer) - .withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(), - e.getChannel().color.getGreen(), e.getChannel().color.getBlue())); - // embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "") - // + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false); - if (e.getSender() instanceof Player) - DPUtils.embedWithHead( - embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id=" - + ((Player) e.getSender()).getUniqueId()), - e.getSender().getName()); - else if (e.getSender() instanceof DiscordSenderBase) - embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL()) - .withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id=" - + ((DiscordSenderBase) e.getSender()).getUser().getStringID()); // TODO: Constant/method to get URLs like this - // embed.withFooterText(e.getChannel().DisplayName); - final long nanoTime = System.nanoTime(); - Consumer doit = lastmsgdata -> { - final EmbedObject embedObject = embed.build(); - if (lastmsgdata.message == null || lastmsgdata.message.isDeleted() - || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName()) - || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120 - || !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) { - lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, "", - embedObject); // TODO Use ChromaBot API - lastmsgdata.time = nanoTime; - lastmsgdata.mcchannel = e.getChannel(); - lastmsgdata.content = embedObject.description; - } else - try { - lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n" - + embedObject.description;// The message object doesn't get updated - final LastMsgData _lastmsgdata = lastmsgdata; - DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject)); - } catch (MissingPermissionsException | DiscordException e1) { - TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); - } - }; - // Checks if the given channel is different than where the message was sent from - Predicate isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase) - || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID(); + @EventHandler // Minecraft + public void onMCChat(TBMCChatEvent ev) { + if (ev.isCancelled()) + return; + sendevents.add(ev); + if (sendtask != null) + return; + sendrunnable = () -> { + try { + TBMCChatEvent e; + try { + e = sendevents.take(); // Wait until an element is available + } catch (InterruptedException ex) { + sendtask.cancel(); + sendtask = null; + return; + } + final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " // + + (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") // + + (DPUtils.sanitizeString(e.getSender() instanceof Player // + ? ((Player) e.getSender()).getDisplayName() // + : e.getSender().getName())); + final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer) + .withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(), + e.getChannel().color.getGreen(), e.getChannel().color.getBlue())); + // embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "") + // + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false); + if (e.getSender() instanceof Player) + DPUtils.embedWithHead( + embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id=" + + ((Player) e.getSender()).getUniqueId()), + e.getSender().getName()); + else if (e.getSender() instanceof DiscordSenderBase) + embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL()) + .withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id=" + + ((DiscordSenderBase) e.getSender()).getUser().getStringID()); // TODO: Constant/method to get URLs like this + // embed.withFooterText(e.getChannel().DisplayName); + final long nanoTime = System.nanoTime(); + Consumer doit = lastmsgdata -> { + final EmbedObject embedObject = embed.build(); + if (lastmsgdata.message == null || lastmsgdata.message.isDeleted() + || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName()) + || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120 + || !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) { + lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, "", + embedObject); // TODO Use ChromaBot API + lastmsgdata.time = nanoTime; + lastmsgdata.mcchannel = e.getChannel(); + lastmsgdata.content = embedObject.description; + } else + try { + lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n" + + embedObject.description;// The message object doesn't get updated + final LastMsgData _lastmsgdata = lastmsgdata; + DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject)); + } catch (MissingPermissionsException | DiscordException e1) { + TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); + } + }; + // Checks if the given channel is different than where the message was sent from + Predicate isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase) + || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID(); - if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp")) - && isdifferentchannel.test(DiscordPlugin.chatchannel)) - doit.accept(lastmsgdata == null - ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) - : lastmsgdata); + if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp")) + && isdifferentchannel.test(DiscordPlugin.chatchannel)) + doit.accept(lastmsgdata == null + ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) + : lastmsgdata); - for (LastMsgData data : lastmsgPerUser) { - if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel) - && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) - doit.accept(data); - } - } - } catch (Exception ex) { - TBMCCoreAPI.SendException("Error while sending mesasge to Discord!", ex); - } - }); - } + for (LastMsgData data : lastmsgPerUser) { + if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel) + && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) + doit.accept(data); + } + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); + } catch (Exception ex) { + TBMCCoreAPI.SendException("Error while sending mesasge to Discord!", ex); + } + }; + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); + } - @RequiredArgsConstructor - private static class LastMsgData { - public IMessage message; - public long time; - public String content; - public final IChannel channel; - public Channel mcchannel; - public final IUser user; - public final DiscordPlayer dp; - } + @RequiredArgsConstructor + private static class LastMsgData { + public IMessage message; + public long time; + public String content; + public final IChannel channel; + public Channel mcchannel; + public final IUser user; + public final DiscordPlayer dp; + } - @EventHandler - public void onChatPreprocess(TBMCChatPreprocessEvent event) { - int start = -1; - while ((start = event.getMessage().indexOf('@', start + 1)) != -1) { - int mid = event.getMessage().indexOf('#', start + 1); - if (mid == -1) - return; - int end_ = event.getMessage().indexOf(' ', mid + 1); - if (end_ == -1) - end_ = event.getMessage().length(); - final int end = end_; - final int startF = start; - DiscordPlugin.dc.getUsersByName(event.getMessage().substring(start + 1, mid)).stream() - .filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).findAny() - .ifPresent(user -> event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getName() - + (event.getMessage().length() > end ? event.getMessage().substring(end) : ""))); // TODO: Add formatting - start = end; // Skip any @s inside the mention - } - } + @EventHandler + public void onChatPreprocess(TBMCChatPreprocessEvent event) { + int start = -1; + while ((start = event.getMessage().indexOf('@', start + 1)) != -1) { + int mid = event.getMessage().indexOf('#', start + 1); + if (mid == -1) + return; + int end_ = event.getMessage().indexOf(' ', mid + 1); + if (end_ == -1) + end_ = event.getMessage().length(); + final int end = end_; + final int startF = start; + DiscordPlugin.dc.getUsersByName(event.getMessage().substring(start + 1, mid)).stream() + .filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).findAny() + .ifPresent(user -> event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getName() + + (event.getMessage().length() > end ? event.getMessage().substring(end) : ""))); // TODO: Add formatting + start = end; // Skip any @s inside the mention + } + } - private static final String[] UnconnectedCmds = new String[] { "list", "u", "shrug", "tableflip", "unflip", "mwiki", - "yeehaw" }; + private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki", + "yeehaw"}; - private static LastMsgData lastmsgdata; - private static short lastlist = 0; - private static short lastlistp = 0; - /** - * Used for messages in PMs (mcchat). - */ - private static ArrayList lastmsgPerUser = new ArrayList(); + private static LastMsgData lastmsgdata; + private static short lastlist = 0; + private static short lastlistp = 0; + /** + * Used for messages in PMs (mcchat). + */ + private static ArrayList lastmsgPerUser = new ArrayList(); - public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) { - TBMCPlayer mcp = dp.getAs(TBMCPlayer.class); - if (mcp != null) { // If the accounts aren't connected, can't make a connected sender - val p = Bukkit.getPlayer(mcp.getUUID()); - val op = Bukkit.getOfflinePlayer(mcp.getUUID()); - if (start) { - val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); - ConnectedSenders.put(user.getStringID(), sender); - if (p == null)// Player is offline - If the player is online, that takes precedence - MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, "")); - } else { - val sender = ConnectedSenders.remove(user.getStringID()); - if (p == null)// Player is offline - If the player is online, that takes precedence - MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, "")); - } - } - return start // - ? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs - : lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); - } + public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) { + TBMCPlayer mcp = dp.getAs(TBMCPlayer.class); + if (mcp != null) { // If the accounts aren't connected, can't make a connected sender + val p = Bukkit.getPlayer(mcp.getUUID()); + val op = Bukkit.getOfflinePlayer(mcp.getUUID()); + if (start) { + val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); + ConnectedSenders.put(user.getStringID(), sender); + if (p == null)// Player is offline - If the player is online, that takes precedence + MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, "")); + } else { + val sender = ConnectedSenders.remove(user.getStringID()); + if (p == null)// Player is offline - If the player is online, that takes precedence + MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, "")); + } + } + return start // + ? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs + : lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); + } - // ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender - // Offline public chat......x............................................ - // Online public chat.......x...........................................x - // Offline private chat.....x.......................x.................... - // Online private chat......x.......................x...................x - // If online and enabling private chat, don't login - // If leaving the server and private chat is enabled (has ConnectedPlayer), call login in a task on lowest priority - // If private chat is enabled and joining the server, logout the fake player on highest priority - // If online and disabling private chat, don't logout - // The maps may not contain the senders for UnconnectedSenders + // ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender + // Offline public chat......x............................................ + // Online public chat.......x...........................................x + // Offline private chat.....x.......................x.................... + // Online private chat......x.......................x...................x + // If online and enabling private chat, don't login + // If leaving the server and private chat is enabled (has ConnectedPlayer), call login in a task on lowest priority + // If private chat is enabled and joining the server, logout the fake player on highest priority + // If online and disabling private chat, don't logout + // The maps may not contain the senders for UnconnectedSenders - public static boolean isMinecraftChatEnabled(DiscordPlayer dp) { - return lastmsgPerUser.stream().anyMatch( - lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(dp.getDiscordID())); - } + public static boolean isMinecraftChatEnabled(DiscordPlayer dp) { + return lastmsgPerUser.stream().anyMatch( + lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(dp.getDiscordID())); + } - public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this - return lastmsgPerUser.stream() - .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did)); - } + public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this + return lastmsgPerUser.stream() + .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did)); + } - /** - * May contain P<DiscordID> as key for public chat - */ - public static final HashMap UnconnectedSenders = new HashMap<>(); - public static final HashMap ConnectedSenders = new HashMap<>(); - /** - * May contain P<DiscordID> as key for public chat - */ - public static final HashMap OnlineSenders = new HashMap<>(); - public static short ListC = 0; + /** + * May contain P<DiscordID> as key for public chat + */ + public static final HashMap UnconnectedSenders = new HashMap<>(); + public static final HashMap ConnectedSenders = new HashMap<>(); + /** + * May contain P<DiscordID> as key for public chat + */ + public static final HashMap OnlineSenders = new HashMap<>(); + public static short ListC = 0; - public static void resetLastMessage() { - (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) - : lastmsgdata).message = null; - } // Don't set the whole object to null, the player and channel information should be preserved + public static void resetLastMessage() { + (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) + : lastmsgdata).message = null; + } // Don't set the whole object to null, the player and channel information should be preserved - public static void resetLastMessage(IChannel channel) { - for (LastMsgData data : lastmsgPerUser) - if (data.channel.getLongID() == channel.getLongID()) - data.message = null; // Since only private channels are stored, only those will work anyways - } + public static void resetLastMessage(IChannel channel) { + for (LastMsgData data : lastmsgPerUser) + if (data.channel.getLongID() == channel.getLongID()) + data.message = null; // Since only private channels are stored, only those will work anyways + } - /** - * This overload sends it to the global chat. - */ - public static void sendSystemMessageToChat(String msg) { - forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(msg))); - } + /** + * This overload sends it to the global chat. + */ + public static void sendSystemMessageToChat(String msg) { + forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(msg))); + } - public static void sendSystemMessageToChat(TBMCSystemChatEvent event) { - forAllowedMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(event.getMessage())), - event); - } + public static void sendSystemMessageToChat(TBMCSystemChatEvent event) { + forAllowedMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(event.getMessage())), + event); + } - public static void forAllMCChat(Consumer action) { - action.accept(DiscordPlugin.chatchannel); - for (LastMsgData data : lastmsgPerUser) - action.accept(data.channel); - } + public static void forAllMCChat(Consumer action) { + action.accept(DiscordPlugin.chatchannel); + for (LastMsgData data : lastmsgPerUser) + action.accept(data.channel); + } - private static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { - if (Channel.GlobalChat.ID.equals(event.getChannel().ID)) - action.accept(DiscordPlugin.chatchannel); - for (LastMsgData data : lastmsgPerUser) - if (event.shouldSendTo(getSender(data.channel, data.user, data.dp))) - action.accept(data.channel); - } + private static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { + if (Channel.GlobalChat.ID.equals(event.getChannel().ID)) + action.accept(DiscordPlugin.chatchannel); + for (LastMsgData data : lastmsgPerUser) + if (event.shouldSendTo(getSender(data.channel, data.user, data.dp))) + action.accept(data.channel); + } - private BukkitTask rectask; - private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); - private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks + private BukkitTask rectask; + private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); + private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks - @Override // Discord - public void handle(MessageReceivedEvent ev) { - if (DiscordPlugin.SafeMode) - return; - val author = ev.getMessage().getAuthor(); - if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID()) - && !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))) - return; - if (author.isBot()) - return; - if (ev.getMessage().getContent().equalsIgnoreCase("mcchat")) - return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommandListener) - if (CommandListener.runCommand(ev.getMessage(), true)) - return; - if (!ev.getMessage().getChannel().isPrivate()) - resetLastMessage(); - else - resetLastMessage(ev.getMessage().getChannel()); - lastlist++; - recevents.add(ev); - if (rectask != null) - return; - rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { - while (true) { - @val - sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent event; - try { - event = recevents.take(); - } catch (InterruptedException e1) { - rectask.cancel(); - return; - } - val sender = event.getMessage().getAuthor(); - val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class); - String dmessage = event.getMessage().getContent(); - try { - final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user); + @Override // Discord + public void handle(MessageReceivedEvent ev) { + if (DiscordPlugin.SafeMode) + return; + val author = ev.getMessage().getAuthor(); + if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID()) + && !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))) + return; + if (author.isBot()) + return; + if (ev.getMessage().getContent().equalsIgnoreCase("mcchat")) + return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommandListener) + if (CommandListener.runCommand(ev.getMessage(), true)) + return; + if (!ev.getMessage().getChannel().isPrivate()) + resetLastMessage(); + else + resetLastMessage(ev.getMessage().getChannel()); + lastlist++; + recevents.add(ev); + if (rectask != null) + return; + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { + while (true) { + @val + sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent event; + try { + event = recevents.take(); + } catch (InterruptedException e1) { + rectask.cancel(); + return; + } + val sender = event.getMessage().getAuthor(); + val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class); + String dmessage = event.getMessage().getContent(); + try { + final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user); - for (IUser u : event.getMessage().getMentions()) { - dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting - final String nick = u.getNicknameForGuild(DiscordPlugin.mainServer); - dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); - } + for (IUser u : event.getMessage().getMentions()) { + dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting + final String nick = u.getNicknameForGuild(DiscordPlugin.mainServer); + dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); + } - BiConsumer sendChatMessage = (channel, msg) -> // - TBMCChatAPI.SendChatMessage(channel, dsender, - msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() - .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) - : "")); + BiConsumer sendChatMessage = (channel, msg) -> // + TBMCChatAPI.SendChatMessage(channel, dsender, + msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() + .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) + : "")); - boolean react = false; + boolean react = false; - if (dmessage.startsWith("/")) { // Ingame command - DPUtils.perform(() -> { - if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) - event.getMessage().delete(); - }); - final String cmd = dmessage.substring(1).toLowerCase(); - if (dsender instanceof DiscordSender && !Arrays.stream(UnconnectedCmds) - .anyMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) { - // Command not whitelisted - dsender.sendMessage("Sorry, you can only access these commands:\n" - + Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc) - .collect(Collectors.joining(", ")) - + (user.getConnectedID(TBMCPlayer.class) == null - ? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in " - + DiscordPlugin.botchannel.mention() - + "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!" - : "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!")); - return; - } - if (lastlist > 5) { - ListC = 0; - lastlist = 0; - } - if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already - { - dsender.sendMessage("Stop it. You know the answer."); - lastlist = 0; - } else { - int spi = cmd.indexOf(' '); - final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi); - Optional ch = Channel.getChannels().stream() - .filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny(); - if (!ch.isPresent()) - Bukkit.getScheduler().runTask(DiscordPlugin.plugin, - () -> VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd)); - else { - Channel chc = ch.get(); - if (!chc.ID.equals(Channel.GlobalChat.ID) - && !event.getMessage().getChannel().isPrivate()) - dsender.sendMessage( - "You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels."); - else { - if (spi == -1) // Switch channels - { - val oldch = dsender.getMcchannel(); - if (oldch instanceof ChatRoom) - ((ChatRoom) oldch).leaveRoom(dsender); - if (!oldch.ID.equals(chc.ID)) { - dsender.setMcchannel(chc); - if (chc instanceof ChatRoom) - ((ChatRoom) chc).joinRoom(dsender); - } else - dsender.setMcchannel(Channel.GlobalChat); - dsender.sendMessage("You're now talking in: " - + DPUtils.sanitizeString(dsender.getMcchannel().DisplayName)); - } else { // Send single message - sendChatMessage.accept(chc, cmd.substring(spi + 1)); - react = true; - } - } - } - } - lastlistp = (short) Bukkit.getOnlinePlayers().size(); - } else {// Not a command - if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 - && !event.getChannel().isPrivate()) - TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, - (dsender instanceof Player ? ((Player) dsender).getDisplayName() - : dsender.getName()) + " pinned a message on Discord."); - else { - sendChatMessage.accept(dsender.getMcchannel(), dmessage); - react = true; - } - } - if (react) { - try { - /* - * System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription()) - * .collect(Collectors.joining("\n"))); - */ - if (lastmsgfromd != null) { - DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(), - DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time - } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e); - } - lastmsgfromd = event.getMessage(); - DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); - } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); - return; - } - } - }); + if (dmessage.startsWith("/")) { // Ingame command + DPUtils.perform(() -> { + if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) + event.getMessage().delete(); + }); + final String cmd = dmessage.substring(1).toLowerCase(); + if (dsender instanceof DiscordSender && !Arrays.stream(UnconnectedCmds) + .anyMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) { + // Command not whitelisted + dsender.sendMessage("Sorry, you can only access these commands:\n" + + Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc) + .collect(Collectors.joining(", ")) + + (user.getConnectedID(TBMCPlayer.class) == null + ? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in " + + DiscordPlugin.botchannel.mention() + + "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!" + : "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!")); + return; + } + if (lastlist > 5) { + ListC = 0; + lastlist = 0; + } + if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already + { + dsender.sendMessage("Stop it. You know the answer."); + lastlist = 0; + } else { + int spi = cmd.indexOf(' '); + final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi); + Optional ch = Channel.getChannels().stream() + .filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny(); + if (!ch.isPresent()) + Bukkit.getScheduler().runTask(DiscordPlugin.plugin, + () -> VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd)); + else { + Channel chc = ch.get(); + if (!chc.ID.equals(Channel.GlobalChat.ID) + && !event.getMessage().getChannel().isPrivate()) + dsender.sendMessage( + "You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels."); + else { + if (spi == -1) // Switch channels + { + val oldch = dsender.getMcchannel(); + if (oldch instanceof ChatRoom) + ((ChatRoom) oldch).leaveRoom(dsender); + if (!oldch.ID.equals(chc.ID)) { + dsender.setMcchannel(chc); + if (chc instanceof ChatRoom) + ((ChatRoom) chc).joinRoom(dsender); + } else + dsender.setMcchannel(Channel.GlobalChat); + dsender.sendMessage("You're now talking in: " + + DPUtils.sanitizeString(dsender.getMcchannel().DisplayName)); + } else { // Send single message + sendChatMessage.accept(chc, cmd.substring(spi + 1)); + react = true; + } + } + } + } + lastlistp = (short) Bukkit.getOnlinePlayers().size(); + } else {// Not a command + if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 + && !event.getChannel().isPrivate()) + TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, + (dsender instanceof Player ? ((Player) dsender).getDisplayName() + : dsender.getName()) + " pinned a message on Discord."); + else { + sendChatMessage.accept(dsender.getMcchannel(), dmessage); + react = true; + } + } + if (react) { + try { + /* + * System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription()) + * .collect(Collectors.joining("\n"))); + */ + if (lastmsgfromd != null) { + DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(), + DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time + } + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e); + } + lastmsgfromd = event.getMessage(); + DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); + } + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); + return; + } + } + }); - } + } - /** - * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. - */ - private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { - val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); - return Stream.>>of( // https://stackoverflow.com/a/28833677/2703239 - () -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null - () -> Optional.ofNullable(ConnectedSenders.get(key)), // This doesn't support the public chat, but it'll always return null for it - () -> Optional.ofNullable(UnconnectedSenders.get(key)), () -> { - val dsender = new DiscordSender(author, channel); - UnconnectedSenders.put(key, dsender); - return Optional.of(dsender); - }).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get(); - } + /** + * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. + */ + private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { + val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); + return Stream.>>of( // https://stackoverflow.com/a/28833677/2703239 + () -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null + () -> Optional.ofNullable(ConnectedSenders.get(key)), // This doesn't support the public chat, but it'll always return null for it + () -> Optional.ofNullable(UnconnectedSenders.get(key)), () -> { + val dsender = new DiscordSender(author, channel); + UnconnectedSenders.put(key, dsender); + return Optional.of(dsender); + }).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get(); + } } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java index f7260b0..42e85a0 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -1,15 +1,17 @@ package buttondevteam.discordplugin.listeners; -import java.util.Arrays; -import java.util.logging.Level; - +import buttondevteam.discordplugin.*; +import buttondevteam.discordplugin.commands.ConnectCommand; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.TBMCSystemChatEvent; +import buttondevteam.lib.player.*; +import com.earth2me.essentials.CommandSource; +import lombok.val; +import net.ess3.api.events.AfkStatusChangeEvent; +import net.ess3.api.events.MuteStatusChangeEvent; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; +import org.bukkit.event.*; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerKickEvent; @@ -21,211 +23,195 @@ import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.plugin.AuthorNagException; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredListener; - -import com.earth2me.essentials.CommandSource; - -import buttondevteam.discordplugin.ChromaBot; -import buttondevteam.discordplugin.DPUtils; -import buttondevteam.discordplugin.DiscordConnectedPlayer; -import buttondevteam.discordplugin.DiscordPlayer; -import buttondevteam.discordplugin.DiscordPlayerSender; -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.discordplugin.commands.ConnectCommand; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.TBMCSystemChatEvent; -import buttondevteam.lib.player.*; -import lombok.val; -import net.ess3.api.events.*; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.MissingPermissionsException; +import java.util.Arrays; +import java.util.logging.Level; + public class MCListener implements Listener { - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerLogin(PlayerLoginEvent e) { - if (e.getResult() != Result.ALLOWED) - return; - MCChatListener.ConnectedSenders.values().stream() - .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerLogin(PlayerLoginEvent e) { + if (e.getResult() != Result.ALLOWED) + return; + MCChatListener.ConnectedSenders.values().stream() + .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() + .ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); + } - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerJoin(TBMCPlayerJoinEvent e) { - if (e.getPlayer() instanceof DiscordConnectedPlayer) - return; // Don't show the joined message for the fake player - final Player p = e.getPlayer(); - DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); - if (dp != null) { - val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); - MCChatListener.OnlineSenders.put(dp.getDiscordID(), - new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); - MCChatListener.OnlineSenders.put("P" + dp.getDiscordID(), - new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); - } - if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { - IUser user = DiscordPlugin.dc - .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); - p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() - + " do /discord accept"); - p.sendMessage("§bIf it wasn't you, do /discord decline"); - } - if (!DiscordPlugin.hooked) - MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game"); - MCChatListener.ListC = 0; - ChromaBot.getInstance().updatePlayerList(); - } + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(TBMCPlayerJoinEvent e) { + if (e.getPlayer() instanceof DiscordConnectedPlayer) + return; // Don't show the joined message for the fake player + final Player p = e.getPlayer(); + DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); + if (dp != null) { + val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); + MCChatListener.OnlineSenders.put(dp.getDiscordID(), + new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); + MCChatListener.OnlineSenders.put("P" + dp.getDiscordID(), + new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); + } + if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { + IUser user = DiscordPlugin.dc + .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); + p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() + + " do /discord accept"); + p.sendMessage("§bIf it wasn't you, do /discord decline"); + } + if (!DiscordPlugin.hooked) + MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game"); + MCChatListener.ListC = 0; + ChromaBot.getInstance().updatePlayerList(); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerLeave(TBMCPlayerQuitEvent e) { - if (e.getPlayer() instanceof DiscordConnectedPlayer) - return; // Only care about real users - MCChatListener.OnlineSenders.entrySet() - .removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())); - Bukkit.getScheduler().runTask(DiscordPlugin.plugin, - () -> MCChatListener.ConnectedSenders.values().stream() - .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); - Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, - ChromaBot.getInstance()::updatePlayerList, 5); - } + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerLeave(TBMCPlayerQuitEvent e) { + if (e.getPlayer() instanceof DiscordConnectedPlayer) + return; // Only care about real users + MCChatListener.OnlineSenders.entrySet() + .removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())); + Bukkit.getScheduler().runTask(DiscordPlugin.plugin, + () -> MCChatListener.ConnectedSenders.values().stream() + .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() + .ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); + Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, + ChromaBot.getInstance()::updatePlayerList, 5); + } - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerKick(PlayerKickEvent e) { - if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting") - && !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special - MCChatListener.sendSystemMessageToChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook - } + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerKick(PlayerKickEvent e) { + if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting") + && !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special + MCChatListener.sendSystemMessageToChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook + } - @EventHandler - public void onGetInfo(TBMCPlayerGetInfoEvent e) { - if (DiscordPlugin.SafeMode) - return; - DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class); - if (dp == null || dp.getDiscordID() == null || dp.getDiscordID() == "") - return; - IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); - e.addInfo("Discord tag: " + user.getName() + "#" + user.getDiscriminator()); - e.addInfo(user.getPresence().getStatus().toString()); - if (user.getPresence().getPlayingText().isPresent()) - e.addInfo("Playing " + user.getPresence().getPlayingText().get()); - else if (user.getPresence().getStreamingUrl().isPresent()) - e.addInfo("Streaming " + user.getPresence().getStreamingUrl().get()); - } + @EventHandler + public void onGetInfo(TBMCPlayerGetInfoEvent e) { + if (DiscordPlugin.SafeMode) + return; + DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class); + if (dp == null || dp.getDiscordID() == null || dp.getDiscordID() == "") + return; + IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); + e.addInfo("Discord tag: " + user.getName() + "#" + user.getDiscriminator()); + e.addInfo(user.getPresence().getStatus().toString()); + if (user.getPresence().getActivity().isPresent() && user.getPresence().getText().isPresent()) + e.addInfo(user.getPresence().getActivity().get() + ": " + user.getPresence().getText().get()); + } - @EventHandler(priority = EventPriority.LOW) - public void onPlayerDeath(PlayerDeathEvent e) { - if (!DiscordPlugin.hooked) - MCChatListener.sendSystemMessageToChat(e.getDeathMessage()); - } + @EventHandler(priority = EventPriority.LOW) + public void onPlayerDeath(PlayerDeathEvent e) { + if (!DiscordPlugin.hooked) + MCChatListener.sendSystemMessageToChat(e.getDeathMessage()); + } - @EventHandler - public void onPlayerAFK(AfkStatusChangeEvent e) { - if (e.isCancelled() || !e.getAffected().getBase().isOnline()) - return; - MCChatListener.sendSystemMessageToChat(DPUtils.sanitizeString(e.getAffected().getBase().getDisplayName()) - + " is " + (e.getValue() ? "now" : "no longer") + " AFK."); - } + @EventHandler + public void onPlayerAFK(AfkStatusChangeEvent e) { + if (e.isCancelled() || !e.getAffected().getBase().isOnline()) + return; + MCChatListener.sendSystemMessageToChat(DPUtils.sanitizeString(e.getAffected().getBase().getDisplayName()) + + " is " + (e.getValue() ? "now" : "no longer") + " AFK."); + } - @EventHandler - public void onServerCommand(ServerCommandEvent e) { - DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped - } + @EventHandler + public void onServerCommand(ServerCommandEvent e) { + DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped + } - @EventHandler - public void onPlayerMute(MuteStatusChangeEvent e) { - try { - DPUtils.performNoWait(() -> { - final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L); - final CommandSource source = e.getAffected().getSource(); - if (!source.isPlayer()) - return; - final IUser user = DiscordPlugin.dc.getUserByID( - Long.parseLong(TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class) - .getAs(DiscordPlayer.class).getDiscordID())); // TODO: Use long - if (e.getValue()) - user.addRole(role); - else - user.removeRole(role); - }); - } catch (DiscordException | MissingPermissionsException ex) { - TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!", - ex); - } - } + @EventHandler + public void onPlayerMute(MuteStatusChangeEvent e) { + try { + DPUtils.performNoWait(() -> { + final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L); + final CommandSource source = e.getAffected().getSource(); + if (!source.isPlayer()) + return; + final IUser user = DiscordPlugin.dc.getUserByID( + Long.parseLong(TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class) + .getAs(DiscordPlayer.class).getDiscordID())); // TODO: Use long + if (e.getValue()) + user.addRole(role); + else + user.removeRole(role); + }); + } catch (DiscordException | MissingPermissionsException ex) { + TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!", + ex); + } + } - @EventHandler - public void onChatSystemMessage(TBMCSystemChatEvent event) { - MCChatListener.sendSystemMessageToChat(event); - } + @EventHandler + public void onChatSystemMessage(TBMCSystemChatEvent event) { + MCChatListener.sendSystemMessageToChat(event); + } - @EventHandler - public void onBroadcastMessage(BroadcastMessageEvent event) { - MCChatListener.sendSystemMessageToChat(event.getMessage()); - } + @EventHandler + public void onBroadcastMessage(BroadcastMessageEvent event) { + MCChatListener.sendSystemMessageToChat(event.getMessage()); + } - private static final String[] EXCLUDED_PLUGINS = { "ProtocolLib", "LibsDisguises" }; + private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises"}; - public static void callEventExcludingSome(Event event) { - callEventExcluding(event, EXCLUDED_PLUGINS); - } + public static void callEventExcludingSome(Event event) { + callEventExcluding(event, EXCLUDED_PLUGINS); + } - /** - * Calls an event with the given details. - *

- * This method only synchronizes when the event is not asynchronous. - * - * @param event - * Event details - * @param plugins - * The plugins to exclude. Not case sensitive. - */ - private static void callEventExcluding(Event event, String... plugins) { // Copied from Spigot-API and modified a bit - if (event.isAsynchronous()) { - if (Thread.holdsLock(Bukkit.getPluginManager())) { - throw new IllegalStateException( - event.getEventName() + " cannot be triggered asynchronously from inside synchronized code."); - } - if (Bukkit.getServer().isPrimaryThread()) { - throw new IllegalStateException( - event.getEventName() + " cannot be triggered asynchronously from primary server thread."); - } - fireEventExcluding(event, plugins); - } else { - synchronized (Bukkit.getPluginManager()) { - fireEventExcluding(event, plugins); - } - } - } + /** + * Calls an event with the given details. + *

+ * This method only synchronizes when the event is not asynchronous. + * + * @param event Event details + * @param plugins The plugins to exclude. Not case sensitive. + */ + private static void callEventExcluding(Event event, String... plugins) { // Copied from Spigot-API and modified a bit + if (event.isAsynchronous()) { + if (Thread.holdsLock(Bukkit.getPluginManager())) { + throw new IllegalStateException( + event.getEventName() + " cannot be triggered asynchronously from inside synchronized code."); + } + if (Bukkit.getServer().isPrimaryThread()) { + throw new IllegalStateException( + event.getEventName() + " cannot be triggered asynchronously from primary server thread."); + } + fireEventExcluding(event, plugins); + } else { + synchronized (Bukkit.getPluginManager()) { + fireEventExcluding(event, plugins); + } + } + } - private static void fireEventExcluding(Event event, String... plugins) { - HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API - RegisteredListener[] listeners = handlers.getRegisteredListeners(); - val server = Bukkit.getServer(); + private static void fireEventExcluding(Event event, String... plugins) { + HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API + RegisteredListener[] listeners = handlers.getRegisteredListeners(); + val server = Bukkit.getServer(); - for (RegisteredListener registration : listeners) { - if (!registration.getPlugin().isEnabled() - || Arrays.stream(plugins).anyMatch(p -> p.equalsIgnoreCase(registration.getPlugin().getName()))) - continue; // Modified to exclude plugins + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled() + || Arrays.stream(plugins).anyMatch(p -> p.equalsIgnoreCase(registration.getPlugin().getName()))) + continue; // Modified to exclude plugins - try { - registration.callEvent(event); - } catch (AuthorNagException ex) { - Plugin plugin = registration.getPlugin(); + try { + registration.callEvent(event); + } catch (AuthorNagException ex) { + Plugin plugin = registration.getPlugin(); - if (plugin.isNaggable()) { - plugin.setNaggable(false); + if (plugin.isNaggable()) { + plugin.setNaggable(false); - server.getLogger().log(Level.SEVERE, - String.format("Nag author(s): '%s' of '%s' about the following: %s", - plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(), - ex.getMessage())); - } - } catch (Throwable ex) { - server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " - + registration.getPlugin().getDescription().getFullName(), ex); - } - } - } + server.getLogger().log(Level.SEVERE, + String.format("Nag author(s): '%s' of '%s' about the following: %s", + plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(), + ex.getMessage())); + } + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + + registration.getPlugin().getDescription().getFullName(), ex); + } + } + } }