From 038cb98f1a2cf91ab10e5385708b5c78a3f7944b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 24 Apr 2019 13:29:52 +0200 Subject: [PATCH] Refactoring & made mcchat teleport config --- .../discordplugin/DiscordConnectedPlayer.java | 9 +- .../discordplugin/DiscordPlayer.java | 2 +- .../discordplugin/DiscordPlayerSender.java | 6 +- .../discordplugin/DiscordSender.java | 6 +- .../discordplugin/DiscordSenderBase.java | 15 +- .../commands/ConnectCommand.java | 10 +- .../commands/UserinfoCommand.java | 20 +- .../discordplugin/fun/FunModule.java | 2 +- .../listeners/CommandListener.java | 30 +- .../discordplugin/listeners/MCListener.java | 6 +- .../mcchat/ChannelconCommand.java | 4 +- .../discordplugin/mcchat/MCChatCommand.java | 2 +- .../discordplugin/mcchat/MCChatCustom.java | 22 +- .../discordplugin/mcchat/MCChatListener.java | 679 +++++++++--------- .../discordplugin/mcchat/MCChatPrivate.java | 10 +- .../discordplugin/mcchat/MCChatUtils.java | 14 +- .../discordplugin/mcchat/MCListener.java | 6 +- .../mcchat/MinecraftChatModule.java | 31 +- .../playerfaker/DiscordEntity.java | 28 +- .../playerfaker/DiscordFakePlayer.java | 13 +- .../playerfaker/DiscordHumanEntity.java | 9 +- .../playerfaker/DiscordLivingEntity.java | 9 +- 22 files changed, 488 insertions(+), 445 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java index ff36dcb..de96b18 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java @@ -1,10 +1,11 @@ package buttondevteam.discordplugin; +import buttondevteam.discordplugin.mcchat.MinecraftChatModule; import buttondevteam.discordplugin.playerfaker.DiscordFakePlayer; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import lombok.Getter; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.util.UUID; @@ -12,8 +13,8 @@ public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlay private static int nextEntityId = 10000; private @Getter VanillaCommandListener vanillaCmdListener; - public DiscordConnectedPlayer(IUser user, MessageChannel channel, UUID uuid, String mcname) { - super(user, channel, nextEntityId++, uuid, mcname); + public DiscordConnectedPlayer(User user, MessageChannel channel, UUID uuid, String mcname, MinecraftChatModule module) { + super(user, channel, nextEntityId++, uuid, mcname ,module); vanillaCmdListener = new VanillaCommandListener<>(this); } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java b/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java index bbb9a75..d748433 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlayer.java @@ -20,7 +20,7 @@ public class DiscordPlayer extends ChromaGamerBase { /** * Returns true if player has the private Minecraft chat enabled. For setting the value, see - * {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.MessageChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)} + * {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.MessageChannel, boolean, sx.blah.discord.handle.obj.User, DiscordPlayer)} */ public boolean isMinecraftChatEnabled() { return MCChatPrivate.isMinecraftChatEnabled(this); diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java b/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java index 1f30113..807abd4 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlayerSender.java @@ -1,6 +1,8 @@ package buttondevteam.discordplugin; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import lombok.Getter; import org.bukkit.*; import org.bukkit.advancement.Advancement; @@ -26,8 +28,6 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.util.Vector; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.net.InetSocketAddress; import java.util.*; @@ -38,7 +38,7 @@ public class DiscordPlayerSender extends DiscordSenderBase implements IMCPlayer< protected Player player; private @Getter VanillaCommandListener vanillaCmdListener; - public DiscordPlayerSender(IUser user, MessageChannel channel, Player player) { + public DiscordPlayerSender(User user, MessageChannel channel, Player player) { super(user, channel); this.player = player; vanillaCmdListener = new VanillaCommandListener(this); diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSender.java b/src/main/java/buttondevteam/discordplugin/DiscordSender.java index de1eed9..7b87b5d 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordSender.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordSender.java @@ -8,7 +8,7 @@ import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.User; import sx.blah.discord.handle.obj.MessageChannel; import java.util.Set; @@ -18,12 +18,12 @@ public class DiscordSender extends DiscordSenderBase implements CommandSender { private String name; - public DiscordSender(IUser user, MessageChannel channel) { + public DiscordSender(User user, MessageChannel channel) { super(user, channel); name = user == null ? "Discord user" : user.getDisplayName(DiscordPlugin.mainServer); } - public DiscordSender(IUser user, MessageChannel channel, String name) { + public DiscordSender(User user, MessageChannel channel, String name) { super(user, channel); this.name = name; } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java index f16e92b..145a8c0 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java @@ -1,20 +1,20 @@ package buttondevteam.discordplugin; import buttondevteam.lib.TBMCCoreAPI; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitTask; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; public abstract class DiscordSenderBase implements CommandSender { /** * May be null. */ - protected IUser user; + protected User user; protected MessageChannel channel; - protected DiscordSenderBase(IUser user, MessageChannel channel) { + protected DiscordSenderBase(User user, MessageChannel channel) { this.user = user; this.channel = channel; } @@ -27,7 +27,7 @@ public abstract class DiscordSenderBase implements CommandSender { * * @return The user or null. */ - public IUser getUser() { + public User getUser() { return user; } @@ -43,7 +43,7 @@ public abstract class DiscordSenderBase implements CommandSender { * @return A Chroma user of Discord or a Discord user of Chroma */ public DiscordPlayer getChromaUser() { - if (chromaUser == null) chromaUser = DiscordPlayer.getUser(user.getStringID(), DiscordPlayer.class); + if (chromaUser == null) chromaUser = DiscordPlayer.getUser(user.getId().asString(), DiscordPlayer.class); return chromaUser; } @@ -58,8 +58,7 @@ public abstract class DiscordSenderBase implements CommandSender { msgtosend += "\n" + sendmsg; if (sendtask == null) sendtask = Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> { - DiscordPlugin.sendMessageToChannel(channel, - (!broadcast && user != null ? user.mention() + "\n" : "") + msgtosend.trim()); + channel.createMessage((!broadcast && user != null ? user.getMention() + "\n" : "") + msgtosend.trim()); sendtask = null; msgtosend = ""; }, 4); // Waits a 0.2 second to gather all/most of the different messages diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java index 4e37e35..a4c829e 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java @@ -28,10 +28,10 @@ public class ConnectCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender, String Minecraftname) { val message = sender.getMessage(); - if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) { + if (WaitingToConnect.inverse().containsKey(message.getAuthor().getId().asString())) { DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + Minecraftname); - WaitingToConnect.inverse().remove(message.getAuthor().getStringID()); + "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getId().asString()) + " with " + Minecraftname); + WaitingToConnect.inverse().remove(message.getAuthor().getId().asString()); } @SuppressWarnings("deprecation") OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname); @@ -41,7 +41,7 @@ public class ConnectCommand extends ICommand2DC { } try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { DiscordPlayer dp = pl.getAs(DiscordPlayer.class); - if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) { + if (dp != null && message.getAuthor().getId().asString().equals(dp.getDiscordID())) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); return true; } @@ -49,7 +49,7 @@ public class ConnectCommand extends ICommand2DC { TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e); } - WaitingToConnect.put(p.getName(), message.getAuthor().getStringID()); + WaitingToConnect.put(p.getName(), message.getAuthor().getId().asString()); DiscordPlugin.sendMessageToChannel(message.getChannel(), "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."); diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java index 0de8121..83242ae 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java @@ -8,7 +8,7 @@ import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; import lombok.val; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.User; import sx.blah.discord.handle.obj.Message; import java.util.List; @@ -24,23 +24,23 @@ public class UserinfoCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) { val message = sender.getMessage(); - IUser target = null; + User target = null; if (user == null || user.length() == 0) target = message.getAuthor(); else { - final Optional firstmention = message.getMentions().stream() - .filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst(); + final Optional firstmention = message.getMentions().stream() + .filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelf().getId().asString())).findFirst(); if (firstmention.isPresent()) target = firstmention.get(); else if (user.contains("#")) { String[] targettag = user.split("#"); - final List targets = getUsers(message, targettag[0]); + 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; } - for (IUser ptarget : targets) { + for (User ptarget : targets) { if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { target = ptarget; break; @@ -53,7 +53,7 @@ public class UserinfoCommand extends ICommand2DC { return true; } } else { - final List targets = getUsers(message, user); + final List targets = getUsers(message, user); if (targets.size() == 0) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "The user cannot be found on Discord: " + user); @@ -67,7 +67,7 @@ public class UserinfoCommand extends ICommand2DC { target = targets.get(0); } } - try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getStringID(), DiscordPlayer.class)) { + 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()); @@ -78,8 +78,8 @@ public class UserinfoCommand extends ICommand2DC { return true; } - private List getUsers(Message message, String args) { - final List targets; + 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()); diff --git a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java index c3c21ad..ee72a6a 100644 --- a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java +++ b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java @@ -135,7 +135,7 @@ public class FunModule extends Component implements Listener { if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE) && !event.getNewPresence().getStatus().equals(StatusType.OFFLINE) && event.getUser().getRolesForGuild(channel.getGuild()).stream() - .anyMatch(r -> r.getLongID() == devrole.getLongID()) + .anyMatch(r -> r.getId().asLong() == devrole.getId().asLong()) && channel.getGuild().getUsersByRole(devrole).stream() .noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE)) && lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime()) diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 69c27cf..a12a665 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -3,6 +3,10 @@ package buttondevteam.discordplugin.listeners; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.Command2DCSender; import buttondevteam.lib.TBMCCoreAPI; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.PrivateChannel; +import lombok.val; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.Message; import sx.blah.discord.handle.obj.MessageChannel; @@ -16,22 +20,28 @@ public class CommandListener { * @return Whether it ran the command */ public static boolean runCommand(Message message, boolean mentionedonly) { - if (message.getContent().length() == 0) + if (message.getContent().isEmpty()) return false; //Pin messages and such, let the mcchat listener deal with it - final MessageChannel channel = message.getChannel(); + final MessageChannel channel = message.getChannel().block(); + @SuppressWarnings("OptionalGetWithoutIsPresent") val content = message.getContent().get(); + if (channel == null) return false; if (!mentionedonly) { //mentionedonly conditions are in CommonListeners - if (!message.getChannel().isPrivate() - && !(message.getContent().charAt(0) == DiscordPlugin.getPrefix() - && channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) // + if (!(channel instanceof PrivateChannel) + && !(content.charAt(0) == DiscordPlugin.getPrefix() + && channel.getId().asString().equals(DiscordPlugin.plugin.CommandChannel().get().getId().asString()))) // return false; - message.getChannel().setTypingStatus(true); // Fun + channel.type().subscribe(); // Fun } - final StringBuilder cmdwithargs = new StringBuilder(message.getContent()); - final String mention = DiscordPlugin.dc.getOurUser().mention(false); - final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true); + final StringBuilder cmdwithargs = new StringBuilder(content); + val self=DiscordPlugin.dc.getSelf().block(); + if(self==null) return false; + val member=self.asMember(DiscordPlugin.mainServer.getId()).block(); + if(member==null) return false; + final String mention = self.getMention(); + final String mentionNick = member.getNicknameMention(); boolean gotmention = checkanddeletemention(cmdwithargs, mention, message); gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention; - for (String mentionRole : (Iterable) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(IRole::mention)::iterator) + for (String mentionRole : (Iterable) message.getRoleMentions().filter(r -> member.getRoles().filter(r)).map(IRole::mention)::iterator) //TODO: Remove all that matches 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/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java index c23b8fa..e41713c 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -8,13 +8,13 @@ import buttondevteam.lib.player.TBMCPlayerJoinEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.ServerCommandEvent; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.User; public class MCListener implements Listener { @EventHandler public void onPlayerJoin(TBMCPlayerJoinEvent e) { if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { - @SuppressWarnings("ConstantConditions") IUser user = DiscordPlugin.dc + @SuppressWarnings("ConstantConditions") User user = DiscordPlugin.dc .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); e.getPlayer().sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() + " do /discord accept"); @@ -29,7 +29,7 @@ public class MCListener implements Listener { DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class); if (dp == null || dp.getDiscordID() == null || dp.getDiscordID().equals("")) return; - IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); + User 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()) diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java index dba50e5..fad76fc 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java @@ -95,7 +95,7 @@ public class ChannelconCommand extends ICommand2DC { message.reply("MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /."); return true; } - val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class); + val dp = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class); val chp = dp.getAs(TBMCPlayer.class); if (chp == null) { message.reply("you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect "); @@ -140,7 +140,7 @@ public class ChannelconCommand extends ICommand2DC { "You need to have access to the MC channel and have manage permissions on the Discord channel.", // "You also need to have your Minecraft account connected. In " + DPUtils.botmention() + " use " + DiscordPlugin.getPrefix() + "connect .", // "Call this command from the channel you want to use.", // - "Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon ", // + "Usage: @" + DiscordPlugin.dc.getSelf().getName() + " channelcon ", // "Use the ID (command) of the channel, for example `g` for the global chat.", // "To remove a connection use @ChromaBot channelcon remove in the channel.", // "Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in " + DPUtils.botmention() + ".", // diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java index 23af46f..c579818 100755 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java @@ -24,7 +24,7 @@ public class MCChatCommand extends ICommand2DC { message.reply("this command can only be issued in a direct message with the bot."); return true; } - try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) { + try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class)) { boolean mcchat = !user.isMinecraftChatEnabled(); MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user); message.reply("Minecraft chat " + (mcchat // diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java index 8c4b6c2..7302ad6 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java @@ -4,10 +4,12 @@ import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.ChatRoom; import buttondevteam.discordplugin.DiscordConnectedPlayer; import buttondevteam.lib.TBMCSystemChatEvent; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.TextChannel; +import discord4j.core.object.entity.User; +import discord4j.core.object.util.Snowflake; import lombok.NonNull; import lombok.val; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import javax.annotation.Nullable; import java.util.ArrayList; @@ -21,7 +23,7 @@ public class MCChatCustom { */ static ArrayList lastmsgCustom = new ArrayList<>(); - public static void addCustomChat(MessageChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles, Set brtoggles) { + public static void addCustomChat(MessageChannel channel, String groupid, Channel mcchannel, User user, DiscordConnectedPlayer dcp, int toggles, Set brtoggles) { if (mcchannel instanceof ChatRoom) { ((ChatRoom) mcchannel).joinRoom(dcp); if (groupid == null) groupid = mcchannel.getGroupID(dcp); @@ -30,19 +32,19 @@ public class MCChatCustom { lastmsgCustom.add(lmd); } - public static boolean hasCustomChat(MessageChannel channel) { - return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID()); + public static boolean hasCustomChat(Snowflake channel) { + return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getId().asLong() == channel.asLong()); } @Nullable public static CustomLMD getCustomChat(MessageChannel channel) { - return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null); + return lastmsgCustom.stream().filter(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()).findAny().orElse(null); } public static boolean removeCustomChat(MessageChannel channel) { - MCChatUtils.lastmsgfromd.remove(channel.getLongID()); + MCChatUtils.lastmsgfromd.remove(channel.getId().asLong()); return lastmsgCustom.removeIf(lmd -> { - if (lmd.channel.getLongID() != channel.getLongID()) + if (lmd.channel.getId().asLong() != channel.getId().asLong()) return false; if (lmd.mcchannel instanceof ChatRoom) ((ChatRoom) lmd.mcchannel).leaveRoom(lmd.dcp); @@ -61,9 +63,9 @@ public class MCChatCustom { public int toggles; public Set brtoggles; - private CustomLMD(@NonNull MessageChannel channel, @NonNull IUser user, + private CustomLMD(@NonNull MessageChannel channel, @NonNull User user, @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, Set brtoggles) { - super(channel, user); + super((TextChannel) channel, user); groupID = groupid; this.mcchannel = mcchannel; this.dcp = dcp; diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java index ed52108..ee2a6fb 100755 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java @@ -14,6 +14,11 @@ import buttondevteam.lib.chat.ChatMessage; 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.spec.EmbedCreateSpec; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -22,7 +27,7 @@ import org.bukkit.event.Listener; import org.bukkit.scheduler.BukkitTask; import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.User; import sx.blah.discord.handle.obj.Message; import sx.blah.discord.handle.obj.MessageChannel; import sx.blah.discord.util.DiscordException; @@ -41,10 +46,10 @@ import java.util.function.Predicate; import java.util.stream.Collectors; public class MCChatListener implements Listener { - private BukkitTask sendtask; - private LinkedBlockingQueue> sendevents = new LinkedBlockingQueue<>(); - private Runnable sendrunnable; - private static Thread sendthread; + private BukkitTask sendtask; + private LinkedBlockingQueue> sendevents = new LinkedBlockingQueue<>(); + private Runnable sendrunnable; + private static Thread sendthread; private final MinecraftChatModule module; public MCChatListener(MinecraftChatModule minecraftChatModule) { @@ -52,359 +57,361 @@ public class MCChatListener implements Listener { } @EventHandler // Minecraft - public void onMCChat(TBMCChatEvent ev) { - if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown - return; - sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now())); - if (sendtask != null) - return; - sendrunnable = () -> { - sendthread = Thread.currentThread(); - processMCToDiscord(); - if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down - sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); - }; - sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); - } + public void onMCChat(TBMCChatEvent ev) { + if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown + return; + sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now())); + if (sendtask != null) + return; + sendrunnable = () -> { + sendthread = Thread.currentThread(); + processMCToDiscord(); + if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); + }; + sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable); + } - private void processMCToDiscord() { - try { - TBMCChatEvent e; - Instant time; - val se = sendevents.take(); // Wait until an element is available - e = se.getKey(); - time = se.getValue(); + private void processMCToDiscord() { + try { + TBMCChatEvent e; + Instant time; + val se = sendevents.take(); // Wait until an element is available + e = se.getKey(); + time = se.getValue(); - 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())); - val color = e.getChannel().Color().get(); - final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer) - .withDescription(e.getMessage()).withColor(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().getStringID()); // TODO: Constant/method to get URLs like this - // embed.withFooterText(e.getChannel().DisplayName); - embed.withTimestamp(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()) - || 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 MCChatUtils.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 - // Or if it was from MC + 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())); + val color = e.getChannel().Color().get(); + final EmbedCreateSpec embed = new EmbedBuilder().withAuthorName(authorPlayer) + .withDescription(e.getMessage()).withColor(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); + 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()) + || 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 + lastmsgdata.message.edit(mes -> mes.setEmbed(ecs -> embedObject)).block(); + } 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 + // Or if it was from MC Predicate isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase) - || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID(); + || ((DiscordSenderBase) e.getSender()).getChannel().getId().asLong() != ch.getId().asLong(); - if (e.getChannel().isGlobal() - && (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get()))) - doit.accept(MCChatUtils.lastmsgdata == null - ? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannel().get(), null) - : MCChatUtils.lastmsgdata); + 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); - for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) { - if ((e.isFromCommand() || isdifferentchannel.test(data.channel)) - && e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user))) - doit.accept(data); - } + for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) { + if ((e.isFromCommand() || isdifferentchannel.test(data.channel)) + && e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user))) + doit.accept(data); + } - val iterator = MCChatCustom.lastmsgCustom.iterator(); - while (iterator.hasNext()) { - val lmd = iterator.next(); - if ((e.isFromCommand() || 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 - && e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58 - if (e.shouldSendTo(lmd.dcp)) //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."); - } - } - } - } catch (InterruptedException ex) { //Stop if interrupted anywhere - sendtask.cancel(); - sendtask = null; - } catch (Exception ex) { - TBMCCoreAPI.SendException("Error while sending message to Discord!", ex); - } - } + val iterator = MCChatCustom.lastmsgCustom.iterator(); + while (iterator.hasNext()) { + val lmd = iterator.next(); + if ((e.isFromCommand() || 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 + && e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58 + if (e.shouldSendTo(lmd.dcp)) //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."); + } + } + } + } catch (InterruptedException ex) { //Stop if interrupted anywhere + sendtask.cancel(); + sendtask = null; + } catch (Exception ex) { + TBMCCoreAPI.SendException("Error while sending message to Discord!", ex); + } + } - @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; + val user = DiscordPlugin.dc.getUsers().filter(u -> u.getUsername().equals(event.getMessage().substring(startF + 1, mid))) + .filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).blockFirst(); + if (user != null) //TODO: Nicknames + event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getUsername() + + (event.getMessage().length() > end ? event.getMessage().substring(end) : "")); // TODO: Add formatting + start = end; // Skip any @s inside the mention + } + } - // ......................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 - /** - * Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode. - * - * @param wait Wait 5 seconds for the threads to stop - */ - public static void stop(boolean wait) { - if (sendthread != null) sendthread.interrupt(); - if (recthread != null) recthread.interrupt(); - try { - if (sendthread != null) { - sendthread.interrupt(); - if (wait) - sendthread.join(5000); - } - if (recthread != null) { - recthread.interrupt(); - if (wait) - recthread.join(5000); - } - MCChatUtils.lastmsgdata = null; - MCChatPrivate.lastmsgPerUser.clear(); - MCChatCustom.lastmsgCustom.clear(); - MCChatUtils.lastmsgfromd.clear(); - MCChatUtils.ConnectedSenders.clear(); - MCChatUtils.UnconnectedSenders.clear(); - recthread = sendthread = null; - } catch (InterruptedException e) { - e.printStackTrace(); //This thread shouldn't be interrupted - } - } + /** + * Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode. + * + * @param wait Wait 5 seconds for the threads to stop + */ + public static void stop(boolean wait) { + if (sendthread != null) sendthread.interrupt(); + if (recthread != null) recthread.interrupt(); + try { + if (sendthread != null) { + sendthread.interrupt(); + if (wait) + sendthread.join(5000); + } + if (recthread != null) { + recthread.interrupt(); + if (wait) + recthread.join(5000); + } + MCChatUtils.lastmsgdata = null; + MCChatPrivate.lastmsgPerUser.clear(); + MCChatCustom.lastmsgCustom.clear(); + MCChatUtils.lastmsgfromd.clear(); + MCChatUtils.ConnectedSenders.clear(); + MCChatUtils.UnconnectedSenders.clear(); + recthread = sendthread = null; + } catch (InterruptedException e) { + e.printStackTrace(); //This thread shouldn't be interrupted + } + } - private BukkitTask rectask; - private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); - private Runnable recrun; - private static Thread recthread; + private BukkitTask rectask; + private LinkedBlockingQueue recevents = new LinkedBlockingQueue<>(); + private Runnable recrun; + private static Thread recthread; // Discord - public boolean handleDiscord(MessageReceivedEvent ev) { - if (!ComponentManager.isEnabled(MinecraftChatModule.class)) - return false; - val author = ev.getMessage().getAuthor(); - final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getChannel()); - if (ev.getMessage().getChannel().getLongID() != module.chatChannel().get().getLongID() - && !(ev.getMessage().getChannel().isPrivate() && MCChatPrivate.isMinecraftChatEnabled(author.getStringID())) - && !hasCustomChat) + public boolean handleDiscord(MessageCreateEvent ev) { + if (!ComponentManager.isEnabled(MinecraftChatModule.class)) + return false; + val author = ev.getMessage().getAuthor(); + final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getMessage().getChannelId()); + val channel = ev.getMessage().getChannel().block(); + if (ev.getMessage().getChannelId().asLong() != module.chatChannel().get().getId().asLong() + && !(channel instanceof PrivateChannel + && author.map(u -> MCChatPrivate.isMinecraftChatEnabled(u.getId().asString())).orElse(false) + && !hasCustomChat)) return false; //Chat isn't enabled on this channel - if (ev.getMessage().getChannel().isPrivate() //Only in private chat - && ev.getMessage().getContent().length() < "/mcchat<>".length() - && ev.getMessage().getContent().replace("/", "") - .equalsIgnoreCase("mcchat")) //Either mcchat or /mcchat + if (channel instanceof PrivateChannel //Only in private chat + && ev.getMessage().getContent().isPresent() + && ev.getMessage().getContent().get().length() < "/mcchat<>".length() + && ev.getMessage().getContent().get().replace("/", "") + .equalsIgnoreCase("mcchat")) //Either mcchat or /mcchat return false; //Allow disabling the chat if needed - if (CommandListener.runCommand(ev.getMessage(), true)) - return true; //Allow running commands in chat channels - MCChatUtils.resetLastMessage(ev.getChannel()); - recevents.add(ev); - if (rectask != null) - return true; - recrun = () -> { //Don't return in a while loop next time - recthread = Thread.currentThread(); - processDiscordToMC(); - if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down - rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing - }; - rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing + if (CommandListener.runCommand(ev.getMessage(), true)) + return true; //Allow running commands in chat channels + MCChatUtils.resetLastMessage(channel); + recevents.add(ev); + if (rectask != null) + return true; + recrun = () -> { //Don't return in a while loop next time + recthread = Thread.currentThread(); + processDiscordToMC(); + if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing + }; + rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing return true; - } + } - 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(); - String dmessage = event.getMessage().getContent(); - try { - final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender); - val user = dsender.getChromaUser(); + 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(); + String dmessage = event.getMessage().getContent(); + try { + final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender); + val user = dsender.getChromaUser(); - 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 (User 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 (MessageChannel ch : event.getMessage().getChannelMentions()) { - dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting - } + dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting + } - 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 + 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 - Function getChatMessage = msg -> // - msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() - .getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n")) - : ""); + Function getChatMessage = msg -> // + msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() + .getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n")) + : ""); - MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel()); + MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel()); - 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); - final String cmdlowercased = cmd.toLowerCase(); - if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream() - .noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) { - // Command not whitelisted - dsender.sendMessage("Sorry, you can only access these commands:\n" - + module.whitelistedCommands().get().stream().map(uc -> "/" + uc) - .collect(Collectors.joining(", ")) - + (user.getConnectedID(TBMCPlayer.class) == null - ? "\nTo access your commands, first please connect your accounts, using /connect in " - + DPUtils.botmention() - + "\nThen y" - : "\nY") - + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"); - return; - } - val ev = new TBMCCommandPreprocessEvent(dsender, dmessage); - Bukkit.getPluginManager().callEvent(ev); - if (ev.isCancelled()) - return; - int spi = cmdlowercased.indexOf(' '); - final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi); - Optional ch = Channel.getChannels() - .filter(c -> c.ID.equalsIgnoreCase(topcmd) - || (c.IDs().get().length > 0 - && Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny(); - if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one - Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync - () -> { //TODO: Better handling... - val channel = user.channel(); - val chtmp = channel.get(); - if (clmd != null) { - channel.set(clmd.mcchannel); //Hack to send command in the channel - } //TODO: Permcheck isn't implemented for commands - VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); - Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased); - if (clmd != null) - channel.set(chtmp); - }); - else { - Channel chc = ch.get(); - if (!chc.isGlobal() && !event.getMessage().getChannel().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 { - if (spi == -1) // Switch channels - { - val channel = dsender.getChromaUser().channel(); - val oldch = channel.get(); - if (oldch instanceof ChatRoom) - ((ChatRoom) oldch).leaveRoom(dsender); - if (!oldch.ID.equals(chc.ID)) { - channel.set(chc); - if (chc instanceof ChatRoom) - ((ChatRoom) chc).joinRoom(dsender); - } else - channel.set(Channel.GlobalChat); - dsender.sendMessage("You're now talking in: " - + DPUtils.sanitizeString(channel.get().DisplayName().get())); - } else { // Send single message - final String msg = cmd.substring(spi + 1); - val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true); - if (clmd == null) - TBMCChatAPI.SendChatMessage(cmb.build(), chc); - else - TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc); - react = true; - } - } - } - } else {// Not a command - if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 - && !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) { - 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, - (dsender instanceof Player ? ((Player) dsender).getDisplayName() - : dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL); - } - else { - val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false); - if (clmd != null) - TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), clmd.mcchannel); - else - TBMCChatAPI.SendChatMessage(cmb.build()); - react = true; - } - } - if (react) { - try { - val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getLongID()); - if (lmfd != null) { - DPUtils.perform(() -> lmfd.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); - } - MCChatUtils.lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage()); - DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); - } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); - } - } + if (dmessage.startsWith("/")) { // Ingame command + DPUtils.perform(() -> { + if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) + event.getMessage().delete(); + }); + final String cmd = dmessage.substring(1); + final String cmdlowercased = cmd.toLowerCase(); + if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream() + .noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) { + // Command not whitelisted + dsender.sendMessage("Sorry, you can only access these commands:\n" + + module.whitelistedCommands().get().stream().map(uc -> "/" + uc) + .collect(Collectors.joining(", ")) + + (user.getConnectedID(TBMCPlayer.class) == null + ? "\nTo access your commands, first please connect your accounts, using /connect in " + + DPUtils.botmention() + + "\nThen y" + : "\nY") + + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"); + return; + } + val ev = new TBMCCommandPreprocessEvent(dsender, dmessage); + Bukkit.getPluginManager().callEvent(ev); + if (ev.isCancelled()) + return; + int spi = cmdlowercased.indexOf(' '); + final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi); + Optional ch = Channel.getChannels() + .filter(c -> c.ID.equalsIgnoreCase(topcmd) + || (c.IDs().get().length > 0 + && Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny(); + if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one + Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync + () -> { //TODO: Better handling... + val channel = user.channel(); + val chtmp = channel.get(); + if (clmd != null) { + channel.set(clmd.mcchannel); //Hack to send command in the channel + } //TODO: Permcheck isn't implemented for commands + VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased); + if (clmd != null) + channel.set(chtmp); + }); + else { + Channel chc = ch.get(); + if (!chc.isGlobal() && !event.getMessage().getChannel().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 { + if (spi == -1) // Switch channels + { + val channel = dsender.getChromaUser().channel(); + val oldch = channel.get(); + if (oldch instanceof ChatRoom) + ((ChatRoom) oldch).leaveRoom(dsender); + if (!oldch.ID.equals(chc.ID)) { + channel.set(chc); + if (chc instanceof ChatRoom) + ((ChatRoom) chc).joinRoom(dsender); + } else + channel.set(Channel.GlobalChat); + dsender.sendMessage("You're now talking in: " + + DPUtils.sanitizeString(channel.get().DisplayName().get())); + } else { // Send single message + final String msg = cmd.substring(spi + 1); + val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true); + if (clmd == null) + TBMCChatAPI.SendChatMessage(cmb.build(), chc); + else + TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc); + react = true; + } + } + } + } else {// Not a command + if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 + && !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) { + 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, + (dsender instanceof Player ? ((Player) dsender).getDisplayName() + : dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL); + } else { + val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false); + if (clmd != null) + TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), clmd.mcchannel); + else + TBMCChatAPI.SendChatMessage(cmb.build()); + react = true; + } + } + if (react) { + try { + val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getId().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 + } + } 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)); + } + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); + } + } - @FunctionalInterface - private interface InterruptibleConsumer { - void accept(T value) throws TimeoutException, InterruptedException; - } + @FunctionalInterface + private interface InterruptibleConsumer { + void accept(T value) throws TimeoutException, InterruptedException; + } } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java index 3a2f2f2..3c6c893 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java @@ -10,7 +10,7 @@ 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.IUser; +import sx.blah.discord.handle.obj.User; import sx.blah.discord.handle.obj.MessageChannel; import java.util.ArrayList; @@ -22,7 +22,7 @@ public class MCChatPrivate { */ static ArrayList lastmsgPerUser = new ArrayList<>(); - public static boolean privateMCChat(MessageChannel channel, boolean start, IUser user, DiscordPlayer dp) { + public static boolean privateMCChat(MessageChannel channel, boolean start, User 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()); @@ -39,10 +39,10 @@ public class MCChatPrivate { } } // ---- PermissionsEx warning is normal on logout ---- if (!start) - MCChatUtils.lastmsgfromd.remove(channel.getLongID()); + 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.getLongID() == channel.getLongID()); + : lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()); } public static boolean isMinecraftChatEnabled(DiscordPlayer dp) { @@ -51,7 +51,7 @@ 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().getStringID().equals(did)); + .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getId().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 6399d90..5651d40 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java @@ -81,7 +81,7 @@ public class MCChatUtils { return addSender(senders, user.getId().asLong(), sender); } - public static T addSender(HashMap> senders, + public static T addSender(HashMap> senders, long did, T sender) { var map = senders.get(did); if (map == null) @@ -91,8 +91,8 @@ public class MCChatUtils { return sender; } - public static T getSender(HashMap> senders, - Channel channel, User user) { + public static T getSender(HashMap> senders, + MessageChannel channel, User user) { var map = senders.get(user.getId().asLong()); if (map != null) return map.get(channel); @@ -172,7 +172,7 @@ public class MCChatUtils { } public static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { - if (notEnabled()) return + if (notEnabled()) return; if (event.getChannel().isGlobal()) action.accept(module.chatChannel().get()); for (LastMsgData data : MCChatPrivate.lastmsgPerUser) @@ -188,7 +188,7 @@ public class MCChatUtils { /** * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. */ - static DiscordSenderBase getSender(Channel channel, final User author) { + static DiscordSenderBase getSender(MessageChannel channel, final User author) { //noinspection OptionalGetWithoutIsPresent return Stream.>>of( // https://stackoverflow.com/a/28833677/2703239 () -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null @@ -206,13 +206,13 @@ public class MCChatUtils { */ public static void resetLastMessage(Channel channel) { if (notEnabled()) return; - if (channel.getLongID() == module.chatChannel().get().getLongID()) { + if (channel.getId().asLong() == module.chatChannel().get().getId().asLong()) { (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 for (LastMsgData data : channel.isPrivate() ? MCChatPrivate.lastmsgPerUser : MCChatCustom.lastmsgCustom) { - if (data.channel.getLongID() == channel.getLongID()) { + if (data.channel.getId().asLong() == channel.getId().asLong()) { data.message = null; return; } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java index 3ed7bcf..3c2cf40 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java @@ -24,7 +24,7 @@ import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.BroadcastMessageEvent; import sx.blah.discord.handle.obj.IRole; -import sx.blah.discord.handle.obj.IUser; +import sx.blah.discord.handle.obj.User; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.MissingPermissionsException; @@ -115,7 +115,7 @@ class MCListener implements Listener { final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class) .getAs(DiscordPlayer.class); if (p == null) return; - final IUser user = DiscordPlugin.dc.getUserByID( + final User user = DiscordPlugin.dc.getUserByID( Long.parseLong(p.getDiscordID())); if (e.getValue()) user.addRole(role); @@ -149,7 +149,7 @@ class MCListener implements Listener { : event.getSender().getName(); //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO val yeehaw = DiscordPlugin.mainServer.getEmojiByName("YEEHAW"); - MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getStringID() + ">s" : " YEEHAWs"))); + MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getId().asString() + ">s" : " YEEHAWs"))); } @EventHandler diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 9e8cfe0..5418086 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -9,6 +9,9 @@ import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; import com.google.common.collect.Lists; +import discord4j.core.event.domain.message.MessageCreateEvent; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.util.Snowflake; import lombok.Getter; import lombok.val; import org.bukkit.Bukkit; @@ -23,7 +26,8 @@ import java.util.stream.Collectors; * Provides Minecraft chat connection to Discord. Commands may be used either in a public chat (limited) or in a DM. */ public class MinecraftChatModule extends Component { - private @Getter MCChatListener listener; + private @Getter + MCChatListener listener; /*public MCChatListener getListener() { //It doesn't want to generate return listener; - And now ButtonProcessor didn't look beyond this - return instead of continue... @@ -58,11 +62,20 @@ public class MinecraftChatModule extends Component { return getConfig().getData("excludedPlugins", new String[]{"ProtocolLib", "LibsDisguises", "JourneyMapServer"}); } + /** + * If this setting is on then players logged in through the 'mcchat' command will be able to teleport using plugin commands. + * They can then use commands like /tpahere to teleport others to that place.
+ * If this is off, then teleporting will have no effect. + */ + public ConfigData allowFakePlayerTeleports() { + return getConfig().getData("allowFakePlayerTeleports", false); + } + @Override protected void enable() { if (DPUtils.disableIfConfigError(this, chatChannel())) return; listener = new MCChatListener(this); - DiscordPlugin.dc.getDispatcher().registerListener(listener); + DiscordPlugin.dc.getEventDispatcher().on(MessageCreateEvent.class).subscribe(listener::handleDiscord); 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()); @@ -76,17 +89,17 @@ public class MinecraftChatModule extends Component { for (val chconkey : chconkeys) { val chcon = chcons.getConfigurationSection(chconkey); val mcch = Channel.getChannels().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny(); - val ch = DiscordPlugin.dc.getChannelByID(chcon.getLong("chid")); + val ch = DiscordPlugin.dc.getChannelById(Snowflake.of(chcon.getLong("chid"))).block(); val did = chcon.getLong("did"); - val user = DiscordPlugin.dc.fetchUser(did); + val user = DiscordPlugin.dc.getUserById(Snowflake.of(did)).block(); val groupid = chcon.getString("groupid"); val toggles = chcon.getInt("toggles"); val brtoggles = chcon.getStringList("brtoggles"); if (!mcch.isPresent() || ch == null || user == null || groupid == null) continue; Bukkit.getScheduler().runTask(getPlugin(), () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase) - val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname")); - MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet())); + val dcp = new DiscordConnectedPlayer(user, (MessageChannel) ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"), this); + MCChatCustom.addCustomChat((MessageChannel) ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet())); }); } } @@ -97,10 +110,10 @@ public class MinecraftChatModule extends Component { val chcons = MCChatCustom.getCustomChats(); val chconsc = getConfig().getConfig().createSection("chcons"); for (val chcon : chcons) { - val chconc = chconsc.createSection(chcon.channel.getStringID()); + val chconc = chconsc.createSection(chcon.channel.getId().asString()); chconc.set("mcchid", chcon.mcchannel.ID); - chconc.set("chid", chcon.channel.getLongID()); - chconc.set("did", chcon.user.getLongID()); + chconc.set("chid", chcon.channel.getId().asLong()); + chconc.set("did", chcon.user.getId().asLong()); chconc.set("mcuid", chcon.dcp.getUniqueId().toString()); chconc.set("mcname", chcon.dcp.getName()); chconc.set("groupid", chcon.groupID); diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java index 61cfa5e..9a75717 100755 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordEntity.java @@ -1,6 +1,10 @@ package buttondevteam.discordplugin.playerfaker; +import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordSenderBase; +import buttondevteam.discordplugin.mcchat.MinecraftChatModule; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import lombok.Getter; import lombok.Setter; import org.bukkit.*; @@ -11,8 +15,6 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; import org.bukkit.util.Vector; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.util.*; @@ -20,10 +22,11 @@ import java.util.*; @Setter @SuppressWarnings("deprecated") public abstract class DiscordEntity extends DiscordSenderBase implements Entity { - protected DiscordEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) { + protected DiscordEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) { super(user, channel); this.entityId = entityId; uniqueId = uuid; + this.module = module; } private HashMap metadata = new HashMap(); @@ -34,6 +37,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity private EntityDamageEvent lastDamageCause; private final Set scoreboardTags = new HashSet(); private final UUID uniqueId; + private final MinecraftChatModule module; @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { @@ -42,7 +46,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity @Override public List getMetadata(String metadataKey) { - return Arrays.asList(metadata.get(metadataKey)); // Who needs multiple data anyways + return Collections.singletonList(metadata.get(metadataKey)); // Who needs multiple data anyways } @Override @@ -91,31 +95,35 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity @Override public boolean teleport(Location location) { - this.location = location; + if (module.allowFakePlayerTeleports().get()) + this.location = location; return true; } @Override public boolean teleport(Location location, TeleportCause cause) { - this.location = location; + if (module.allowFakePlayerTeleports().get()) + this.location = location; return true; } @Override public boolean teleport(Entity destination) { - this.location = destination.getLocation(); + if (module.allowFakePlayerTeleports().get()) + this.location = destination.getLocation(); return true; } @Override public boolean teleport(Entity destination, TeleportCause cause) { - this.location = destination.getLocation(); + if (module.allowFakePlayerTeleports().get()) + this.location = destination.getLocation(); return true; } @Override public List getNearbyEntities(double x, double y, double z) { - return Arrays.asList(); + return Collections.emptyList(); } @Override @@ -163,7 +171,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity @Override public List getPassengers() { - return Arrays.asList(); + return Collections.emptyList(); } @Override diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java index e7d1c74..f197c84 100755 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java @@ -1,6 +1,9 @@ package buttondevteam.discordplugin.playerfaker; import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.discordplugin.mcchat.MinecraftChatModule; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import lombok.Getter; import lombok.experimental.Delegate; import org.bukkit.*; @@ -16,16 +19,14 @@ import org.bukkit.map.MapView; import org.bukkit.permissions.PermissibleBase; import org.bukkit.plugin.Plugin; import org.bukkit.scoreboard.Scoreboard; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.net.InetSocketAddress; import java.util.*; @SuppressWarnings("deprecation") public class DiscordFakePlayer extends DiscordHumanEntity implements Player { - protected DiscordFakePlayer(IUser user, MessageChannel channel, int entityId, UUID uuid, String mcname) { - super(user, channel, entityId, uuid); + protected DiscordFakePlayer(User user, MessageChannel channel, int entityId, UUID uuid, String mcname, MinecraftChatModule module) { + super(user, channel, entityId, uuid, module); perm = new PermissibleBase(Bukkit.getOfflinePlayer(uuid)); name = mcname; } @@ -42,7 +43,7 @@ public class DiscordFakePlayer extends DiscordHumanEntity implements Player { @Override public String getCustomName() { - return user.getName(); + return user.getUsername(); } @Override @@ -127,7 +128,7 @@ public class DiscordFakePlayer extends DiscordHumanEntity implements Player { @Override public String getDisplayName() { - return user.getDisplayName(DiscordPlugin.mainServer); + return Objects.requireNonNull(user.asMember(DiscordPlugin.mainServer.getId()).block()).getDisplayName(); } @Override diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java index f984b6c..4b8b32d 100755 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordHumanEntity.java @@ -1,5 +1,8 @@ package buttondevteam.discordplugin.playerfaker; +import buttondevteam.discordplugin.mcchat.MinecraftChatModule; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -8,14 +11,12 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Villager; import org.bukkit.inventory.*; import org.bukkit.inventory.InventoryView.Property; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.util.UUID; public abstract class DiscordHumanEntity extends DiscordLivingEntity implements HumanEntity { - protected DiscordHumanEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) { - super(user, channel, entityId, uuid); + protected DiscordHumanEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) { + super(user, channel, entityId, uuid, module); } private PlayerInventory inv = new DiscordPlayerInventory(this); diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java index 876d17e..c561fbf 100755 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordLivingEntity.java @@ -1,5 +1,8 @@ package buttondevteam.discordplugin.playerfaker; +import buttondevteam.discordplugin.mcchat.MinecraftChatModule; +import discord4j.core.object.entity.MessageChannel; +import discord4j.core.object.entity.User; import lombok.Getter; import lombok.Setter; import org.bukkit.Location; @@ -16,15 +19,13 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; -import sx.blah.discord.handle.obj.IUser; -import sx.blah.discord.handle.obj.MessageChannel; import java.util.*; public abstract class DiscordLivingEntity extends DiscordEntity implements LivingEntity { - protected DiscordLivingEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) { - super(user, channel, entityId, uuid); + protected DiscordLivingEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) { + super(user, channel, entityId, uuid, module); } private @Getter EntityEquipment equipment = new DiscordEntityEquipment(this);