From e47f8abb05c26209670f81cfd9df7bfee67d3cf6 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 13 Jun 2018 23:54:27 +0200 Subject: [PATCH] Channelcon chat works! groupid, not args... that took a while to track down... Various fixes regarding channelcon Saving channel connections works Fromcmd fix for channel cmds Only allow game roles from the main server Game role fix Only allowing one connection per group for now --- .../discordplugin/ChromaBot.java | 10 +-- .../buttondevteam/discordplugin/DPUtils.java | 2 - .../discordplugin/DiscordPlugin.java | 60 +++++++++++------- .../commands/ChannelconCommand.java | 10 ++- .../listeners/CommandListener.java | 4 +- .../listeners/MCChatListener.java | 63 +++++++++++-------- 6 files changed, 86 insertions(+), 63 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/ChromaBot.java b/src/main/java/buttondevteam/discordplugin/ChromaBot.java index e67b431..e597095 100755 --- a/src/main/java/buttondevteam/discordplugin/ChromaBot.java +++ b/src/main/java/buttondevteam/discordplugin/ChromaBot.java @@ -46,7 +46,7 @@ public class ChromaBot { } /** - * Send a message to the chat channel and private chats. + * Send a message to the chat channels and private chats. * * @param message * The message to send, duh @@ -72,7 +72,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -85,7 +85,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -100,7 +100,7 @@ public class ChromaBot { } /** - * Send a fancy message to the chat channel. This will show a bold text with a colored line. + * Send a fancy message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh @@ -117,7 +117,7 @@ public class ChromaBot { } /** - * Send a message to the chat channel. This will show a bold text with a colored line. + * Send a message to the chat channels. This will show a bold text with a colored line. * * @param message * The message to send, duh diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index d7c3bcb..abc1f8f 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -58,10 +58,8 @@ public final class DPUtils { */ @Nullable public static T perform(IRequest action) { - System.out.println("performA"); if (DiscordPlugin.SafeMode) return null; - System.out.println("performB"); if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <-- // throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag."); Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!"); diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 2bbfa93..170c789 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -4,6 +4,7 @@ import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.listeners.*; import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.ChromaGamerBase; import com.google.common.io.Files; @@ -32,6 +33,7 @@ import java.awt.*; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -132,12 +134,26 @@ public class DiscordPlugin extends JavaPlugin implements IListener { task.cancel(); if (!sent) { new ChromaBot(this).updatePlayerList(); - //Get all roles with the default color - /*GameRoles = mainServer.getRoles().stream().filter(r -> { - System.out.println(r.getName()+" - "+r.getColor().toString()+" "+r.getColor().getAlpha()); - return r.getColor().getAlpha() == 0; - }).map(IRole::getName).collect(Collectors.toList()); //r=149,g=165,b=166*/ GameRoles = mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList()); + + val chcons = getConfig().getConfigurationSection("chcons"); + if (chcons != null) { + val chconkeys = chcons.getKeys(false); + for (val chconkey : chconkeys) { + val chcon = chcons.getConfigurationSection(chconkey); + val mcch = Channel.getChannels().stream().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny(); + val ch = dc.getChannelByID(chcon.getLong("chid")); + val did = chcon.getLong("did"); + val dp = DiscordPlayer.getUser(Long.toString(did), DiscordPlayer.class); + val user = dc.fetchUser(did); + val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname")); + val groupid = chcon.getString("groupid"); + if (!mcch.isPresent() || ch == null || user == null || groupid == null) + continue; + MCChatListener.addCustomChat(ch, groupid, mcch.get(), dp, user, dcp); + } + } + DiscordCommandBase.registerCommands(); if (getConfig().getBoolean("serverup", false)) { ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.YELLOW) @@ -210,6 +226,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } public boolean isGameRole(IRole r) { + if (r.getGuild().getLongID() != mainServer.getLongID()) + return false; //Only allow on the main server val rc = new Color(149, 165, 166, 0); return r.getColor().equals(rc) && r.getPosition() < mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role @@ -223,16 +241,25 @@ public class DiscordPlugin extends JavaPlugin implements IListener { @Override public void onDisable() { stop = true; - System.out.println("X"); for (val entry : MCChatListener.ConnectedSenders.entrySet()) MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), "")); - System.out.println("Y"); getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastseentime", lastseentime); getConfig().set("serverup", false); - System.out.println("Z"); + + val chcons = MCChatListener.getCustomChats(); + val chconsc = getConfig().createSection("chcons"); + for (val chcon : chcons) { + val chconc = chconsc.createSection(chcon.channel.getStringID()); + chconc.set("mcchid", chcon.mcchannel.ID); + chconc.set("chid", chcon.channel.getLongID()); + chconc.set("did", chcon.user.getLongID()); + chconc.set("mcuid", chcon.dcp.getUniqueId().toString()); + chconc.set("mcname", chcon.dcp.getName()); + chconc.set("groupid", chcon.groupID); + } + saveConfig(); - System.out.println("XX"); MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannelWait(ch, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED) .withTitle(Restart ? "Server restarting" : "Server stopping") @@ -245,19 +272,13 @@ public class DiscordPlugin extends JavaPlugin implements IListener { + "asked *politely* to leave the server for a bit.") : "") .build(), 5, TimeUnit.SECONDS)); - System.out.println("XY"); ChromaBot.getInstance().updatePlayerList(); try { - System.out.println("XZ"); SafeMode = true; // Stop interacting with Discord MCChatListener.stop(); - System.out.println("YX"); ChromaBot.delete(); - System.out.println("YY"); dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing - System.out.println("YZ"); dc.logout(); - System.out.println("ZX"); } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e); } @@ -346,12 +367,10 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed) { - System.out.println("lol"); return sendMessageToChannel(channel, message, embed, true); } public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed, long timeout, TimeUnit unit) { - System.out.println("lol!"); return sendMessageToChannel(channel, message, embed, true, timeout, unit); } @@ -360,26 +379,19 @@ public class DiscordPlugin extends JavaPlugin implements IListener { } private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) { - System.out.println("lolwut"); if (message.length() > 1980) { - System.out.println("wut"); message = message.substring(0, 1980); Bukkit.getLogger() .warning("Message was too long to send to discord and got truncated. In " + channel.getName()); - System.out.println("wat"); } - System.out.println("wot"); try { - System.out.println("sendA"); if (channel == chatchannel) MCChatListener.resetLastMessage(); // If this is a chat message, it'll be set again else if (channel.isPrivate()) MCChatListener.resetLastMessage(channel); - System.out.println("sendB"); final String content = message; RequestBuffer.IRequest r = () -> embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false); - System.out.println("sendC"); if (wait) { if (unit != null) return DPUtils.perform(r, timeout, unit); diff --git a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java index 44c88a7..d9a1c8f 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java @@ -28,7 +28,6 @@ public class ChannelconCommand extends DiscordCommandBase { message.reply("you need to have manage permissions for this channel!"); return true; } - //TODO: What if they no longer have permission to view the channel - check on some message events and startup - if somebody who can view the channel (on both platforms) has their accounts connected, keep it if (MCChatListener.hasCustomChat(message.getChannel())) { if (args.equalsIgnoreCase("remove")) { if (MCChatListener.removeCustomChat(message.getChannel())) @@ -51,14 +50,19 @@ public class ChannelconCommand extends DiscordCommandBase { message.reply("you need to connect your Minecraft account. On our server in #bot do /connect "); return true; } - val ev = new TBMCChannelConnectFakeEvent(new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName()), chan.get()); + DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName()); + val ev = new TBMCChannelConnectFakeEvent(dcp, chan.get()); //Using a fake player with no login/logout, should be fine for this event String groupid = ev.getGroupID(ev.getSender()); //We're not trying to send in a specific group, we want to know which group the user belongs to (so not getGroupID()) if (groupid == null) { message.reply("sorry, that didn't work. You cannot use that Minecraft channel."); return true; } - MCChatListener.addCustomChat(message.getChannel(), args, ev.getChannel(), dp, message.getAuthor()); //TODO: SAVE + if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) { + message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm."); + return true; + } + MCChatListener.addCustomChat(message.getChannel(), groupid, ev.getChannel(), dp, message.getAuthor(), dcp); message.reply("alright, connection made to group `" + groupid + "`!"); return true; } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 12fbdbd..76ae457 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -131,7 +131,7 @@ public class CommandListener { } }, (IListener) event -> { Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> { - if (event.getRole().isDeleted() || DiscordPlugin.plugin.isGameRole(event.getRole())) + if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole())) return; //Deleted or not a game role DiscordPlugin.GameRoles.add(event.getRole().getName()); DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default."); @@ -216,7 +216,7 @@ public class CommandListener { else cmdwithargs.replace(0, cmdwithargs.length(), "help"); else { - if (cmdwithargs.charAt(0) == '/') + if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/') cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat return false; } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 2754e63..d4a3ce9 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -11,6 +11,7 @@ import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.TBMCPlayer; import com.vdurmont.emoji.EmojiParser; +import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.val; import org.bukkit.Bukkit; @@ -34,9 +35,10 @@ import sx.blah.discord.util.MissingPermissionsException; import java.awt.*; import java.time.Instant; import java.util.*; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; -import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -142,8 +144,8 @@ public class MCChatListener implements Listener, IListener val lmd = iterator.next(); if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord && e.getChannel().ID.equals(lmd.mcchannel.ID)) //If it's from a command, the command msg has been deleted, so we need to send it - if (e.shouldSendTo(getSender(lmd.channel, lmd.user)) && e.getGroupID().equals(lmd.groupID)) - doit.accept(lmd); //TODO: Store dcp and check that both ways, add option to not check sender perms on msg + if (e.shouldSendTo(lmd.dcp) && e.getGroupID().equals(lmd.groupID)) //Check original user's permissions + doit.accept(lmd); else { iterator.remove(); //If the user no longer has permission, remove the connection DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed."); @@ -155,7 +157,7 @@ public class MCChatListener implements Listener, IListener } @RequiredArgsConstructor - private static class LastMsgData { + public static class LastMsgData { public IMessage message; public long time; public String content; @@ -165,15 +167,17 @@ public class MCChatListener implements Listener, IListener public final DiscordPlayer dp; } - private static class CustomLMD extends LastMsgData { + public static class CustomLMD extends LastMsgData { public final String groupID; public final Channel mcchannel; + public final DiscordConnectedPlayer dcp; - public CustomLMD(IChannel channel, IUser user, DiscordPlayer dp, String groupid, Channel mcchannel) { + public CustomLMD(@NonNull IChannel channel, @NonNull IUser user, @NonNull DiscordPlayer dp, + @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp) { super(channel, user, dp); groupID = groupid; this.mcchannel = mcchannel; - + this.dcp = dcp; } } @@ -254,8 +258,8 @@ public class MCChatListener implements Listener, IListener .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did)); } - public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, DiscordPlayer dp, IUser user) { - val lmd = new CustomLMD(channel, user, dp, groupid, mcchannel); + public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, DiscordPlayer dp, IUser user, DiscordConnectedPlayer dcp) { + val lmd = new CustomLMD(channel, user, dp, groupid, mcchannel, dcp); lastmsgCustom.add(lmd); } @@ -271,6 +275,10 @@ public class MCChatListener implements Listener, IListener return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); } + public static List getCustomChats() { + return Collections.unmodifiableList(lastmsgCustom); + } + /** * May contain P<DiscordID> as key for public chat */ @@ -312,12 +320,10 @@ public class MCChatListener implements Listener, IListener } public static void forAllMCChat(Consumer action) { - System.out.println("XA"); action.accept(DiscordPlugin.chatchannel); - System.out.println("XB"); for (LastMsgData data : lastmsgPerUser) action.accept(data.channel); - System.out.println("XC"); + lastmsgCustom.forEach(cc -> action.accept(cc.channel)); } private static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { @@ -326,6 +332,8 @@ public class MCChatListener implements Listener, IListener for (LastMsgData data : lastmsgPerUser) if (event.shouldSendTo(getSender(data.channel, data.user))) action.accept(data.channel); + lastmsgCustom.stream().filter(data -> event.shouldSendTo(data.dcp)) + .map(data -> data.channel).forEach(action); } public static void stop() { @@ -398,11 +406,12 @@ public class MCChatListener implements Listener, IListener dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?) dmessage = dmessage.replaceAll(":(\\S+)\\|type_(?:(\\d)|(1)_2):", ":$1::skin-tone-$2:"); //Convert to Discord's format so it still shows up - BiConsumer sendChatMessage = (channel, msg) -> // - TBMCChatAPI.SendChatMessage(channel, dsender, - msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() + Function getChatMessage = msg -> // + msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) - : "")); + : ""); + + CustomLMD clmd = getCustomChat(event.getChannel()); boolean react = false; @@ -411,7 +420,7 @@ public class MCChatListener implements Listener, IListener if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) event.getMessage().delete(); }); - preprocessChat(dsender, dmessage); + //preprocessChat(dsender, dmessage); - Same is done below final String cmdlowercased = dmessage.substring(1).toLowerCase(); if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds) .noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) { @@ -468,7 +477,11 @@ public class MCChatListener implements Listener, IListener dsender.sendMessage("You're now talking in: " + DPUtils.sanitizeString(dsender.getMcchannel().DisplayName)); } else { // Send single message - sendChatMessage.accept(chc, event.getMessage().getContent().substring(spi + 2)); + final String msg = event.getMessage().getContent().substring(spi + 2); + if (clmd == null) + TBMCChatAPI.SendChatMessage(chc, dsender, getChatMessage.apply(msg), true); + else + TBMCChatAPI.SendChatMessageDontCheckSender(chc, dsender, getChatMessage.apply(msg), true, clmd.dcp); react = true; } } @@ -481,20 +494,16 @@ public class MCChatListener implements Listener, IListener TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, "everyone", (dsender instanceof Player ? ((Player) dsender).getDisplayName() : dsender.getName()) + " pinned a message on Discord."); - else if (hasCustomChat(event.getChannel())) { - val cc = getCustomChat(event.getChannel()); - sendChatMessage.accept(cc.mcchannel, dmessage); - } else { - sendChatMessage.accept(dsender.getMcchannel(), dmessage); + else { + if (clmd != null) + TBMCChatAPI.SendChatMessageDontCheckSender(clmd.mcchannel, dsender, getChatMessage.apply(dmessage), false, clmd.dcp); + else + TBMCChatAPI.SendChatMessage(dsender.getMcchannel(), dsender, getChatMessage.apply(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