From 155311b019bd876d53b5e8abbe82edb670fb2620 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 17 Apr 2018 19:05:52 +0200 Subject: [PATCH] MCchat and other fixes - Fixed disallowed command stopping message processing - Fixed failure sending a message to Discord stopping msg proc. - Added timestamps for messages showing when the message was sent - Fixed mentioning in mcchat (now it only detects it's own roles) - Fixed exception reporting (shouldn't break the code block, also only shows buttondevteam lines) --- .../discordplugin/DiscordPlugin.java | 4 +- .../listeners/CommandListener.java | 16 +- .../listeners/ExceptionListener.java | 106 +++-- .../listeners/MCChatListener.java | 399 +++++++++--------- 4 files changed, 264 insertions(+), 261 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 0f1641f..5e1d8dc 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -324,8 +324,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) { - if (message.length() > 1900) { - message = message.substring(0, 1900); + if (message.length() > 1980) { + message = message.substring(0, 1980); Bukkit.getLogger() .warning("Message was too long to send to discord and got truncated. In " + channel.getName()); } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 7d09c6c..c4c9e33 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -1,11 +1,5 @@ package buttondevteam.discordplugin.listeners; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Random; -import java.util.concurrent.TimeUnit; - import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.DiscordCommandBase; @@ -20,6 +14,12 @@ import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.StatusType; import sx.blah.discord.util.EmbedBuilder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Random; +import java.util.concurrent.TimeUnit; + public class CommandListener { private static final String[] serverReadyStrings = new String[] { "In one week from now", // Ali @@ -126,7 +126,7 @@ public class CommandListener { /** * Runs a ChromaBot command. - * + * * @param message * The Discord message * @param mentionedonly @@ -141,7 +141,7 @@ public class CommandListener { final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true); boolean gotmention = checkanddeletemention(cmdwithargs, mention, message); gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention; - for (String mentionRole : (Iterable) message.getRoleMentions().stream().map(r -> r.mention())::iterator) + for (String mentionRole : (Iterable) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(r -> r.mention())::iterator) gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions if (mentionedonly && !gotmention) { message.getChannel().setTypingStatus(false); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java b/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java index eeec43a..1712e0d 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/ExceptionListener.java @@ -1,68 +1,62 @@ package buttondevteam.discordplugin.listeners; +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.TBMCExceptionEvent; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import sx.blah.discord.handle.obj.IRole; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import org.apache.commons.lang.exception.ExceptionUtils; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.TBMCExceptionEvent; -import sx.blah.discord.handle.obj.IRole; - public class ExceptionListener implements Listener { - private List lastthrown = new ArrayList<>(); - private List lastsourcemsg = new ArrayList<>(); + private List lastthrown = new ArrayList<>(); + private List lastsourcemsg = new ArrayList<>(); - @EventHandler - public void onException(TBMCExceptionEvent e) { - if (DiscordPlugin.SafeMode) - return; - if (lastthrown.stream() - .anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace()) - && e.getException().getMessage() == null ? ex.getMessage() == null - : e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message - && lastsourcemsg.contains(e.getSourceMessage())) - return; - SendException(e.getException(), e.getSourceMessage()); - if (lastthrown.size() >= 10) - lastthrown.remove(0); - if (lastsourcemsg.size() >= 10) - lastsourcemsg.remove(0); - lastthrown.add(e.getException()); - lastsourcemsg.add(e.getSourceMessage()); - e.setHandled(); - } + @EventHandler + public void onException(TBMCExceptionEvent e) { + if (DiscordPlugin.SafeMode) + return; + if (lastthrown.stream() + .anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace()) + && e.getException().getMessage() == null ? ex.getMessage() == null + : e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message + && lastsourcemsg.contains(e.getSourceMessage())) + return; + SendException(e.getException(), e.getSourceMessage()); + if (lastthrown.size() >= 10) + lastthrown.remove(0); + if (lastsourcemsg.size() >= 10) + lastsourcemsg.remove(0); + lastthrown.add(e.getException()); + lastsourcemsg.add(e.getSourceMessage()); + e.setHandled(); + } - private static IRole coderRole; + private static IRole coderRole; - private static void SendException(Throwable e, String sourcemessage) { - try { - if (coderRole == null) - coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0); - StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder() - : new StringBuilder(coderRole.mention()).append("\n"); - sb.append(sourcemessage).append("\n"); - sb.append("```").append("\n"); - String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) - .filter(s -> !(s.contains("\tat ") && ( // - s.contains("java.util") // - || s.contains("java.lang") // - || s.contains("net.minecraft.server") // - || s.contains("sun.reflect") // - || s.contains("org.bukkit") // - ))).collect(Collectors.joining("\n")); - if (stackTrace.length() > 1800) - stackTrace = stackTrace.substring(0, 1800); - sb.append(stackTrace).append("\n"); - sb.append("```"); - DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString()); - } catch (Exception ex) { - ex.printStackTrace(); - } - } + private static void SendException(Throwable e, String sourcemessage) { + try { + if (coderRole == null) + coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0); + StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder() + : new StringBuilder(coderRole.mention()).append("\n"); + sb.append(sourcemessage).append("\n"); + sb.append("```").append("\n"); + String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) + .filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam.")) + .collect(Collectors.joining("\n")); + if (stackTrace.length() > 1800) + stackTrace = stackTrace.substring(0, 1800); + sb.append(stackTrace).append("\n"); + sb.append("```"); + DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 4f5907a..df1bf12 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -31,10 +31,8 @@ import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.MissingPermissionsException; import java.awt.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Optional; +import java.time.Instant; +import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -45,91 +43,99 @@ import java.util.stream.Stream; public class MCChatListener implements Listener, IListener { private BukkitTask sendtask; - private LinkedBlockingQueue sendevents = new LinkedBlockingQueue<>(); + private LinkedBlockingQueue> sendevents = new LinkedBlockingQueue<>(); private Runnable sendrunnable; @EventHandler // Minecraft public void onMCChat(TBMCChatEvent ev) { if (ev.isCancelled()) return; - sendevents.add(ev); + sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now())); 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); - - 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); - } + processMCToDiscord(); + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); }; sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); } + private void processMCToDiscord() { + try { + TBMCChatEvent e; + Instant time; + try { + val se = sendevents.take(); // Wait until an element is available + e = se.getKey(); + time = se.getValue(); + } 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); + embed.withTimestamp(time); + 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 occurred 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); + + 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 message to Discord!", ex); + } + } + @RequiredArgsConstructor private static class LastMsgData { public IMessage message; @@ -265,6 +271,7 @@ public class MCChatListener implements Listener, IListener private BukkitTask rectask; private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks + private Runnable recrun; @Override // Discord public void handle(MessageReceivedEvent ev) { @@ -288,133 +295,135 @@ public class MCChatListener implements Listener, IListener 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(); + recrun = () -> { //Don't return in a while loop next time + processDiscordToMC(); + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing + }; + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing + } + + private void processDiscordToMC() { + @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())); + } + + 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; + + 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) + .noneMatch(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; } - 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())); - } - - 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; - - 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."); + 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 { - 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 + 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; } - } 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; + } + 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); + } } /**