Cleanup, organizing (MCChatListener)

Removed all sysouts
Split MCChatListener into utils, private and custom (and the existing one)
Using fixed version of Discord4J (fixes issues with local testing)
This commit is contained in:
Norbi Peti 2018-12-17 21:33:55 +01:00
parent 38b45299c0
commit 1878a46041
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
17 changed files with 402 additions and 343 deletions

19
pom.xml
View file

@ -106,7 +106,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<branch>master</branch> <!-- Should be master if building ButtonCore locally -->
<branch>
master
</branch> <!-- Should be master if building ButtonCore locally - the CI will overwrite it (see below) -->
</properties>
<repositories>
@ -160,11 +162,16 @@
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.discord4j/Discord4J -->
<dependency>
<groupId>com.discord4j</groupId>
<artifactId>Discord4J</artifactId>
<version>2.10.1</version>
</dependency>
<!-- <dependency>
<groupId>com.discord4j</groupId>
<artifactId>Discord4J</artifactId>
<version>2.10.1</version>
</dependency> -->
<dependency>
<groupId>com.github.SizableShrimp</groupId>
<artifactId>Discord4J</artifactId>
<version>httprequestchange-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
<dependency>
<groupId>org.slf4j</groupId>

View file

@ -1,6 +1,6 @@
package buttondevteam.discordplugin;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatUtils;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -43,7 +43,7 @@ public class ChromaBot {
* The message to send, duh
*/
public void sendMessage(String message) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message));
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message));
}
/**
@ -55,7 +55,7 @@ public class ChromaBot {
* Custom fancy stuff, use {@link EmbedBuilder} to create one
*/
public void sendMessage(String message, EmbedObject embed) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed));
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed));
}
/**
@ -66,7 +66,7 @@ public class ChromaBot {
* @param toggle The toggle type for channelcon
*/
public void sendMessageCustomAsWell(String message, EmbedObject embed, @Nullable ChannelconBroadcast toggle) {
MCChatListener.forCustomAndAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed), toggle, false);
MCChatUtils.forCustomAndAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed), toggle, false);
}
/**
@ -92,7 +92,7 @@ public class ChromaBot {
* The color of the line before the text
*/
public void sendMessage(String message, Color color) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
new EmbedBuilder().withTitle(message).withColor(color).build()));
}
@ -107,7 +107,7 @@ public class ChromaBot {
* The name of the Minecraft player who is the author of this message
*/
public void sendMessage(String message, Color color, String mcauthor) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
DPUtils.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), mcauthor).build()));
}
@ -124,7 +124,7 @@ public class ChromaBot {
* The URL of the avatar image for this message's author
*/
public void sendMessage(String message, Color color, String authorname, String authorimg) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, new EmbedBuilder()
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, new EmbedBuilder()
.withTitle(message).withColor(color).withAuthorName(authorname).withAuthorIcon(authorimg).build()));
}
@ -139,7 +139,7 @@ public class ChromaBot {
* The player who sends this message
*/
public void sendMessage(String message, Color color, Player sender) {
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, DPUtils
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, DPUtils
.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), sender.getName()).build()));
}

View file

@ -9,6 +9,7 @@ import sx.blah.discord.util.RequestBuffer.IVoidRequest;
import javax.annotation.Nullable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
public final class DPUtils {
@ -96,4 +97,10 @@ public final class DPUtils {
return message.replaceAll("([*_~])", Matcher.quoteReplacement("\\")+"$1");
}
public static Logger getLogger() {
if (DiscordPlugin.plugin == null || DiscordPlugin.plugin.getLogger() == null)
return Logger.getLogger("DiscordPlugin");
return DiscordPlugin.plugin.getLogger();
}
}

View file

@ -1,6 +1,6 @@
package buttondevteam.discordplugin;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.UserClass;
@ -20,9 +20,9 @@ public class DiscordPlayer extends ChromaGamerBase {
/**
* Returns true if player has the private Minecraft chat enabled. For setting the value, see
* {@link MCChatListener#privateMCChat(sx.blah.discord.handle.obj.IChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)}
* {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.IChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)}
*/
public boolean isMinecraftChatEnabled() {
return MCChatListener.isMinecraftChatEnabled(this);
return MCChatPrivate.isMinecraftChatEnabled(this);
}
}

