From b0c791e6221e723a8c966e37452a2c570233e7a4 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 19 Jul 2017 13:26:22 +0200 Subject: [PATCH 1/7] Did some old open issues #5 - Post if the server crashes #7 - When announcing a Reddit post, use Discord names, if known #9 - Print "full house" when full house --- .../discordplugin/DiscordPlugin.java | 46 ++++++++++++++----- .../listeners/CommandListener.java | 20 ++++++++ .../listeners/MCChatListener.java | 4 +- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 5494a77..b6e45d5 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -20,6 +20,8 @@ import buttondevteam.discordplugin.listeners.*; import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.TBMCChatAPI; +import buttondevteam.lib.player.ChromaGamerBase; +import lombok.val; import net.milkbowl.vault.permission.Permission; import sx.blah.discord.api.*; import sx.blah.discord.api.events.IListener; @@ -67,6 +69,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { */ public static IChannel officechannel; public static IChannel updatechannel; + public static IChannel devofficechannel; public static IGuild mainServer; public static IGuild devServer; @@ -91,6 +94,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room officechannel = devServer.getChannelByID(219626707458457603L); // developers-office updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates + devofficechannel = officechannel; // developers-office dc.online("on TBMC"); } else { botchannel = devServer.getChannelByID(239519012529111040L); // bot-room @@ -100,6 +104,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { chatchannel = botchannel;// bot-room officechannel = devServer.getChannelByID(219626707458457603L); // developers-office updatechannel = botchannel; + devofficechannel = botchannel;// bot-room dc.online("testing"); } if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null @@ -109,17 +114,26 @@ public class DiscordPlugin extends JavaPlugin implements IListener { if (task != null) task.cancel(); if (!sent) { - sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN) - .withTitle("Server started - chat connected.").build()); - try { - List msgs = genchannel.getPinnedMessages(); - for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10 - genchannel.unpin(msgs.get(i)); - Thread.sleep(10); + if (getConfig().getBoolean("serverup", false)) { + sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.YELLOW) + .withTitle("Server recovered from a crash - chat connected.").build()); + TBMCCoreAPI.SendException("The server crashed!", new Throwable( + "The server shut down unexpectedly. See the log of the previous run for more details.")); + } else + sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN) + .withTitle("Server started - chat connected.").build()); + getConfig().set("serverup", true); + saveConfig(); + perform(() -> { + try { + List msgs = genchannel.getPinnedMessages(); + for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10 + genchannel.unpin(msgs.get(i)); + Thread.sleep(10); + } + } catch (InterruptedException e) { } - } catch (Exception e) { - TBMCCoreAPI.SendException("Error occured while unpinning messages!", e); - } + }); sent = true; } }, 0, 10); @@ -172,6 +186,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastseentime", lastseentime); getConfig().set("gameroles", GameRoles); + getConfig().set("serverup", false); saveConfig(); sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED) .withTitle(Restart ? "Server restarting" : "Server stopping").build()); @@ -203,7 +218,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { for (int i = json.size() - 1; i >= 0; i--) { JsonObject item = json.get(i).getAsJsonObject(); final JsonObject data = item.get("data").getAsJsonObject(); - String author = data.get("author").getAsString(); + String author = "/u/" + data.get("author").getAsString(); JsonElement distinguishedjson = data.get("distinguished"); String distinguished; if (distinguishedjson.isJsonNull()) @@ -215,6 +230,15 @@ public class DiscordPlugin extends JavaPlugin implements IListener { if (date > lastseentime) lastseentime = date; else if (date > lastannouncementtime) { + do { + val reddituserclass = ChromaGamerBase.getTypeForFolder("reddit"); + if (reddituserclass == null) + break; + val user = ChromaGamerBase.getUser(author, reddituserclass); + String id = user.getConnectedID(DiscordPlayer.class); + if (id != null) + author = "<@" + id + ">"; + } while (false); (distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb) .append("A new post was submitted to the subreddit by ").append(author).append("\n") .append(permalink).append("\n"); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index ddad886..2d6ea2b 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -8,11 +8,15 @@ import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.lib.TBMCCoreAPI; +import lombok.val; import sx.blah.discord.api.events.IListener; import sx.blah.discord.handle.impl.events.guild.channel.message.MentionEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; +import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; +import sx.blah.discord.handle.obj.StatusType; +import sx.blah.discord.util.EmbedBuilder; public class CommandListener { @@ -89,6 +93,22 @@ public class CommandListener { return; runCommand(event.getMessage(), false); } + }, new IListener() { + @Override + public void handle(PresenceUpdateEvent event) { + val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0); + if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE) + && !event.getNewPresence().getStatus().equals(StatusType.OFFLINE) + && event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream() + .anyMatch(r -> r.getLongID() == devrole.getLongID()) + && DiscordPlugin.devServer.getUsersByRole(devrole).stream() + .noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))) + DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!", + new EmbedBuilder() + .withImage( + "https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png") + .build()); + } } }; } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 5160f05..72892a2 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -238,8 +238,10 @@ public class MCChatListener implements Listener, IListener { dsender.sendMessage("Stop it. You know the answer."); lastlist = 0; - } else + } else { + String topcmd = null; // TODO: Channels VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + } lastlistp = (short) Bukkit.getOnlinePlayers().size(); } else { if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0) From 67074017d2051f4a9b6074ceff14acda50766923 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 4 Aug 2017 13:33:26 +0200 Subject: [PATCH 2/7] Added chat channel & mixed case cmds support Needs testing --- .../discordplugin/DiscordSenderBase.java | 5 ++ .../listeners/CommandListener.java | 2 +- .../listeners/MCChatListener.java | 50 ++++++++++++------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java index 172b738..16e9a3d 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordSenderBase.java @@ -9,7 +9,11 @@ import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitTask; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.IDiscordSender; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; @@ -19,6 +23,7 @@ public abstract class DiscordSenderBase implements IDiscordSender { */ protected IUser user; protected IChannel channel; + private @Getter @Setter @NonNull Channel mcchannel = Channel.GlobalChat; protected DiscordSenderBase(IUser user, IChannel channel) { this.user = user; diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 2d6ea2b..8d68df0 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -146,7 +146,7 @@ public class CommandListener { cmd = cmdwithargs.substring(0, index); args = cmdwithargs.substring(index + 1); } - DiscordCommandBase.runCommand(cmd, args, message); + DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message); message.getChannel().setTypingStatus(false); return true; } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 72892a2..9a2763a 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -1,12 +1,8 @@ package buttondevteam.discordplugin.listeners; import java.awt.Color; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Supplier; +import java.util.*; +import java.util.function.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -212,7 +208,13 @@ public class MCChatListener implements Listener, IListener dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); } - if (dmessage.startsWith("/")) { + BiConsumer sendChatMessage = (channel, msg) -> TBMCChatAPI.SendChatMessage(channel, + dsender, + msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() + .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) + : "")); + + if (dmessage.startsWith("/")) { // Ingame command DiscordPlugin.perform(() -> { if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) event.getMessage().delete(); @@ -239,21 +241,35 @@ public class MCChatListener implements Listener, IListener dsender.sendMessage("Stop it. You know the answer."); lastlist = 0; } else { - String topcmd = null; // TODO: Channels - VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + int spi = cmd.indexOf(' '); + final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi); + Optional ch = Channel.getChannels().stream().filter(c -> c.ID.equalsIgnoreCase(topcmd)) + .findAny(); + if (!ch.isPresent()) + VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + else // TO!DO: Only allow talking in general in public chat - A to-do from before I went to Greece + { + Channel chc = ch.get(); + if (!chc.ID.equals(Channel.GlobalChat.ID) && !event.getMessage().getChannel().isPrivate()) + dsender.sendMessage( + "You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels."); + else { + if (spi == -1) // Switch channels + { + dsender.setMcchannel(chc); + dsender.sendMessage("You're now talking in: " + + DiscordPlugin.sanitizeString(dsender.getMcchannel().DisplayName)); + } else // Send single message + sendChatMessage.accept(chc, cmd.substring(spi + 1)); + } + } } lastlistp = (short) Bukkit.getOnlinePlayers().size(); - } else { + } else {// Not a command if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0) TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message else - TBMCChatAPI - .SendChatMessage(Channel.GlobalChat, - dsender, dmessage - + (event.getMessage().getAttachments().size() > 0 - ? "\n" + event.getMessage().getAttachments().stream() - .map(a -> a.getUrl()).collect(Collectors.joining("\n")) - : "")); + sendChatMessage.accept(dsender.getMcchannel(), dmessage); event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> { try { final IReaction reaction = m.getReactionByUnicode(DiscordPlugin.DELIVERED_REACTION); From 649fd4611fcec488fe49c537bda4f062ed7ded8b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 5 Aug 2017 15:45:31 +0200 Subject: [PATCH 3/7] Excluding ProtocolLib from fake player events --- .../listeners/MCChatListener.java | 4 +- .../discordplugin/listeners/MCListener.java | 70 ++++++++++++++++++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 9a2763a..138c154 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -134,11 +134,11 @@ public class MCChatListener implements Listener, IListener val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID()); ConnectedSenders.put(user.getStringID(), sender); if (p == null)// Player is offline - If the player is online, that takes precedence - Bukkit.getPluginManager().callEvent(new PlayerJoinEvent(sender, "")); + MCListener.callEventExcluding(new PlayerJoinEvent(sender, ""), "ProtocolLib"); } else { val sender = ConnectedSenders.remove(user.getStringID()); if (p == null)// Player is offline - If the player is online, that takes precedence - Bukkit.getPluginManager().callEvent(new PlayerQuitEvent(sender, "")); + MCListener.callEventExcluding(new PlayerQuitEvent(sender, ""), "ProtocolLib"); } } return start // diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java index dc7fcad..c60ca6c 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -1,14 +1,22 @@ package buttondevteam.discordplugin.listeners; +import java.util.Arrays; +import java.util.logging.Level; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.ServerCommandEvent; +import org.bukkit.plugin.AuthorNagException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; import com.earth2me.essentials.CommandSource; @@ -41,7 +49,7 @@ public class MCListener implements Listener { new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); MCChatListener.ConnectedSenders.values().stream() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> Bukkit.getPluginManager().callEvent(new PlayerQuitEvent(dcp, ""))); + .ifPresent(dcp -> callEventExcluding(new PlayerQuitEvent(dcp, ""), "ProtocolLib")); } if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { IUser user = DiscordPlugin.dc @@ -62,7 +70,7 @@ public class MCListener implements Listener { .removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())); MCChatListener.ConnectedSenders.values().stream() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> Bukkit.getPluginManager().callEvent(new PlayerJoinEvent(dcp, ""))); + .ifPresent(dcp -> callEventExcluding(new PlayerJoinEvent(dcp, ""), "ProtocolLib")); MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " left the game"); } @@ -121,4 +129,62 @@ public class MCListener implements Listener { ex); } } + + /** + * Calls an event with the given details. + *

