From 5ff433f3bbaa2809233910eb8bf2fb2bdd506f26 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 22 Dec 2018 16:20:20 +0100 Subject: [PATCH] Code organization Moved part of MCListener Added support for custom chat player list --- .../discordplugin/ChromaBot.java | 14 +- .../discordplugin/DiscordPlugin.java | 11 +- .../discordplugin/listeners/MCListener.java | 174 ++--------------- .../discordplugin/mcchat/MCChatPrivate.java | 8 +- .../discordplugin/mcchat/MCChatUtils.java | 38 +++- .../discordplugin/mcchat/MCListener.java | 184 ++++++++++++++++++ .../mcchat/MinecraftChatModule.java | 1 + 7 files changed, 247 insertions(+), 183 deletions(-) create mode 100644 src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java diff --git a/src/main/java/buttondevteam/discordplugin/ChromaBot.java b/src/main/java/buttondevteam/discordplugin/ChromaBot.java index 90e5afb..56a6fb9 100755 --- a/src/main/java/buttondevteam/discordplugin/ChromaBot.java +++ b/src/main/java/buttondevteam/discordplugin/ChromaBot.java @@ -2,7 +2,6 @@ package buttondevteam.discordplugin; import buttondevteam.discordplugin.mcchat.MCChatUtils; import lombok.Getter; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitScheduler; import sx.blah.discord.api.internal.json.objects.EmbedObject; @@ -11,8 +10,6 @@ import sx.blah.discord.util.EmbedBuilder; import javax.annotation.Nullable; import java.awt.*; -import java.util.Arrays; -import java.util.stream.Collectors; public class ChromaBot { /** @@ -144,15 +141,6 @@ public class ChromaBot { } public void updatePlayerList() { - DPUtils.performNoWait(() -> { - String[] s = DiscordPlugin.chatchannel.getTopic().split("\\n----\\n"); - if (s.length < 3) - return; - s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "") - + " online"; - s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream() - .map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", ")); - DiscordPlugin.chatchannel.changeTopic(Arrays.stream(s).collect(Collectors.joining("\n----\n"))); - }); + MCChatUtils.updatePlayerList(); } } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 8c4856a..da87790 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -5,10 +5,7 @@ import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.discordplugin.listeners.ExceptionListener; import buttondevteam.discordplugin.listeners.MCListener; -import buttondevteam.discordplugin.mcchat.MCChatCustom; -import buttondevteam.discordplugin.mcchat.MCChatListener; -import buttondevteam.discordplugin.mcchat.MCChatUtils; -import buttondevteam.discordplugin.mcchat.MinecraftChatModule; +import buttondevteam.discordplugin.mcchat.*; import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase; import buttondevteam.discordplugin.mccommands.ResetMCCommand; import buttondevteam.lib.TBMCCoreAPI; @@ -27,7 +24,6 @@ import lombok.val; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.scheduler.BukkitTask; import sx.blah.discord.api.ClientBuilder; @@ -250,10 +246,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener @Override public void pluginDisable() { stop = true; - for (val entry : MCChatUtils.ConnectedSenders.entrySet()) - for (val valueEntry : entry.getValue().entrySet()) - MCListener.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); - MCChatUtils.ConnectedSenders.clear(); + MCChatPrivate.logoutAll(); getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastseentime", lastseentime); getConfig().set("serverup", false); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java index cd8a826..89b4e17 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java @@ -1,99 +1,29 @@ package buttondevteam.discordplugin.listeners; -import buttondevteam.discordplugin.*; -import buttondevteam.discordplugin.commands.ConnectCommand; -import buttondevteam.discordplugin.mcchat.MCChatListener; +import buttondevteam.discordplugin.ChannelconBroadcast; +import buttondevteam.discordplugin.DPUtils; +import buttondevteam.discordplugin.DiscordPlayer; +import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.mcchat.MCChatUtils; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCSystemChatEvent; -import buttondevteam.lib.player.*; +import buttondevteam.lib.player.TBMCPlayer; +import buttondevteam.lib.player.TBMCPlayerBase; +import buttondevteam.lib.player.TBMCPlayerGetInfoEvent; +import buttondevteam.lib.player.TBMCYEEHAWEvent; import com.earth2me.essentials.CommandSource; -import lombok.val; -import net.ess3.api.events.AfkStatusChangeEvent; import net.ess3.api.events.MuteStatusChangeEvent; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.event.*; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; -import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.event.server.BroadcastMessageEvent; import org.bukkit.event.server.ServerCommandEvent; -import org.bukkit.plugin.AuthorNagException; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.RegisteredListener; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.MissingPermissionsException; -import java.util.Arrays; -import java.util.logging.Level; - public class MCListener implements Listener { - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerLogin(PlayerLoginEvent e) { - if (e.getResult() != Result.ALLOWED) - return; - MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders - .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onPlayerJoin(TBMCPlayerJoinEvent e) { - if (e.getPlayer() instanceof DiscordConnectedPlayer) - return; // Don't show the joined message for the fake player - Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { - final Player p = e.getPlayer(); - DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); - if (dp != null) { - val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); - MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(), - new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); - MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(), - new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel - } - if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { - IUser user = DiscordPlugin.dc - .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); - p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() - + " do /discord accept"); - p.sendMessage("§bIf it wasn't you, do /discord decline"); - } - final String message = e.GetPlayer().PlayerName().get() + " joined the game"; - MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true); - MCChatListener.ListC = 0; - ChromaBot.getInstance().updatePlayerList(); - }); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerLeave(TBMCPlayerQuitEvent e) { - if (e.getPlayer() instanceof DiscordConnectedPlayer) - return; // Only care about real users - MCChatUtils.OnlineSenders.entrySet() - .removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId()))); - Bukkit.getScheduler().runTask(DiscordPlugin.plugin, - () -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) - .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() - .ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); - Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, - ChromaBot.getInstance()::updatePlayerList, 5); - final String message = e.GetPlayer().PlayerName().get() + " left the game"; - MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerKick(PlayerKickEvent e) { - /*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting") - && !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special - MCChatListener.forAllowedCustomAndAllMCChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook*/ - } - @EventHandler public void onGetInfo(TBMCPlayerGetInfoEvent e) { if (DiscordPlugin.SafeMode) @@ -108,21 +38,6 @@ public class MCListener implements Listener { e.addInfo(user.getPresence().getActivity().get() + ": " + user.getPresence().getText().get()); } - @EventHandler(priority = EventPriority.LOW) - public void onPlayerDeath(PlayerDeathEvent e) { - MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true); - } - - @EventHandler - public void onPlayerAFK(AfkStatusChangeEvent e) { - final Player base = e.getAffected().getBase(); - if (e.isCancelled() || !base.isOnline()) - return; - final String msg = base.getDisplayName() - + " is " + (e.getValue() ? "now" : "no longer") + " AFK."; - MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false); - } - @EventHandler public void onServerCommand(ServerCommandEvent e) { DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped @@ -136,13 +51,16 @@ public class MCListener implements Listener { final CommandSource source = e.getAffected().getSource(); if (!source.isPlayer()) return; + final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class) + .getAs(DiscordPlayer.class); + if (p == null) return; final IUser user = DiscordPlugin.dc.getUserByID( - Long.parseLong(TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class) - .getAs(DiscordPlayer.class).getDiscordID())); + Long.parseLong(p.getDiscordID())); if (e.getValue()) user.addRole(role); else user.removeRole(role); + DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName()); }); } catch (DiscordException | MissingPermissionsException ex) { TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!", @@ -167,66 +85,4 @@ public class MCListener implements Listener { //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s")); } - - private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises"}; - - public static void callEventExcludingSome(Event event) { - callEventExcluding(event, EXCLUDED_PLUGINS); - } - - /** - * 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. - */ - private 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/mcchat/MCChatPrivate.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java index 3afdd18..5edcfa0 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java @@ -2,7 +2,6 @@ package buttondevteam.discordplugin.mcchat; import buttondevteam.discordplugin.DiscordConnectedPlayer; import buttondevteam.discordplugin.DiscordPlayer; -import buttondevteam.discordplugin.listeners.MCListener; import buttondevteam.lib.player.TBMCPlayer; import lombok.val; import org.bukkit.Bukkit; @@ -52,4 +51,11 @@ public class MCChatPrivate { return lastmsgPerUser.stream() .anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did)); } + + public static void logoutAll() { + for (val entry : MCChatUtils.ConnectedSenders.entrySet()) + for (val valueEntry : entry.getValue().entrySet()) + MCListener.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); + MCChatUtils.ConnectedSenders.clear(); + } } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java index e700b9a..cb476a2 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.mcchat; +import buttondevteam.core.ComponentManager; import buttondevteam.discordplugin.*; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; import buttondevteam.lib.TBMCSystemChatEvent; @@ -7,6 +8,7 @@ import buttondevteam.lib.chat.Channel; import io.netty.util.collection.LongObjectHashMap; import lombok.RequiredArgsConstructor; import lombok.experimental.var; +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; @@ -17,6 +19,7 @@ import java.util.HashMap; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.Stream; public class MCChatUtils { @@ -29,9 +32,36 @@ public class MCChatUtils { * May contain P<DiscordID> as key for public chat */ public static final HashMap> OnlineSenders = new HashMap<>(); - static LastMsgData lastmsgdata; + static @Nullable LastMsgData lastmsgdata; static LongObjectHashMap lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks + public static void updatePlayerList() { + if (notEnabled()) return; + DPUtils.performNoWait(() -> { + if (lastmsgdata != null) + updatePL(lastmsgdata); + MCChatCustom.lastmsgCustom.forEach(MCChatUtils::updatePL); + }); + } + + private static boolean notEnabled() { + return !ComponentManager.isEnabled(MinecraftChatModule.class); + } + + private static void updatePL(LastMsgData lmd) { + String topic = lmd.channel.getTopic(); + if (topic.length() == 0) + topic = ".\n----\nMinecraft chat\n----\n."; + String[] s = topic.split("\\n----\\n"); + if (s.length < 3) + return; + s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "") + + " online"; + s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream() + .map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", ")); + lmd.channel.changeTopic(String.join("\n----\n", s)); + } + public static T addSender(HashMap> senders, IUser user, T sender) { return addSender(senders, user.getStringID(), sender); @@ -64,6 +94,7 @@ public class MCChatUtils { } public static void forAllMCChat(Consumer action) { + if (notEnabled()) return; action.accept(DiscordPlugin.chatchannel); for (LastMsgData data : MCChatPrivate.lastmsgPerUser) action.accept(data.channel); @@ -78,6 +109,7 @@ public class MCChatUtils { * @param hookmsg Whether the message is also sent from the hook */ public static void forCustomAndAllMCChat(Consumer action, @Nullable ChannelconBroadcast toggle, boolean hookmsg) { + if (notEnabled()) return; if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg) forAllMCChat(action); final Consumer customLMDConsumer = cc -> action.accept(cc.channel); @@ -95,6 +127,7 @@ public class MCChatUtils { * @param toggle The toggle to check or null to send to all allowed */ public static void forAllowedCustomMCChat(Consumer action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle) { + if (notEnabled()) return; MCChatCustom.lastmsgCustom.stream().filter(clmd -> { //new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple if (toggle != null && (clmd.toggles & toggle.flag) == 0) @@ -114,6 +147,7 @@ public class MCChatUtils { * @param hookmsg Whether the message is also sent from the hook */ public static void forAllowedCustomAndAllMCChat(Consumer action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) { + if (notEnabled()) return; if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg) forAllMCChat(action); forAllowedCustomMCChat(action, sender, toggle); @@ -124,6 +158,7 @@ public class MCChatUtils { } public static void forAllowedMCChat(Consumer action, TBMCSystemChatEvent event) { + if (notEnabled()) return; if (event.getChannel().isGlobal()) action.accept(DiscordPlugin.chatchannel); for (LastMsgData data : MCChatPrivate.lastmsgPerUser) @@ -156,6 +191,7 @@ public class MCChatUtils { * @param channel The channel to reset in - the process is slightly different for the public, private and custom chats */ public static void resetLastMessage(IChannel channel) { + if (notEnabled()) return; if (channel.getLongID() == DiscordPlugin.chatchannel.getLongID()) { (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null) : lastmsgdata).message = null; diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java new file mode 100644 index 0000000..1824ef8 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java @@ -0,0 +1,184 @@ +package buttondevteam.discordplugin.mcchat; + +import buttondevteam.discordplugin.*; +import buttondevteam.discordplugin.commands.ConnectCommand; +import buttondevteam.lib.TBMCSystemChatEvent; +import buttondevteam.lib.player.TBMCPlayerJoinEvent; +import buttondevteam.lib.player.TBMCPlayerQuitEvent; +import buttondevteam.lib.player.TBMCYEEHAWEvent; +import lombok.val; +import net.ess3.api.events.AfkStatusChangeEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.*; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.BroadcastMessageEvent; +import org.bukkit.plugin.AuthorNagException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; +import sx.blah.discord.handle.obj.IUser; + +import java.util.Arrays; +import java.util.logging.Level; + +class MCListener implements Listener { + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerLogin(PlayerLoginEvent e) { + if (e.getResult() != Result.ALLOWED) + return; + MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders + .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() + .ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(TBMCPlayerJoinEvent e) { + if (e.getPlayer() instanceof DiscordConnectedPlayer) + return; // Don't show the joined message for the fake player + Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { + final Player p = e.getPlayer(); + DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); + if (dp != null) { + val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); + MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(), + new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); + MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(), + new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel + } + if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { + IUser user = DiscordPlugin.dc + .getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get()))); + p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator() + + " do /discord accept"); + p.sendMessage("§bIf it wasn't you, do /discord decline"); + } + final String message = e.GetPlayer().PlayerName().get() + " joined the game"; + MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true); + MCChatListener.ListC = 0; + ChromaBot.getInstance().updatePlayerList(); + }); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerLeave(TBMCPlayerQuitEvent e) { + if (e.getPlayer() instanceof DiscordConnectedPlayer) + return; // Only care about real users + MCChatUtils.OnlineSenders.entrySet() + .removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId()))); + Bukkit.getScheduler().runTask(DiscordPlugin.plugin, + () -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) + .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() + .ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); + Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, + ChromaBot.getInstance()::updatePlayerList, 5); + final String message = e.GetPlayer().PlayerName().get() + " left the game"; + MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerKick(PlayerKickEvent e) { + /*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting") + && !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special + MCChatListener.forAllowedCustomAndAllMCChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook*/ + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerDeath(PlayerDeathEvent e) { + MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true); + } + + @EventHandler + public void onPlayerAFK(AfkStatusChangeEvent e) { + final Player base = e.getAffected().getBase(); + if (e.isCancelled() || !base.isOnline()) + return; + final String msg = base.getDisplayName() + + " is " + (e.getValue() ? "now" : "no longer") + " AFK."; + MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false); + } + + @EventHandler + public void onChatSystemMessage(TBMCSystemChatEvent event) { + MCChatUtils.forAllowedMCChat(MCChatUtils.send(event.getMessage()), event); + } + + @EventHandler + public void onBroadcastMessage(BroadcastMessageEvent event) { + MCChatUtils.forCustomAndAllMCChat(MCChatUtils.send(event.getMessage()), ChannelconBroadcast.BROADCAST, false); + } + + @EventHandler + public void onYEEHAW(TBMCYEEHAWEvent event) { //TODO: Inherit from the chat event base to have channel support + String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName() + : event.getSender().getName(); + //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO + MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s")); + } + + private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises"}; + + static void callEventExcludingSome(Event event) { + callEventExcluding(event, EXCLUDED_PLUGINS); + } + + /** + * 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. + */ + private 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/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 4c84bdf..12ddb78 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -10,6 +10,7 @@ public class MinecraftChatModule extends Component { MCChatListener mcchat = new MCChatListener(); DiscordPlugin.dc.getDispatcher().registerListener(mcchat); TBMCCoreAPI.RegisterEventsForExceptions(mcchat, getPlugin()); + TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), getPlugin()); } @Override