View file

@ -4,8 +4,10 @@ import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.discordplugin.listeners.CommonListeners;
import buttondevteam.discordplugin.listeners.ExceptionListener;
import buttondevteam.discordplugin.listeners.MCChatListener;
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.mccommands.DiscordMCCommandBase;
import buttondevteam.discordplugin.mccommands.ResetMCCommand;
@ -149,7 +151,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
val toggles = chcon.getInt("toggles");
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
continue;
MCChatListener.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
}
}
@ -213,12 +215,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
ChromaGamerBase.addConverter(sender -> {
//System.out.println("Discord converter queried: "+sender+" "+sender.getName()); - TODO: Remove
//System.out.println(((DiscordSenderBase) sender).getChromaUser().channel().get().ID); //TODO: TMP
return Optional.ofNullable(sender instanceof DiscordSenderBase
? ((DiscordSenderBase) sender).getChromaUser() : null);
});
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
? ((DiscordSenderBase) sender).getChromaUser() : null));
new Thread(this::AnnouncementGetterThreadMethod).start();
setupProviders();
} catch (Exception e) {
@ -242,15 +240,15 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
@Override
public void onDisable() {
stop = true;
for (val entry : MCChatListener.ConnectedSenders.entrySet())
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
for (val valueEntry : entry.getValue().entrySet())
MCListener.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), ""));
MCChatListener.ConnectedSenders.clear();
MCChatUtils.ConnectedSenders.clear();
getConfig().set("lastannouncementtime", lastannouncementtime);
getConfig().set("lastseentime", lastseentime);
getConfig().set("serverup", false);
val chcons = MCChatListener.getCustomChats();
val chcons = MCChatCustom.getCustomChats();
val chconsc = getConfig().createSection("chcons");
for (val chcon : chcons) {
val chconc = chconsc.createSection(chcon.channel.getStringID());
@ -279,7 +277,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
+ "kicked the hell out.") //TODO: Make configurable
: "") //If 'restart' is disabled then this isn't shown even if joinleave is enabled
.build();
MCChatListener.forCustomAndAllMCChat(ch -> {
MCChatUtils.forCustomAndAllMCChat(ch -> {
try {
DiscordPlugin.sendMessageToChannelWait(ch, "",
embed, 5, TimeUnit.SECONDS);
@ -406,7 +404,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
}
try {
MCChatListener.resetLastMessage(channel); // If this is a chat message, it'll be set again
MCChatUtils.resetLastMessage(channel); // If this is a chat message, it'll be set again
final String content = message;
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
: channel.sendMessage(content, embed, false);

View file

@ -1,5 +1,6 @@
package buttondevteam.discordplugin.broadcaster;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import lombok.Getter;
@ -23,9 +24,9 @@ public class GeneralEventBroadcasterModule extends Component {
protected void disable() {
try {
if (PlayerListWatcher.hookDown())
System.out.println("Finished unhooking the player list!");
DPUtils.getLogger().info("Finished unhooking the player list!");
else
System.out.println("Didn't have the player list hooked.");
DPUtils.getLogger().info("Didn't have the player list hooked.");
hooked = false;
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while hacking the player list!", e);

View file

@ -1,6 +1,6 @@
package buttondevteam.discordplugin.broadcaster;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatUtils;
import buttondevteam.lib.TBMCCoreAPI;
import com.mojang.authlib.GameProfile;
import lombok.val;
@ -30,7 +30,7 @@ public class PlayerListWatcher extends DedicatedPlayerList {
if (packet instanceof PacketPlayOutChat) {
Field msgf = PacketPlayOutChat.class.getDeclaredField("a");
msgf.setAccessible(true);
MCChatListener.forAllMCChat(MCChatListener.send(((IChatBaseComponent) msgf.get(packet)).toPlainText()));
MCChatUtils.forAllMCChat(MCChatUtils.send(((IChatBaseComponent) msgf.get(packet)).toPlainText()));
}
} catch (Exception e) {
TBMCCoreAPI.SendException("Failed to broadcast message sent to all players - hacking failed.", e);

View file

@ -3,7 +3,7 @@ package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.ChannelconBroadcast;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatCustom;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.player.TBMCPlayer;
import lombok.val;
@ -30,16 +30,16 @@ public class ChannelconCommand extends DiscordCommandBase {
message.reply("you need to have manage permissions for this channel!");
return true;
}
if (MCChatListener.hasCustomChat(message.getChannel())) {
if (MCChatCustom.hasCustomChat(message.getChannel())) {
if (args.toLowerCase().startsWith("remove")) {
if (MCChatListener.removeCustomChat(message.getChannel()))
if (MCChatCustom.removeCustomChat(message.getChannel()))
message.reply("channel connection removed.");
else
message.reply("wait what, couldn't remove channel connection.");
return true;
}
if (args.toLowerCase().startsWith("toggle")) {
val cc = MCChatListener.getCustomChat(message.getChannel());
val cc = MCChatCustom.getCustomChat(message.getChannel());
Supplier<String> togglesString = () -> Arrays.stream(ChannelconBroadcast.values()).map(t -> t.toString().toLowerCase() + ": " + ((cc.toggles & t.flag) == 0 ? "disabled" : "enabled")).collect(Collectors.joining("\n"));
String[] argsa = args.split(" ");
if (argsa.length < 2) {
@ -88,7 +88,7 @@ public class ChannelconCommand extends DiscordCommandBase {
message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm.");
return true;
}*/ //TODO: "Channel admins" that can connect channels?
MCChatListener.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0);
MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0);
message.reply("alright, connection made to group `" + groupid + "`!");
return true;
}

View file

@ -2,7 +2,7 @@ package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.handle.obj.IMessage;
@ -22,7 +22,7 @@ public class MCChatCommand extends DiscordCommandBase {
}
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
boolean mcchat = !user.isMinecraftChatEnabled();
MCChatListener.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Minecraft chat " + (mcchat //
? "enabled. Use '/mcchat' again to turn it off." //

View file

@ -1,7 +1,10 @@
package buttondevteam.discordplugin.listeners;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.discordplugin.mcchat.MCChatCustom;
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
import buttondevteam.lib.TBMCCoreAPI;
import lombok.val;
import org.bukkit.Bukkit;
@ -72,7 +75,7 @@ public class CommonListeners {
return;
final IChannel channel = event.getMessage().getChannel();
if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID())
&& (!event.getMessage().getContent().contains("channelcon") || MCChatListener.hasCustomChat(channel))) //Allow channelcon in other servers but avoid double handling when it's enabled
&& (!event.getMessage().getContent().contains("channelcon") || MCChatCustom.hasCustomChat(channel))) //Allow channelcon in other servers but avoid double handling when it's enabled
return;
if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID()))
return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel
@ -98,7 +101,7 @@ public class CommonListeners {
&& !(event.getMessage().getContent().startsWith("/")
&& event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
return;
if (MCChatListener.isMinecraftChatEnabled(event.getAuthor().toString()))
if (MCChatPrivate.isMinecraftChatEnabled(event.getAuthor().toString()))
if (!event.getMessage().getContent().equalsIgnoreCase("mcchat"))
return;
if (event.getMessage().getAuthor().isBot())
@ -201,7 +204,7 @@ public class CommonListeners {
public static void debug(String debug) {
if (CommonListeners.debug) //Debug
System.out.println(debug);
DPUtils.getLogger().info(debug);
}
public static boolean debug() {

View file

@ -2,6 +2,8 @@ package buttondevteam.discordplugin.listeners;
import buttondevteam.discordplugin.*;
import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.discordplugin.mcchat.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatUtils;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.player.*;
@ -36,7 +38,7 @@ public class MCListener implements Listener {
public void onPlayerLogin(PlayerLoginEvent e) {
if (e.getResult() != Result.ALLOWED)
return;
MCChatListener.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
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, "")));
}
@ -50,9 +52,9 @@ public class MCListener implements Listener {
DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class);
if (dp != null) {
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
}
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
@ -63,8 +65,7 @@ public class MCListener implements Listener {
p.sendMessage("§bIf it wasn't you, do /discord decline");
}
final String message = e.GetPlayer().PlayerName().get() + " joined the game";
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
//System.out.println("Does this appear more than once?"); //No
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
MCChatListener.ListC = 0;
ChromaBot.getInstance().updatePlayerList();
});
@ -74,16 +75,16 @@ public class MCListener implements Listener {
public void onPlayerLeave(TBMCPlayerQuitEvent e) {
if (e.getPlayer() instanceof DiscordConnectedPlayer)
return; // Only care about real users
MCChatListener.OnlineSenders.entrySet()
MCChatUtils.OnlineSenders.entrySet()
.removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
() -> MCChatListener.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
() -> 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";
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
}
@EventHandler(priority = EventPriority.HIGHEST)
@ -109,7 +110,7 @@ public class MCListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerDeath(PlayerDeathEvent e) {
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true);
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true);
}
@EventHandler
@ -119,7 +120,7 @@ public class MCListener implements Listener {
return;
final String msg = base.getDisplayName()
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(msg), base, ChannelconBroadcast.AFK, false);
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
}
@EventHandler
@ -151,12 +152,12 @@ public class MCListener implements Listener {
@EventHandler
public void onChatSystemMessage(TBMCSystemChatEvent event) {
MCChatListener.forAllowedMCChat(MCChatListener.send(event.getMessage()), event);
MCChatUtils.forAllowedMCChat(MCChatUtils.send(event.getMessage()), event);
}
@EventHandler
public void onBroadcastMessage(BroadcastMessageEvent event) {
MCChatListener.forCustomAndAllMCChat(MCChatListener.send(event.getMessage()), ChannelconBroadcast.BROADCAST, false);
MCChatUtils.forCustomAndAllMCChat(MCChatUtils.send(event.getMessage()), ChannelconBroadcast.BROADCAST, false);
}
@EventHandler
@ -164,7 +165,7 @@ public class MCListener implements Listener {
String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName()
: event.getSender().getName();
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
MCChatListener.forAllMCChat(MCChatListener.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
}
private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises"};

View file

@ -0,0 +1,59 @@
package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.lib.chat.Channel;
import lombok.NonNull;
import lombok.val;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MCChatCustom {
/**
* Used for town or nation chats or anything else
*/
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
lastmsgCustom.add(lmd);
}
public static boolean hasCustomChat(IChannel channel) {
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
@Nullable
public static CustomLMD getCustomChat(IChannel channel) {
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
}
public static boolean removeCustomChat(IChannel channel) {
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static List<CustomLMD> getCustomChats() {
return Collections.unmodifiableList(lastmsgCustom);
}
public static class CustomLMD extends MCChatUtils.LastMsgData {
public final String groupID;
public final Channel mcchannel;
public final DiscordConnectedPlayer dcp;
public int toggles;
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
super(channel, user);
groupID = groupid;
this.mcchannel = mcchannel;
this.dcp = dcp;
this.toggles = toggles;
}
}
}

View file

@ -1,57 +1,47 @@
package buttondevteam.discordplugin.listeners;
package buttondevteam.discordplugin.mcchat;
import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.*;
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.DiscordSender;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.listeners.CommonListeners;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatPreprocessEvent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayer;
import com.vdurmont.emoji.EmojiParser;
import io.netty.util.collection.LongObjectHashMap;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.var;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitTask;
import sx.blah.discord.api.events.IListener;
import sx.blah.discord.api.internal.json.objects.EmbedObject;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IPrivateChannel;
import sx.blah.discord.handle.obj.IUser;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.EmbedBuilder;
import sx.blah.discord.util.MissingPermissionsException;
import javax.annotation.Nullable;
import java.awt.*;
import java.time.Instant;
import java.util.List;
import java.util.*;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MCChatListener implements Listener, IListener<MessageReceivedEvent> {
private BukkitTask sendtask;
@ -105,7 +95,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
// embed.withFooterText(e.getChannel().DisplayName);
embed.withTimestamp(time);
final long nanoTime = System.nanoTime();
InterruptibleConsumer<LastMsgData> doit = lastmsgdata -> {
InterruptibleConsumer<MCChatUtils.LastMsgData> doit = lastmsgdata -> {
final EmbedObject embedObject = embed.build();
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
@ -120,7 +110,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
try {
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
+ embedObject.description;// The message object doesn't get updated
final LastMsgData _lastmsgdata = lastmsgdata;
final MCChatUtils.LastMsgData _lastmsgdata = lastmsgdata;
DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject));
} catch (MissingPermissionsException | DiscordException e1) {
TBMCCoreAPI.SendException("An error occurred while editing chat message!", e1);
@ -133,17 +123,17 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
if (e.getChannel().isGlobal()
&& (e.isFromcmd() || isdifferentchannel.test(DiscordPlugin.chatchannel)))
doit.accept(lastmsgdata == null
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
: lastmsgdata);
doit.accept(MCChatUtils.lastmsgdata == null
? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(DiscordPlugin.chatchannel, null)
: MCChatUtils.lastmsgdata);
for (LastMsgData data : lastmsgPerUser) {
for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) {
if ((e.isFromcmd() || isdifferentchannel.test(data.channel))
&& e.shouldSendTo(getSender(data.channel, data.user)))
&& e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user)))
doit.accept(data);
}
val iterator = lastmsgCustom.iterator();
val iterator = MCChatCustom.lastmsgCustom.iterator();
while (iterator.hasNext()) {
val lmd = iterator.next();
if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
@ -165,32 +155,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
}
@RequiredArgsConstructor
public static class LastMsgData {
public IMessage message;
public long time;
public String content;
public final IChannel channel;
public Channel mcchannel;
public final IUser user;
}
public static class CustomLMD extends LastMsgData {
public final String groupID;
public final Channel mcchannel;
public final DiscordConnectedPlayer dcp;
public int toggles;
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
super(channel, user);
groupID = groupid;
this.mcchannel = mcchannel;
this.dcp = dcp;
this.toggles = toggles;
}
}
@EventHandler
public void onChatPreprocess(TBMCChatPreprocessEvent event) {
int start = -1;
@ -214,72 +178,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw", "lenny", "rp", "plugins"};
private static LastMsgData lastmsgdata;
private static short lastlist = 0;
private static short lastlistp = 0;
/**
* Used for messages in PMs (mcchat).
*/
private static ArrayList<LastMsgData> lastmsgPerUser = new ArrayList<LastMsgData>();
/**
* Used for town or nation chats or anything else
*/
private static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
private static LongObjectHashMap<IMessage> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
val p = Bukkit.getPlayer(mcp.getUUID());
val op = Bukkit.getOfflinePlayer(mcp.getUUID());
if (start) {
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
addSender(ConnectedSenders, user, sender);
if (p == null)// Player is offline - If the player is online, that takes precedence
MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, ""));
} else {
val sender = removeSender(ConnectedSenders, channel, user);
if (p == null)// Player is offline - If the player is online, that takes precedence
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
}
}
if (!start)
lastmsgfromd.remove(channel.getLongID());
return start //
? lastmsgPerUser.add(new LastMsgData(channel, user)) // Doesn't support group DMs
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
IUser user, T sender) {
return addSender(senders, user.getStringID(), sender);
}
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
String did, T sender) {
var map = senders.get(did);
if (map == null)
map = new HashMap<>();
map.put(sender.getChannel(), sender);
senders.put(did, map);
return sender;
}
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<IChannel, T>> senders,
IChannel channel, IUser user) {
var map = senders.get(user.getStringID());
if (map != null)
return map.get(channel);
return null;
}
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<IChannel, T>> senders,
IChannel channel, IUser user) {
var map = senders.get(user.getStringID());
if (map != null)
return map.remove(channel);
return null;
}
// ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
// Offline public chat......x............................................
@ -292,143 +192,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
// If online and disabling private chat, don't logout
// The maps may not contain the senders for UnconnectedSenders
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
return isMinecraftChatEnabled(dp.getDiscordID());
}
public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this
return lastmsgPerUser.stream()
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did));
}
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
lastmsgCustom.add(lmd);
}
public static boolean hasCustomChat(IChannel channel) {
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
@Nullable
public static CustomLMD getCustomChat(IChannel channel) {
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
}
public static boolean removeCustomChat(IChannel channel) {
lastmsgfromd.remove(channel.getLongID());
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static List<CustomLMD> getCustomChats() {
return Collections.unmodifiableList(lastmsgCustom);
}
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<IChannel, DiscordSender>> UnconnectedSenders = new HashMap<>();
public static final HashMap<String, HashMap<IChannel, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<IChannel, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
public static short ListC = 0;
/**
* Resets the last message, so it will start a new one instead of appending to it.
* This is used when someone (even the bot) sends a message to the channel.
*
* @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 (channel.getLongID() == DiscordPlugin.chatchannel.getLongID()) {
(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
: lastmsgdata).message = null;
return;
} // Don't set the whole object to null, the player and channel information should be preserved
for (LastMsgData data : channel.isPrivate() ? lastmsgPerUser : lastmsgCustom) {
if (data.channel.getLongID() == channel.getLongID()) {
data.message = null;
return;
}
}
//If it gets here, it's sending a message to a non-chat channel
}
public static void forAllMCChat(Consumer<IChannel> action) {
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : lastmsgPerUser)
action.accept(data.channel);
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat
}
/**
* For custom and all MC chat
*
* @param action The action to act
* @param toggle The toggle to check
* @param hookmsg Whether the message is also sent from the hook
*/
public static void forCustomAndAllMCChat(Consumer<IChannel> action, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
forAllMCChat(action);
final Consumer<CustomLMD> customLMDConsumer = cc -> action.accept(cc.channel);
if (toggle == null)
lastmsgCustom.forEach(customLMDConsumer);
else
lastmsgCustom.stream().filter(cc -> (cc.toggles & toggle.flag) != 0).forEach(customLMDConsumer);
}
/**
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
*
* @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed
*/
public static void forAllowedCustomMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle) {
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)
return false; //If null then allow
if (sender == null)
return true;
return clmd.groupID.equals(clmd.mcchannel.getGroupID(sender));
}).forEach(cc -> action.accept(cc.channel)); //TODO: Send error messages on channel connect
}
/**
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
*
* @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed
* @param hookmsg Whether the message is also sent from the hook
*/
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
forAllMCChat(action);
forAllowedCustomMCChat(action, sender, toggle);
}
public static Consumer<IChannel> send(String message) {
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
}
public static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
if (event.getChannel().isGlobal())
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : lastmsgPerUser)
if (event.shouldSendTo(getSender(data.channel, data.user)))
action.accept(data.channel);
lastmsgCustom.stream().filter(clmd -> {
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
return false;
return event.shouldSendTo(clmd.dcp);
}).map(clmd -> clmd.channel).forEach(action);
}
/**
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
*
@ -448,13 +213,13 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
if (wait)
recthread.join(5000);
}
lastmsgdata = null;
lastmsgPerUser.clear();
lastmsgCustom.clear();
lastmsgfromd.clear();
ConnectedSenders.clear();
MCChatUtils.lastmsgdata = null;
MCChatPrivate.lastmsgPerUser.clear();
MCChatCustom.lastmsgCustom.clear();
MCChatUtils.lastmsgfromd.clear();
MCChatUtils.ConnectedSenders.clear();
lastlist = lastlistp = ListC = 0;
UnconnectedSenders.clear();
MCChatUtils.UnconnectedSenders.clear();
recthread = sendthread = null;
} catch (InterruptedException e) {
e.printStackTrace(); //This thread shouldn't be interrupted
@ -473,16 +238,16 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
val author = ev.getMessage().getAuthor();
if (author.isBot())
return;
final boolean hasCustomChat = hasCustomChat(ev.getChannel());
final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getChannel());
if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID())
&& !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))
&& !(ev.getMessage().getChannel().isPrivate() && MCChatPrivate.isMinecraftChatEnabled(author.getStringID()))
&& !hasCustomChat)
return;
if (ev.getMessage().getContent().equalsIgnoreCase("mcchat"))
return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommonListeners)
if (CommonListeners.runCommand(ev.getMessage(), true))
return;
resetLastMessage(ev.getChannel());
MCChatUtils.resetLastMessage(ev.getChannel());
lastlist++;
recevents.add(ev);
if (rectask != null)
@ -508,7 +273,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
val sender = event.getMessage().getAuthor();
String dmessage = event.getMessage().getContent();
try {
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender);
final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender);
val user = dsender.getChromaUser();
for (IUser u : event.getMessage().getMentions()) {
@ -528,7 +293,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
.getAttachments().stream().map(IMessage.Attachment::getUrl).collect(Collectors.joining("\n"))
: "");
CustomLMD clmd = getCustomChat(event.getChannel());
MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel());
boolean react = false;
@ -573,18 +338,13 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
() -> { //TODO: Better handling...
val channel = user.channel();
val chtmp = channel.get();
//System.out.println("1: "+chtmp.ID);
//System.out.println("clmd: "+clmd);
if (clmd != null) {
channel.set(clmd.mcchannel); //Hack to send command in the channel
//System.out.println("clmd chan: "+clmd.mcchannel.ID);
} //TODO: Permcheck isn't implemented for commands
//System.out.println("2: "+channel.get().ID);
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
if (clmd != null)
channel.set(chtmp);
//System.out.println("3: "+channel.get().ID); - TODO: Remove
});
else {
Channel chc = ch.get();
@ -638,7 +398,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
if (react) {
try {
val lmfd = lastmsgfromd.get(event.getChannel().getLongID());
val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getLongID());
if (lmfd != null) {
DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getOurUser(),
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
@ -646,7 +406,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
}
lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
MCChatUtils.lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
}
} catch (Exception e) {
@ -654,19 +414,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
}
/**
* 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 static DiscordSenderBase getSender(IChannel channel, final IUser author) {
//noinspection OptionalGetWithoutIsPresent
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), //
() -> Optional.of(addSender(UnconnectedSenders, author,
new DiscordSender(author, channel)))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
}
@FunctionalInterface
private interface InterruptibleConsumer<T> {
void accept(T value) throws TimeoutException, InterruptedException;

View file

@ -0,0 +1,55 @@
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;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IPrivateChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.ArrayList;
public class MCChatPrivate {
/**
* Used for messages in PMs (mcchat).
*/
static ArrayList<MCChatUtils.LastMsgData> lastmsgPerUser = new ArrayList<>();
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
val p = Bukkit.getPlayer(mcp.getUUID());
val op = Bukkit.getOfflinePlayer(mcp.getUUID());
if (start) {
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender);
if (p == null)// Player is offline - If the player is online, that takes precedence
MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, ""));
} else {
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel, user);
if (p == null)// Player is offline - If the player is online, that takes precedence
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
}
}
if (!start)
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
return start //
? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
return isMinecraftChatEnabled(dp.getDiscordID());
}
public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this
return lastmsgPerUser.stream()
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did));
}
}