+ * This method only synchronizes when the event is not asynchronous. + * + * @param event + * Event details + * @param plugins + * The plugins to exclude. Not case sensitive. + */ + public static void callEventExcluding(Event event, String... plugins) { // Copied from Spigot-API and modified a bit + if (event.isAsynchronous()) { + if (Thread.holdsLock(Bukkit.getPluginManager())) { + throw new IllegalStateException( + event.getEventName() + " cannot be triggered asynchronously from inside synchronized code."); + } + if (Bukkit.getServer().isPrimaryThread()) { + throw new IllegalStateException( + event.getEventName() + " cannot be triggered asynchronously from primary server thread."); + } + fireEventExcluding(event, plugins); + } else { + synchronized (Bukkit.getPluginManager()) { + fireEventExcluding(event, plugins); + } + } + } + + private static void fireEventExcluding(Event event, String... plugins) { + HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API + RegisteredListener[] listeners = handlers.getRegisteredListeners(); + val server = Bukkit.getServer(); + + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled() + || Arrays.stream(plugins).anyMatch(p -> p.equalsIgnoreCase(registration.getPlugin().getName()))) + continue; // Modified to exclude plugins + + try { + registration.callEvent(event); + } catch (AuthorNagException ex) { + Plugin plugin = registration.getPlugin(); + + if (plugin.isNaggable()) { + plugin.setNaggable(false); + + server.getLogger().log(Level.SEVERE, + String.format("Nag author(s): '%s' of '%s' about the following: %s", + plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(), + ex.getMessage())); + } + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + + registration.getPlugin().getDescription().getFullName(), ex); + } + } + } } From cda76fdb9377240b1d288d8ed4e30dc923571118 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 6 Aug 2017 02:23:13 +0200 Subject: [PATCH 4/7] Fixes, added quitting fake players on disable --- pom.xml | 2 +- .../java/buttondevteam/discordplugin/DiscordPlugin.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c6ea957..d2d1e7b 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ maven-compiler-plugin - 3.3 + 3.6.2 1.8 1.8 diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index b6e45d5..d44fd38 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Random; import org.bukkit.Bukkit; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitTask; @@ -183,6 +184,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener { @Override public void onDisable() { stop = true; + for(val entry : MCChatListener.ConnectedSenders.entrySet()) + MCListener.callEventExcluding(new PlayerQuitEvent(entry.getValue(), ""), "ProtocolLib"); getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastseentime", lastseentime); getConfig().set("gameroles", GameRoles); @@ -218,7 +221,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener { for (int i = json.size() - 1; i >= 0; i--) { JsonObject item = json.get(i).getAsJsonObject(); final JsonObject data = item.get("data").getAsJsonObject(); - String author = "/u/" + data.get("author").getAsString(); + String author = data.get("author").getAsString(); JsonElement distinguishedjson = data.get("distinguished"); String distinguished; if (distinguishedjson.isJsonNull()) @@ -239,6 +242,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener { if (id != null) author = "<@" + id + ">"; } while (false); + if (!author.startsWith("<")) + author = "/u/" + author; (distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb) .append("A new post was submitted to the subreddit by ").append(author).append("\n") .append(permalink).append("\n"); From 447f0a3d25a72cb2ef4d325aaace3802e3d2b2e2 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 6 Aug 2017 23:09:26 +0200 Subject: [PATCH 5/7] A fix regarding private pins and part of #34 --- .../discordplugin/listeners/MCChatListener.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 138c154..c4b4c64 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -42,8 +42,9 @@ public class MCChatListener implements Listener, IListener .withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(), e.getChannel().color.getGreen(), e.getChannel().color.getBlue())); if (e.getSender() instanceof Player) - embed.withAuthorIcon( - "https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png"); + embed.withAuthorIcon("https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png") + .withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id=" + + ((Player) e.getSender()).getUniqueId()); // TODO: Constant/method to get URLs like this final long nanoTime = System.nanoTime(); Consumer doit = lastmsgdata -> { final EmbedObject embedObject = embed.build(); @@ -79,7 +80,7 @@ public class MCChatListener implements Listener, IListener doit.accept(data); } } - }); // TODO: Author URL + }); } private static class LastMsgData { @@ -247,8 +248,7 @@ public class MCChatListener implements Listener, IListener .findAny(); if (!ch.isPresent()) VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); - else // TO!DO: Only allow talking in general in public chat - A to-do from before I went to Greece - { + else { Channel chc = ch.get(); if (!chc.ID.equals(Channel.GlobalChat.ID) && !event.getMessage().getChannel().isPrivate()) dsender.sendMessage( @@ -266,7 +266,8 @@ public class MCChatListener implements Listener, IListener } lastlistp = (short) Bukkit.getOnlinePlayers().size(); } else {// Not a command - if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0) + if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 + && !event.getChannel().isPrivate()) TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message else sendChatMessage.accept(dsender.getMcchannel(), dmessage); From 0156888681b6b1b9180e29f03df29ed159983450 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 7 Aug 2017 20:42:28 +0200 Subject: [PATCH 6/7] Fixes, implemented ChatRooms A few hours ago --- .../listeners/MCChatListener.java | 39 +++++++++++++------ .../discordplugin/listeners/MCListener.java | 6 +++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index c4b4c64..8a95071 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -17,6 +17,7 @@ import buttondevteam.discordplugin.*; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; import buttondevteam.lib.*; import buttondevteam.lib.chat.Channel; +import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.TBMCPlayer; import lombok.val; @@ -69,14 +70,11 @@ public class MCChatListener implements Listener, IListener } }; if (e.getChannel().equals(Channel.GlobalChat)) - doit.accept(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) - : lastmsgdata); + doit.accept(lastmsgdata == null + ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) : lastmsgdata); for (LastMsgData data : lastmsgPerUser) { - final IUser iUser = data.channel.getUsersHere().stream() - .filter(u -> u.getLongID() != u.getClient().getOurUser().getLongID()).findFirst().get(); // Doesn't support group DMs - final DiscordPlayer user = DiscordPlayer.getUser(iUser.getStringID(), DiscordPlayer.class); - if (user.isMinecraftChatEnabled() && e.shouldSendTo(getSender(data.channel, iUser, user))) + if (data.dp.isMinecraftChatEnabled() && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) doit.accept(data); } } @@ -89,8 +87,10 @@ public class MCChatListener implements Listener, IListener public String content; public IChannel channel; public Channel mcchannel; + public IUser user; + public DiscordPlayer dp; - public LastMsgData(IChannel channel) { + public LastMsgData(IChannel channel, IUser user, DiscordPlayer dp) { this.channel = channel; } } @@ -143,7 +143,7 @@ public class MCChatListener implements Listener, IListener } } return start // - ? lastmsgPerUser.add(new LastMsgData(channel)) // + ? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs : lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); } @@ -175,15 +175,27 @@ public class MCChatListener implements Listener, IListener public static short ListC = 0; public static void resetLastMessage() { - (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) : lastmsgdata).message = null; // Don't set the whole object to null, the player and channel information should - } // be preserved + (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) + : lastmsgdata).message = null; + } // Don't set the whole object to null, the player and channel information should be preserved + /** + * This overload sends it to the global chat. + */ public static void sendSystemMessageToChat(String msg) { DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, msg); for (LastMsgData data : lastmsgPerUser) DiscordPlugin.sendMessageToChannel(data.channel, msg); } + public static void sendSystemMessageToChat(TBMCSystemChatEvent event) { + if (Channel.GlobalChat.ID.equals(event.getChannel().ID)) + DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, event.getMessage()); + for (LastMsgData data : lastmsgPerUser) + if (event.shouldSendTo(getSender(data.channel, data.user, data.dp))) + DiscordPlugin.sendMessageToChannel(data.channel, event.getMessage()); + } + @Override // Discord public void handle(MessageReceivedEvent event) { val author = event.getMessage().getAuthor(); @@ -256,7 +268,12 @@ public class MCChatListener implements Listener, IListener else { if (spi == -1) // Switch channels { + val oldch = dsender.getMcchannel(); + if (oldch instanceof ChatRoom) + ((ChatRoom) oldch).leaveRoom(dsender); dsender.setMcchannel(chc); + if (chc instanceof ChatRoom) + ((ChatRoom) chc).joinRoom(dsender); dsender.sendMessage("You're now talking in: " + DiscordPlugin.sanitizeString(dsender.getMcchannel().DisplayName)); } else // Send single message @@ -292,7 +309,7 @@ public class MCChatListener implements Listener, IListener /** * This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc. */ - private DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { + private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); return Stream.>>of( // https://stackoverflow.com/a/28833677/2703239 () -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java index c60ca6c..5361559 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -26,6 +26,7 @@ import buttondevteam.discordplugin.DiscordPlayerSender; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.commands.ConnectCommand; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.player.*; import lombok.val; import net.ess3.api.events.*; @@ -130,6 +131,11 @@ public class MCListener implements Listener { } } + @EventHandler + public void onChatSystemMessage(TBMCSystemChatEvent event) { + MCChatListener.sendSystemMessageToChat(event); + } + /** * Calls an event with the given details. *

From 6e619f659f436719a057d36942829e3bcdb9ed77 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 15 Aug 2017 03:05:38 +0200 Subject: [PATCH 7/7] Bunch of fixes! - Fixed fake user name, some plugins depend on MC name - Players will need to relog into mcchat if their name changed - Fixed join-while-mcchat in ButtonCore - Fixed Discord->MC messages showing up in inccorect places on Discord - Fixed chat channel feedback - Other fixes --- .../discordplugin/DiscordConnectedPlayer.java | 4 +- .../listeners/MCChatListener.java | 47 +++++++++++++------ .../playerfaker/DiscordFakePlayer.java | 9 ++-- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java index c10f13b..ef91b16 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordConnectedPlayer.java @@ -12,8 +12,8 @@ public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlay private static int nextEntityId = 10000; private @Getter VanillaCommandListener vanillaCmdListener; - public DiscordConnectedPlayer(IUser user, IChannel channel, UUID uuid) { - super(user, channel, nextEntityId++, uuid); + public DiscordConnectedPlayer(IUser user, IChannel channel, UUID uuid, String mcname) { + super(user, channel, nextEntityId++, uuid, mcname); vanillaCmdListener = new VanillaCommandListener<>(this); } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java index 8a95071..0fcd327 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCChatListener.java @@ -20,6 +20,7 @@ import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.TBMCPlayer; +import lombok.RequiredArgsConstructor; import lombok.val; import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.internal.json.objects.EmbedObject; @@ -32,8 +33,6 @@ public class MCChatListener implements Listener, IListener public void onMCChat(TBMCChatEvent e) { if (e.isCancelled()) return; - if (e.getSender() instanceof DiscordSender || e.getSender() instanceof DiscordPlayerSender) - return; Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { synchronized (this) { final String authorPlayer = DiscordPlugin.sanitizeString(e.getSender() instanceof Player // @@ -46,6 +45,10 @@ public class MCChatListener implements Listener, IListener embed.withAuthorIcon("https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png") .withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id=" + ((Player) e.getSender()).getUniqueId()); // TODO: Constant/method to get URLs like this + 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 final long nanoTime = System.nanoTime(); Consumer doit = lastmsgdata -> { final EmbedObject embedObject = embed.build(); @@ -69,30 +72,37 @@ public class MCChatListener implements Listener, IListener TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); } }; - if (e.getChannel().equals(Channel.GlobalChat)) + Predicate isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase) + || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID(); + + if (e.getChannel().equals(Channel.GlobalChat) && isdifferentchannel.test(DiscordPlugin.chatchannel)) doit.accept(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) : lastmsgdata); for (LastMsgData data : lastmsgPerUser) { - if (data.dp.isMinecraftChatEnabled() && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) + // System.out.println("Data: " + data); + // System.out.println("Data.channel: " + data.channel); + // System.out.println("Sender: " + e.getSender()); + // System.out.println("Sender channel: " + ((DiscordSenderBase) e.getSender()).getChannel()); // TODO + // System.out.println("Predicate: " + isdifferentchannel); + // System.out.println("DP: " + data.dp); - Didn't update the constructor + if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel) + && e.shouldSendTo(getSender(data.channel, data.user, data.dp))) doit.accept(data); } } }); } + @RequiredArgsConstructor private static class LastMsgData { public IMessage message; public long time; public String content; - public IChannel channel; + public final IChannel channel; public Channel mcchannel; - public IUser user; - public DiscordPlayer dp; - - public LastMsgData(IChannel channel, IUser user, DiscordPlayer dp) { - this.channel = channel; - } + public final IUser user; + public final DiscordPlayer dp; } @EventHandler @@ -131,8 +141,9 @@ public class MCChatListener implements Listener, IListener TBMCPlayer mcp = dp.getAs(TBMCPlayer.class); if (mcp != null) { // If the accounts aren't connected, can't make a connected sender val p = Bukkit.getPlayer(mcp.getUUID()); + val op = Bukkit.getOfflinePlayer(mcp.getUUID()); if (start) { - val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID()); + val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); ConnectedSenders.put(user.getStringID(), sender); if (p == null)// Player is offline - If the player is online, that takes precedence MCListener.callEventExcluding(new PlayerJoinEvent(sender, ""), "ProtocolLib"); @@ -227,6 +238,8 @@ public class MCChatListener implements Listener, IListener .getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) : "")); + boolean react = false; + if (dmessage.startsWith("/")) { // Ingame command DiscordPlugin.perform(() -> { if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) @@ -276,8 +289,10 @@ public class MCChatListener implements Listener, IListener ((ChatRoom) chc).joinRoom(dsender); dsender.sendMessage("You're now talking in: " + DiscordPlugin.sanitizeString(dsender.getMcchannel().DisplayName)); - } else // Send single message + } else { // Send single message sendChatMessage.accept(chc, cmd.substring(spi + 1)); + react = true; + } } } } @@ -286,8 +301,12 @@ public class MCChatListener implements Listener, IListener if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 && !event.getChannel().isPrivate()) TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message - else + else { sendChatMessage.accept(dsender.getMcchannel(), dmessage); + react = true; + } + } + if (react) { event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> { try { final IReaction reaction = m.getReactionByUnicode(DiscordPlugin.DELIVERED_REACTION); diff --git a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java index 69e8126..8943970 100644 --- a/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java +++ b/src/main/java/buttondevteam/discordplugin/playerfaker/DiscordFakePlayer.java @@ -16,22 +16,21 @@ import org.bukkit.scoreboard.Scoreboard; import buttondevteam.discordplugin.DiscordPlugin; import lombok.experimental.Delegate; +import lombok.Getter; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IUser; public class DiscordFakePlayer extends DiscordHumanEntity implements Player { - protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid) { + protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid, String mcname) { super(user, channel, entityId, uuid); perm = new PermissibleBase(Bukkit.getOfflinePlayer(uuid)); + name = mcname; } @Delegate private PermissibleBase perm; - @Override - public String getName() { - return user.getName(); - } + private @Getter String name; @Override public EntityType getType() {