diff --git a/src/main/java/buttondevteam/discordplugin/AsyncDiscordEvent.java b/src/main/java/buttondevteam/discordplugin/AsyncDiscordEvent.java deleted file mode 100644 index c4479f3..0000000 --- a/src/main/java/buttondevteam/discordplugin/AsyncDiscordEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package buttondevteam.discordplugin; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -@RequiredArgsConstructor -public class AsyncDiscordEvent extends Event implements Cancellable { - private final @Getter T event; - @Getter - @Setter - private boolean cancelled; - - private static final HandlerList handlers = new HandlerList(); - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index f4a1ce0..028a7f2 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -16,8 +16,8 @@ import java.util.regex.Matcher; public final class DPUtils { - public static EmbedCreateSpec embedWithHead(EmbedCreateSpec ecs, String playername, String profileUrl) { - return ecs.setAuthor(playername, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png"); + public static EmbedCreateSpec embedWithHead(EmbedCreateSpec ecs, String displayname, String playername, String profileUrl) { + return ecs.setAuthor(displayname, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png"); } /** diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 7980e37..bcf5e5e 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -73,6 +73,13 @@ public class DiscordPlugin extends ButtonPlugin { return DPUtils.roleData(getIConfig(), "modRole", "Moderator"); } + /** + * The invite link to show by /discord invite. If empty, it defaults to the first invite if the bot has access. + */ + public ConfigData InviteLink() { + return getIConfig().getData("inviteLink", ""); + } + @Override public void pluginEnable() { try { diff --git a/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java b/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java deleted file mode 100755 index 3e8094f..0000000 --- a/src/main/java/buttondevteam/discordplugin/DiscordRunnable.java +++ /dev/null @@ -1,10 +0,0 @@ -package buttondevteam.discordplugin; - -import sx.blah.discord.util.DiscordException; -import sx.blah.discord.util.MissingPermissionsException; -import sx.blah.discord.util.RateLimitException; - -@FunctionalInterface -public interface DiscordRunnable { - void run() throws DiscordException, RateLimitException, MissingPermissionsException; -} diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java index a4c829e..afa4cfb 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java @@ -1,7 +1,6 @@ package buttondevteam.discordplugin.commands; import buttondevteam.discordplugin.DiscordPlayer; -import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; @@ -28,34 +27,37 @@ public class ConnectCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender, String Minecraftname) { val message = sender.getMessage(); - if (WaitingToConnect.inverse().containsKey(message.getAuthor().getId().asString())) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getId().asString()) + " with " + Minecraftname); - WaitingToConnect.inverse().remove(message.getAuthor().getId().asString()); + val channel = message.getChannel().block(); + val author = message.getAuthor().orElse(null); + if (author == null || channel == null) return true; + if (WaitingToConnect.inverse().containsKey(author.getId().asString())) { + channel.createMessage( + "Replacing " + WaitingToConnect.inverse().get(author.getId().asString()) + " with " + Minecraftname).subscribe(); + WaitingToConnect.inverse().remove(author.getId().asString()); } @SuppressWarnings("deprecation") OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname); if (p == null) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found"); + channel.createMessage("The specified Minecraft player cannot be found").subscribe(); return true; } try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { DiscordPlayer dp = pl.getAs(DiscordPlayer.class); - if (dp != null && message.getAuthor().getId().asString().equals(dp.getDiscordID())) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); + if (dp != null && author.getId().asString().equals(dp.getDiscordID())) { + channel.createMessage("You already have this account connected.").subscribe(); return true; } } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e); + channel.createMessage("An internal error occured!\n" + e).subscribe(); } - WaitingToConnect.put(p.getName(), message.getAuthor().getId().asString()); - DiscordPlugin.sendMessageToChannel(message.getChannel(), + WaitingToConnect.put(p.getName(), author.getId().asString()); + channel.createMessage( "Alright! Now accept the connection in Minecraft from the account " + Minecraftname - + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command."); + + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.").subscribe(); if (p.isOnline()) - ((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#" - + message.getAuthor().getDiscriminator() + " do /discord accept"); + ((Player) p).sendMessage("§bTo connect with the Discord account " + author.getUsername() + "#" + + author.getDiscriminator() + " do /discord accept"); return true; } diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java index 2cf87fb..e75a163 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java @@ -11,10 +11,14 @@ import buttondevteam.lib.chat.CommandClass; public class DebugCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender, String args) { - if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get())) - sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled")); - else - sender.sendMessage("you need to be a moderator to use this command."); - return true; - } + sender.getMessage().getAuthorAsMember() + .map(m -> m.getRoleIds().stream().anyMatch(r -> r.equals(DiscordPlugin.plugin.ModRole().get().getId()))) + .subscribe(success -> { + if (success) + sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled")); + else + sender.sendMessage("you need to be a moderator to use this command."); + }); + return true; + } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java index 83242ae..40f98cb 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java @@ -7,13 +7,11 @@ import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.User; import lombok.val; -import sx.blah.discord.handle.obj.User; -import sx.blah.discord.handle.obj.Message; import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; @CommandClass(helpText = { "User information", // @@ -25,20 +23,21 @@ public class UserinfoCommand extends ICommand2DC { public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) { val message = sender.getMessage(); User target = null; + val channel = message.getChannel().block(); + assert channel != null; if (user == null || user.length() == 0) - target = message.getAuthor(); + target = message.getAuthor().orElse(null); else { - final Optional firstmention = message.getMentions().stream() - .filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelf().getId().asString())).findFirst(); - if (firstmention.isPresent()) - target = firstmention.get(); + @SuppressWarnings("OptionalGetWithoutIsPresent") final User firstmention = message.getUserMentions() + .filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelfId().get().asString())).blockFirst(); + if (firstmention != null) + target = firstmention; else if (user.contains("#")) { String[] targettag = user.split("#"); final List targets = getUsers(message, targettag[0]); if (targets.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by name): " + user); - return true; + channel.createMessage("The user cannot be found (by name): " + user).subscribe(); + return true; } for (User ptarget : targets) { if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { @@ -47,44 +46,47 @@ public class UserinfoCommand extends ICommand2DC { } } if (target == null) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by discriminator): " + user + "(Found " + targets.size() - + " users with the name.)"); - return true; + channel.createMessage("The user cannot be found (by discriminator): " + user + "(Found " + targets.size() + + " users with the name.)").subscribe(); + return true; } } else { final List targets = getUsers(message, user); if (targets.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found on Discord: " + user); - return true; + channel.createMessage("The user cannot be found on Discord: " + user).subscribe(); + return true; } if (targets.size() > 1) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping."); - return true; + channel.createMessage("Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.").subscribe(); + return true; } target = targets.get(0); } } - try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getId().asString(), DiscordPlayer.class)) { - StringBuilder uinfo = new StringBuilder("User info for ").append(target.getName()).append(":\n"); - uinfo.append(dp.getInfo(InfoTarget.Discord)); - DiscordPlugin.sendMessageToChannel(message.getChannel(), uinfo.toString()); - } catch (Exception e) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while getting the user!"); - TBMCCoreAPI.SendException("Error while getting info about " + target.getName() + "!", e); + if (target == null) { + sender.sendMessage("An error occurred."); + return true; } - return true; + try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getId().asString(), DiscordPlayer.class)) { + StringBuilder uinfo = new StringBuilder("User info for ").append(target.getUsername()).append(":\n"); + uinfo.append(dp.getInfo(InfoTarget.Discord)); + channel.createMessage(uinfo.toString()).subscribe(); + } catch (Exception e) { + channel.createMessage("An error occured while getting the user!").subscribe(); + TBMCCoreAPI.SendException("Error while getting info about " + target.getUsername() + "!", e); + } + return true; } private List getUsers(Message message, String args) { final List targets; - if (message.getChannel().isPrivate()) - targets = DiscordPlugin.dc.getUsers().stream().filter(u -> u.getName().equalsIgnoreCase(args)) - .collect(Collectors.toList()); + val guild = message.getGuild().block(); + if (guild == null) //Private channel + targets = DiscordPlugin.dc.getUsers().filter(u -> u.getUsername().equalsIgnoreCase(args)) + .collectList().block(); else - targets = message.getGuild().getUsersByName(args, true); + targets = guild.getMembers().filter(m -> m.getUsername().equalsIgnoreCase(args)) + .map(m -> (User) m).collectList().block(); return targets; } diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java b/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java index 95c3cdb..12606af 100755 --- a/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java +++ b/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java @@ -3,10 +3,11 @@ package buttondevteam.discordplugin.exceptions; import buttondevteam.core.ComponentManager; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCDebugMessageEvent; +import discord4j.core.object.entity.MessageChannel; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -public class DebugMessageListener implements Listener{ +public class DebugMessageListener implements Listener { @EventHandler public void onDebugMessage(TBMCDebugMessageEvent e) { SendMessage(e.getDebugMessage()); @@ -17,13 +18,15 @@ public class DebugMessageListener implements Listener{ if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(ExceptionListenerModule.class)) return; try { + MessageChannel mc = ExceptionListenerModule.getChannel(); + if (mc == null) return; StringBuilder sb = new StringBuilder(); sb.append("```").append("\n"); if (message.length() > 2000) message = message.substring(0, 2000); sb.append(message).append("\n"); sb.append("```"); - DiscordPlugin.sendMessageToChannel(ExceptionListenerModule.getChannel(), sb.toString()); + mc.createMessage(sb.toString()).subscribe(); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 2bb9399..f72e066 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -19,7 +19,7 @@ public class CommandListener { * @return Whether it ran the command */ public static boolean runCommand(Message message, boolean mentionedonly) { - if (message.getContent().isEmpty()) + if (!message.getContent().isPresent()) return false; //Pin messages and such, let the mcchat listener deal with it final MessageChannel channel = message.getChannel().block(); @SuppressWarnings("OptionalGetWithoutIsPresent") val content = message.getContent().get(); diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java index df2bff0..63b2fb5 100755 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.mcchat; +import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.Command2DCSender; @@ -7,6 +8,7 @@ import buttondevteam.discordplugin.commands.ICommand2DC; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; +import discord4j.core.object.entity.PrivateChannel; import lombok.val; @CommandClass(helpText = { @@ -20,18 +22,20 @@ public class MCChatCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender) { val message = sender.getMessage(); - if (!message.getChannel().isPrivate()) { - DPUtils.reply(message, null, "this command can only be issued in a direct message with the bot."); + val channel = message.getChannel().block(); + @SuppressWarnings("OptionalGetWithoutIsPresent") val author = message.getAuthor().get(); + if (!(channel instanceof PrivateChannel)) { + DPUtils.reply(message, null, "this command can only be issued in a direct message with the bot.").subscribe(); return true; } - try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class)) { + try (final DiscordPlayer user = DiscordPlayer.getUser(author.getId().asString(), DiscordPlayer.class)) { boolean mcchat = !user.isMinecraftChatEnabled(); - MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user); + MCChatPrivate.privateMCChat(channel, mcchat, author, user); DPUtils.reply(message, null, "Minecraft chat " + (mcchat // ? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." // - : "disabled.")); + : "disabled.")).subscribe(); } catch (Exception e) { - TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e); + TBMCCoreAPI.SendException("Error while setting mcchat for user " + author.getUsername() + "#" + author.getDiscriminator(), e); } return true; } // TODO: Pin channel switching to indicate the current channel diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java index 550e9df..d89740c 100755 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java @@ -15,10 +15,8 @@ import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.TBMCPlayer; import com.vdurmont.emoji.EmojiParser; import discord4j.core.event.domain.message.MessageCreateEvent; -import discord4j.core.object.entity.MessageChannel; -import discord4j.core.object.entity.PrivateChannel; -import discord4j.core.object.entity.TextChannel; -import discord4j.core.object.entity.User; +import discord4j.core.object.Embed; +import discord4j.core.object.entity.*; import discord4j.core.spec.EmbedCreateSpec; import lombok.val; import org.bukkit.Bukkit; @@ -34,6 +32,7 @@ import java.util.Arrays; import java.util.Optional; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -75,46 +74,39 @@ public class MCChatListener implements Listener { final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " // + ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") // - + (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player // - ? ((Player) e.getSender()).getDisplayName() // - : e.getSender().getName())); + + (DPUtils.sanitizeStringNoEscape(ThorpeUtils.getDisplayName(e.getSender()))); val color = e.getChannel().Color().get(); - final EmbedCreateSpec embed = new EmbedBuilder().withAuthorName(authorPlayer) - .withDescription(e.getMessage()).withColor(new Color(color.getRed(), + final Consumer embed = ecs -> { + ecs.setDescription(e.getMessage()).setColor(new Color(color.getRed(), color.getGreen(), 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().getId().asString()); // TODO: Constant/method to get URLs like this - // embed.withFooterText(e.getChannel().DisplayName); - embed.withTimestamp(time); + if (e.getSender() instanceof Player) + DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), + "https://tbmcplugins.github.io/profile.html?type=minecraft&id=" + + ((Player) e.getSender()).getUniqueId()); + else if (e.getSender() instanceof DiscordSenderBase) + ecs.setAuthor(authorPlayer, "https://tbmcplugins.github.io/profile.html?type=discord&id=" // TODO: Constant/method to get URLs like this + + ((DiscordSenderBase) e.getSender()).getUser().getId().asString(), + ((DiscordSenderBase) e.getSender()).getUser().getAvatarUrl()); + else + DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), null); + ecs.setTimestamp(time); + }; final long nanoTime = System.nanoTime(); InterruptibleConsumer doit = lastmsgdata -> { - final EmbedObject embedObject = embed.build(); - if (lastmsgdata.message == null || lastmsgdata.message.isDeleted() - || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName()) + if (lastmsgdata.message == null + || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().map(Embed.Author::getName).orElse(null)) || 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.message = lastmsgdata.channel.createEmbed(embed).block(); 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 - lastmsgdata.message.edit(mes -> mes.setEmbed(ecs -> embedObject)).block(); - } catch (MissingPermissionsException | DiscordException e1) { - TBMCCoreAPI.SendException("An error occurred while editing chat message!", e1); - } + lastmsgdata.content = e.getMessage(); + } else { + lastmsgdata.content = lastmsgdata.content + "\n" + + e.getMessage(); // The message object doesn't get updated + lastmsgdata.message.edit(mes -> mes.setEmbed(embed.andThen(ecs -> + ecs.setDescription(lastmsgdata.content)))).block(); + } }; // Checks if the given channel is different than where the message was sent from // Or if it was from MC @@ -124,12 +116,12 @@ public class MCChatListener implements Listener { if (e.getChannel().isGlobal() && (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get()))) doit.accept(MCChatUtils.lastmsgdata == null - ? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData((TextChannel) module.chatChannel().get(), null) + ? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannel().get(), null) : MCChatUtils.lastmsgdata); for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) { if ((e.isFromCommand() || isdifferentchannel.test(data.channel)) - && e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user))) + && e.shouldSendTo(MCChatUtils.getSender(data.channel.getId(), data.user))) doit.accept(data); } @@ -143,7 +135,7 @@ public class MCChatListener implements Listener { 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."); + lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe(); } } } @@ -271,13 +263,16 @@ public class MCChatListener implements Listener { final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannelId(), sender); val user = dsender.getChromaUser(); - for (User u : event.getMessage().getUserMentions()) { //TODO: Role mentions - dmessage = dmessage.replace(u.me(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 (User u : event.getMessage().getUserMentions().toIterable()) { //TODO: Role mentions + dmessage = dmessage.replace(u.getMention(), "@" + u.getUsername()); // TODO: IG Formatting + val m = u.asMember(DiscordPlugin.mainServer.getId()).block(); + if (m != null) { + final String nick = m.getDisplayName(); + dmessage = dmessage.replace(m.getNicknameMention(), "@" + nick); + } } - for (MessageChannel ch : event.getMessage().getChannelMentions()) { - dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting + for (GuildChannel ch : event.getGuild().flux().flatMap(Guild::getChannels).toIterable()) { + dmessage = dmessage.replace(ch.getMention(), "#" + ch.getName()); // TODO: IG Formatting } dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?) @@ -285,18 +280,18 @@ public class MCChatListener implements Listener { Function getChatMessage = msg -> // msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() - .getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n")) + .getAttachments().stream().map(Attachment::getUrl).collect(Collectors.joining("\n")) : ""); - MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel()); + MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getMessage().getChannelId()); boolean react = false; + val sendChannel = event.getMessage().getChannel().block(); + boolean isPrivate = sendChannel instanceof PrivateChannel; if (dmessage.startsWith("/")) { // Ingame command - DPUtils.perform(() -> { - if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) - event.getMessage().delete(); - }); + if (!isPrivate) + event.getMessage().delete().subscribe(); final String cmd = dmessage.substring(1); final String cmdlowercased = cmd.toLowerCase(); if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream() @@ -338,7 +333,7 @@ public class MCChatListener implements Listener { }); else { Channel chc = ch.get(); - if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate()) + if (!chc.isGlobal() && !isPrivate) dsender.sendMessage( "You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels."); else { @@ -369,7 +364,7 @@ public class MCChatListener implements Listener { } } else {// Not a command if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 - && !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) { + && !isPrivate && event.getMessage().getType() == Message.Type.CHANNEL_PINNED_MESSAGE) { val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp) : dsender.getChromaUser().channel().get().getRTR(dsender); TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr, @@ -386,16 +381,15 @@ public class MCChatListener implements Listener { } if (react) { try { - val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getId().asLong()); + val lmfd = MCChatUtils.lastmsgfromd.get(event.getMessage().getChannelId().asLong()); if (lmfd != null) { - DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getSelf(), - DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time + lmfd.removeSelfReaction(DiscordPlugin.DELIVERED_REACTION).subscribe(); // 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); } - MCChatUtils.lastmsgfromd.put(event.getChannel().getId().asLong(), event.getMessage()); - DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); + MCChatUtils.lastmsgfromd.put(event.getMessage().getChannelId().asLong(), event.getMessage()); + event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION).subscribe(); } } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java index e706a68..452168a 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java @@ -1,18 +1,19 @@ package buttondevteam.discordplugin.mcchat; +import buttondevteam.core.ComponentManager; import buttondevteam.discordplugin.DiscordConnectedPlayer; import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.player.TBMCPlayer; import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.PrivateChannel; +import discord4j.core.object.entity.TextChannel; +import discord4j.core.object.entity.User; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -import sx.blah.discord.handle.obj.IPrivateChannel; -import sx.blah.discord.handle.obj.User; -import sx.blah.discord.handle.obj.MessageChannel; import java.util.ArrayList; @@ -28,13 +29,14 @@ public class MCChatPrivate { 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()); + val mcm = ComponentManager.getIfEnabled(MinecraftChatModule.class); if (start) { - val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); + val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName(), mcm); MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender); if (p == null)// Player is offline - If the player is online, that takes precedence callEventSync(new PlayerJoinEvent(sender, "")); } else { - val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel, user); + val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId(), user); if (p == null)// Player is offline - If the player is online, that takes precedence callEventSync(new PlayerQuitEvent(sender, "")); } @@ -42,8 +44,8 @@ public class MCChatPrivate { if (!start) MCChatUtils.lastmsgfromd.remove(channel.getId().asLong()); return start // - ? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs - : lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()); + ? lastmsgPerUser.add(new MCChatUtils.LastMsgData((TextChannel) channel, user)) // Doesn't support group DMs + : lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()); } public static boolean isMinecraftChatEnabled(DiscordPlayer dp) { @@ -52,7 +54,8 @@ public class MCChatPrivate { public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this return lastmsgPerUser.stream() - .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getId().asString().equals(did)); + .anyMatch(lmd -> ((PrivateChannel) lmd.channel) + .getRecipientIds().stream().anyMatch(u -> u.asString().equals(did))); } public static void logoutAll() { diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java index 6ee9292..6cb58ee 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java @@ -3,6 +3,7 @@ package buttondevteam.discordplugin.mcchat; import buttondevteam.core.ComponentManager; import buttondevteam.discordplugin.*; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; +import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCSystemChatEvent; import discord4j.core.object.entity.*; import discord4j.core.object.util.Snowflake; @@ -60,7 +61,12 @@ public class MCChatUtils { } private static void updatePL(LastMsgData lmd) { - String topic = lmd.channel.getTopic().orElse(""); + if (!(lmd.channel instanceof TextChannel)) { + TBMCCoreAPI.SendException("Failed to update player list for channel " + lmd.channel.getId(), + new Exception("The channel isn't a (guild) text channel.")); + return; + } + String topic = ((TextChannel) lmd.channel).getTopic().orElse(""); if (topic.length() == 0) topic = ".\n----\nMinecraft chat\n----\n."; String[] s = topic.split("\\n----\\n"); @@ -70,7 +76,7 @@ public class MCChatUtils { + " online"; s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream() .map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", ")); - lmd.channel.edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait + ((TextChannel) lmd.channel).edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait } public static T addSender(HashMap> senders, @@ -204,7 +210,7 @@ public class MCChatUtils { public static void resetLastMessage(Channel channel) { if (notEnabled()) return; if (channel.getId().asLong() == module.chatChannel().get().getId().asLong()) { - (lastmsgdata == null ? lastmsgdata = new LastMsgData((TextChannel) module.chatChannel().get(), null) + (lastmsgdata == null ? lastmsgdata = new LastMsgData(module.chatChannel().get(), null) : lastmsgdata).message = null; return; } // Don't set the whole object to null, the player and channel information should be preserved @@ -285,8 +291,8 @@ public class MCChatUtils { public Message message; public long time; public String content; - public final TextChannel channel; - public Channel mcchannel; + public final MessageChannel channel; + public buttondevteam.core.component.channel.Channel mcchannel; public final User user; } } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 76383b7..cc7e9dc 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -78,7 +78,7 @@ public class MinecraftChatModule extends Component { TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled getPlugin().getManager().registerCommand(new MCChatCommand()); - getPlugin().getManager().registerCommand(new ChannelconCommand()); + getPlugin().getManager().registerCommand(new ChannelconCommand(this)); val chcons = getConfig().getConfig().getConfigurationSection("chcons"); if (chcons == null) //Fallback to old place diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommand.java b/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommand.java index 7fa76d0..6ff0ccc 100644 --- a/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommand.java @@ -8,16 +8,15 @@ import buttondevteam.discordplugin.commands.ConnectCommand; import buttondevteam.discordplugin.commands.VersionCommand; import buttondevteam.discordplugin.mcchat.MCChatUtils; import buttondevteam.lib.chat.Command2; -import buttondevteam.lib.chat.Command2MCSender; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayerBase; -import lombok.val; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import reactor.core.publisher.Mono; import java.lang.reflect.Method; @@ -98,11 +97,16 @@ public class DiscordMCCommand extends ICommand2MC { "Shows an invite link to the server" }) public void invite(CommandSender sender) { - val inv=DiscordPlugin.mainServer.getExtendedInvites().stream().findAny(); //TODO: Needs manage server perms - if (!inv.isPresent()) - sender.sendMessage("§cNo invites found for the server."); - else - sender.sendMessage("§bInvite link: https://discord.gg/"+inv.get().getCode()); + String invi = DiscordPlugin.plugin.InviteLink().get(); + if (invi.length() > 0) { + sender.sendMessage("§bInvite link: " + invi); + return; + } + DiscordPlugin.mainServer.getInvites().limitRequest(1) + .switchIfEmpty(Mono.fromRunnable(() -> sender.sendMessage("§cNo invites found for the server."))) + .subscribe(inv -> {//TODO: Needs manage server perms + sender.sendMessage("§bInvite link: https://discord.gg/" + inv.getCode()); + }); } @Override diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommandBase.java b/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommandBase.java deleted file mode 100755 index 5edbafe..0000000 --- a/src/main/java/buttondevteam/discordplugin/mccommands/DiscordMCCommandBase.java +++ /dev/null @@ -1,9 +0,0 @@ -package buttondevteam.discordplugin.mccommands; - -import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.PlayerCommandBase; - -@CommandClass(modOnly = false, path = "discord") -public abstract class DiscordMCCommandBase extends PlayerCommandBase { - -}