View file

@ -0,0 +1,182 @@
package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.*;
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Channel;
import io.netty.util.collection.LongObjectHashMap;
import lombok.RequiredArgsConstructor;
import lombok.experimental.var;
import org.bukkit.command.CommandSender;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IUser;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class MCChatUtils {
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<IChannel, DiscordSender>> UnconnectedSenders = new HashMap<>();
public static final HashMap<String, HashMap<IChannel, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<IChannel, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
static LastMsgData lastmsgdata;
static LongObjectHashMap<IMessage> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
IUser user, T sender) {
return addSender(senders, user.getStringID(), sender);
}
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
String did, T sender) {
var map = senders.get(did);
if (map == null)
map = new HashMap<>();
map.put(sender.getChannel(), sender);
senders.put(did, map);
return sender;
}
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<IChannel, T>> senders,
IChannel channel, IUser user) {
var map = senders.get(user.getStringID());
if (map != null)
return map.get(channel);
return null;
}
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<IChannel, T>> senders,
IChannel channel, IUser user) {
var map = senders.get(user.getStringID());
if (map != null)
return map.remove(channel);
return null;
}
public static void forAllMCChat(Consumer<IChannel> action) {
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : MCChatPrivate.lastmsgPerUser)
action.accept(data.channel);
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat
}
/**
* For custom and all MC chat
*
* @param action The action to act
* @param toggle The toggle to check
* @param hookmsg Whether the message is also sent from the hook
*/
public static void forCustomAndAllMCChat(Consumer<IChannel> action, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
forAllMCChat(action);
final Consumer<MCChatCustom.CustomLMD> customLMDConsumer = cc -> action.accept(cc.channel);
if (toggle == null)
MCChatCustom.lastmsgCustom.forEach(customLMDConsumer);
else
MCChatCustom.lastmsgCustom.stream().filter(cc -> (cc.toggles & toggle.flag) != 0).forEach(customLMDConsumer);
}
/**
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
*
* @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed
*/
public static void forAllowedCustomMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle) {
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)
return false; //If null then allow
if (sender == null)
return true;
return clmd.groupID.equals(clmd.mcchannel.getGroupID(sender));
}).forEach(cc -> action.accept(cc.channel)); //TODO: Send error messages on channel connect
}
/**
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
*
* @param action The action to do
* @param sender The sender to check perms of or null to send to all that has it toggled
* @param toggle The toggle to check or null to send to all allowed
* @param hookmsg Whether the message is also sent from the hook
*/
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
forAllMCChat(action);
forAllowedCustomMCChat(action, sender, toggle);
}
public static Consumer<IChannel> send(String message) {
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
}
public static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
if (event.getChannel().isGlobal())
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : MCChatPrivate.lastmsgPerUser)
if (event.shouldSendTo(getSender(data.channel, data.user)))
action.accept(data.channel);
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
return false;
return event.shouldSendTo(clmd.dcp);
}).map(clmd -> clmd.channel).forEach(action);
}
/**
* This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc.
*/
static DiscordSenderBase getSender(IChannel channel, final IUser author) {
//noinspection OptionalGetWithoutIsPresent
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
() -> Optional.ofNullable(getSender(UnconnectedSenders, channel, author)), //
() -> Optional.of(addSender(UnconnectedSenders, author,
new DiscordSender(author, channel)))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
}
/**
* Resets the last message, so it will start a new one instead of appending to it.
* This is used when someone (even the bot) sends a message to the channel.
*
* @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 (channel.getLongID() == DiscordPlugin.chatchannel.getLongID()) {
(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
: lastmsgdata).message = null;
return;
} // Don't set the whole object to null, the player and channel information should be preserved
for (LastMsgData data : channel.isPrivate() ? MCChatPrivate.lastmsgPerUser : MCChatCustom.lastmsgCustom) {
if (data.channel.getLongID() == channel.getLongID()) {
data.message = null;
return;
}
}
//If it gets here, it's sending a message to a non-chat channel
}
@RequiredArgsConstructor
public static class LastMsgData {
public IMessage message;
public long time;
public String content;
public final IChannel channel;
public Channel mcchannel;
public final IUser user;
}
}

View file

@ -1,7 +1,6 @@
package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;

View file

@ -2,7 +2,7 @@ package buttondevteam.discordplugin.mccommands;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.discordplugin.mcchat.MCChatUtils;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
@ -35,7 +35,7 @@ public class AcceptMCCommand extends DiscordMCCommandBase {
dp.save();
mcp.save();
ConnectCommand.WaitingToConnect.remove(player.getName());
MCChatListener.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
MCChatUtils.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
player.sendMessage("§bAccounts connected.");
return true;
}