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/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/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 5494a77..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; @@ -20,6 +21,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 +70,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 +95,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 +105,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 +115,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); @@ -169,9 +184,12 @@ 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); + getConfig().set("serverup", false); saveConfig(); sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED) .withTitle(Restart ? "Server restarting" : "Server stopping").build()); @@ -215,6 +233,17 @@ 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); + 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"); 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 ddad886..8d68df0 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()); + } } }; } @@ -126,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 5160f05..0fcd327 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; @@ -21,8 +17,10 @@ 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.RequiredArgsConstructor; import lombok.val; import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.internal.json.objects.EmbedObject; @@ -35,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,8 +42,13 @@ 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 + 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(); @@ -71,31 +72,37 @@ public class MCChatListener implements Listener, IListener TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); } }; - if (e.getChannel().equals(Channel.GlobalChat)) - doit.accept(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) - : lastmsgdata); + 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) { - 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))) + // 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); } } - }); // TODO: Author URL + }); } + @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 LastMsgData(IChannel channel) { - this.channel = channel; - } + public final IUser user; + public final DiscordPlayer dp; } @EventHandler @@ -134,19 +141,20 @@ 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 - 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 // - ? 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()); } @@ -178,15 +186,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(); @@ -212,7 +232,15 @@ 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")) + : "")); + + boolean react = false; + + if (dmessage.startsWith("/")) { // Ingame command DiscordPlugin.perform(() -> { if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) event.getMessage().delete(); @@ -238,20 +266,47 @@ public class MCChatListener implements Listener, IListener { dsender.sendMessage("Stop it. You know the answer."); lastlist = 0; - } else - VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + } else { + int spi = cmd.indexOf(' '); + final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi); + Optional ch = Channel.getChannels().stream().filter(c -> c.ID.equalsIgnoreCase(topcmd)) + .findAny(); + if (!ch.isPresent()) + VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); + else { + Channel chc = ch.get(); + if (!chc.ID.equals(Channel.GlobalChat.ID) && !event.getMessage().getChannel().isPrivate()) + dsender.sendMessage( + "You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels."); + else { + if (spi == -1) // Switch channels + { + val oldch = dsender.getMcchannel(); + if (oldch instanceof ChatRoom) + ((ChatRoom) oldch).leaveRoom(dsender); + 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 + sendChatMessage.accept(chc, cmd.substring(spi + 1)); + react = true; + } + } + } + } lastlistp = (short) Bukkit.getOnlinePlayers().size(); - } else { - if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0) + } else {// Not a command + 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 - TBMCChatAPI - .SendChatMessage(Channel.GlobalChat, - dsender, dmessage - + (event.getMessage().getAttachments().size() > 0 - ? "\n" + event.getMessage().getAttachments().stream() - .map(a -> a.getUrl()).collect(Collectors.joining("\n")) - : "")); + 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); @@ -273,7 +328,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 dc7fcad..5361559 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; @@ -18,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.*; @@ -41,7 +50,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 +71,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 +130,67 @@ public class MCListener implements Listener { ex); } } + + @EventHandler + public void onChatSystemMessage(TBMCSystemChatEvent event) { + MCChatListener.sendSystemMessageToChat(event); + } + + /** + * 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); + } + } + } } 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() {