MCchat and other fixes
- Fixed disallowed command stopping message processing - Fixed failure sending a message to Discord stopping msg proc. - Added timestamps for messages showing when the message was sent - Fixed mentioning in mcchat (now it only detects it's own roles) - Fixed exception reporting (shouldn't break the code block, also only shows buttondevteam lines)
This commit is contained in:
parent
68e99e0000
commit
155311b019
4 changed files with 264 additions and 261 deletions
|
@ -324,8 +324,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) {
|
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) {
|
||||||
if (message.length() > 1900) {
|
if (message.length() > 1980) {
|
||||||
message = message.substring(0, 1900);
|
message = message.substring(0, 1980);
|
||||||
Bukkit.getLogger()
|
Bukkit.getLogger()
|
||||||
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
package buttondevteam.discordplugin.listeners;
|
package buttondevteam.discordplugin.listeners;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||||
|
@ -20,6 +14,12 @@ import sx.blah.discord.handle.obj.IMessage;
|
||||||
import sx.blah.discord.handle.obj.StatusType;
|
import sx.blah.discord.handle.obj.StatusType;
|
||||||
import sx.blah.discord.util.EmbedBuilder;
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class CommandListener {
|
public class CommandListener {
|
||||||
|
|
||||||
private static final String[] serverReadyStrings = new String[] { "In one week from now", // Ali
|
private static final String[] serverReadyStrings = new String[] { "In one week from now", // Ali
|
||||||
|
@ -126,7 +126,7 @@ public class CommandListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a ChromaBot command.
|
* Runs a ChromaBot command.
|
||||||
*
|
*
|
||||||
* @param message
|
* @param message
|
||||||
* The Discord message
|
* The Discord message
|
||||||
* @param mentionedonly
|
* @param mentionedonly
|
||||||
|
@ -141,7 +141,7 @@ public class CommandListener {
|
||||||
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
|
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
|
||||||
boolean gotmention = checkanddeletemention(cmdwithargs, mention, message);
|
boolean gotmention = checkanddeletemention(cmdwithargs, mention, message);
|
||||||
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
|
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
|
||||||
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().map(r -> r.mention())::iterator)
|
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(r -> r.mention())::iterator)
|
||||||
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
|
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
|
||||||
if (mentionedonly && !gotmention) {
|
if (mentionedonly && !gotmention) {
|
||||||
message.getChannel().setTypingStatus(false);
|
message.getChannel().setTypingStatus(false);
|
||||||
|
|
|
@ -1,68 +1,62 @@
|
||||||
package buttondevteam.discordplugin.listeners;
|
package buttondevteam.discordplugin.listeners;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.TBMCExceptionEvent;
|
||||||
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import sx.blah.discord.handle.obj.IRole;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import buttondevteam.lib.TBMCExceptionEvent;
|
|
||||||
import sx.blah.discord.handle.obj.IRole;
|
|
||||||
|
|
||||||
public class ExceptionListener implements Listener {
|
public class ExceptionListener implements Listener {
|
||||||
private List<Throwable> lastthrown = new ArrayList<>();
|
private List<Throwable> lastthrown = new ArrayList<>();
|
||||||
private List<String> lastsourcemsg = new ArrayList<>();
|
private List<String> lastsourcemsg = new ArrayList<>();
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onException(TBMCExceptionEvent e) {
|
public void onException(TBMCExceptionEvent e) {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode)
|
||||||
return;
|
return;
|
||||||
if (lastthrown.stream()
|
if (lastthrown.stream()
|
||||||
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
|
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
|
||||||
&& e.getException().getMessage() == null ? ex.getMessage() == null
|
&& e.getException().getMessage() == null ? ex.getMessage() == null
|
||||||
: e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message
|
: e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message
|
||||||
&& lastsourcemsg.contains(e.getSourceMessage()))
|
&& lastsourcemsg.contains(e.getSourceMessage()))
|
||||||
return;
|
return;
|
||||||
SendException(e.getException(), e.getSourceMessage());
|
SendException(e.getException(), e.getSourceMessage());
|
||||||
if (lastthrown.size() >= 10)
|
if (lastthrown.size() >= 10)
|
||||||
lastthrown.remove(0);
|
lastthrown.remove(0);
|
||||||
if (lastsourcemsg.size() >= 10)
|
if (lastsourcemsg.size() >= 10)
|
||||||
lastsourcemsg.remove(0);
|
lastsourcemsg.remove(0);
|
||||||
lastthrown.add(e.getException());
|
lastthrown.add(e.getException());
|
||||||
lastsourcemsg.add(e.getSourceMessage());
|
lastsourcemsg.add(e.getSourceMessage());
|
||||||
e.setHandled();
|
e.setHandled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRole coderRole;
|
private static IRole coderRole;
|
||||||
|
|
||||||
private static void SendException(Throwable e, String sourcemessage) {
|
private static void SendException(Throwable e, String sourcemessage) {
|
||||||
try {
|
try {
|
||||||
if (coderRole == null)
|
if (coderRole == null)
|
||||||
coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0);
|
coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0);
|
||||||
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
|
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
|
||||||
: new StringBuilder(coderRole.mention()).append("\n");
|
: new StringBuilder(coderRole.mention()).append("\n");
|
||||||
sb.append(sourcemessage).append("\n");
|
sb.append(sourcemessage).append("\n");
|
||||||
sb.append("```").append("\n");
|
sb.append("```").append("\n");
|
||||||
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
|
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
|
||||||
.filter(s -> !(s.contains("\tat ") && ( //
|
.filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam."))
|
||||||
s.contains("java.util") //
|
.collect(Collectors.joining("\n"));
|
||||||
|| s.contains("java.lang") //
|
if (stackTrace.length() > 1800)
|
||||||
|| s.contains("net.minecraft.server") //
|
stackTrace = stackTrace.substring(0, 1800);
|
||||||
|| s.contains("sun.reflect") //
|
sb.append(stackTrace).append("\n");
|
||||||
|| s.contains("org.bukkit") //
|
sb.append("```");
|
||||||
))).collect(Collectors.joining("\n"));
|
DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString());
|
||||||
if (stackTrace.length() > 1800)
|
} catch (Exception ex) {
|
||||||
stackTrace = stackTrace.substring(0, 1800);
|
ex.printStackTrace();
|
||||||
sb.append(stackTrace).append("\n");
|
}
|
||||||
sb.append("```");
|
}
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,8 @@ import sx.blah.discord.util.EmbedBuilder;
|
||||||
import sx.blah.discord.util.MissingPermissionsException;
|
import sx.blah.discord.util.MissingPermissionsException;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -45,91 +43,99 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
public class MCChatListener implements Listener, IListener<MessageReceivedEvent> {
|
public class MCChatListener implements Listener, IListener<MessageReceivedEvent> {
|
||||||
private BukkitTask sendtask;
|
private BukkitTask sendtask;
|
||||||
private LinkedBlockingQueue<TBMCChatEvent> sendevents = new LinkedBlockingQueue<>();
|
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
|
||||||
private Runnable sendrunnable;
|
private Runnable sendrunnable;
|
||||||
|
|
||||||
@EventHandler // Minecraft
|
@EventHandler // Minecraft
|
||||||
public void onMCChat(TBMCChatEvent ev) {
|
public void onMCChat(TBMCChatEvent ev) {
|
||||||
if (ev.isCancelled())
|
if (ev.isCancelled())
|
||||||
return;
|
return;
|
||||||
sendevents.add(ev);
|
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
||||||
if (sendtask != null)
|
if (sendtask != null)
|
||||||
return;
|
return;
|
||||||
sendrunnable = () -> {
|
sendrunnable = () -> {
|
||||||
try {
|
processMCToDiscord();
|
||||||
TBMCChatEvent e;
|
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||||
try {
|
|
||||||
e = sendevents.take(); // Wait until an element is available
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
sendtask.cancel();
|
|
||||||
sendtask = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " //
|
|
||||||
+ (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") //
|
|
||||||
+ (DPUtils.sanitizeString(e.getSender() instanceof Player //
|
|
||||||
? ((Player) e.getSender()).getDisplayName() //
|
|
||||||
: e.getSender().getName()));
|
|
||||||
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
|
||||||
.withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(),
|
|
||||||
e.getChannel().color.getGreen(), e.getChannel().color.getBlue()));
|
|
||||||
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "")
|
|
||||||
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false);
|
|
||||||
if (e.getSender() instanceof Player)
|
|
||||||
DPUtils.embedWithHead(
|
|
||||||
embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id="
|
|
||||||
+ ((Player) e.getSender()).getUniqueId()),
|
|
||||||
e.getSender().getName());
|
|
||||||
else if (e.getSender() instanceof DiscordSenderBase)
|
|
||||||
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL())
|
|
||||||
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id="
|
|
||||||
+ ((DiscordSenderBase) e.getSender()).getUser().getStringID()); // TODO: Constant/method to get URLs like this
|
|
||||||
// embed.withFooterText(e.getChannel().DisplayName);
|
|
||||||
final long nanoTime = System.nanoTime();
|
|
||||||
Consumer<LastMsgData> doit = lastmsgdata -> {
|
|
||||||
final EmbedObject embedObject = embed.build();
|
|
||||||
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
|
||||||
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
|
||||||
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|
|
||||||
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
|
|
||||||
lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, "",
|
|
||||||
embedObject); // TODO Use ChromaBot API
|
|
||||||
lastmsgdata.time = nanoTime;
|
|
||||||
lastmsgdata.mcchannel = e.getChannel();
|
|
||||||
lastmsgdata.content = embedObject.description;
|
|
||||||
} else
|
|
||||||
try {
|
|
||||||
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
|
|
||||||
+ embedObject.description;// The message object doesn't get updated
|
|
||||||
final LastMsgData _lastmsgdata = lastmsgdata;
|
|
||||||
DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject));
|
|
||||||
} catch (MissingPermissionsException | DiscordException e1) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while editing chat message!", e1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Checks if the given channel is different than where the message was sent from
|
|
||||||
Predicate<IChannel> isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase)
|
|
||||||
|| ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
|
|
||||||
|
|
||||||
if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp"))
|
|
||||||
&& isdifferentchannel.test(DiscordPlugin.chatchannel))
|
|
||||||
doit.accept(lastmsgdata == null
|
|
||||||
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null)
|
|
||||||
: lastmsgdata);
|
|
||||||
|
|
||||||
for (LastMsgData data : lastmsgPerUser) {
|
|
||||||
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
|
|
||||||
&& e.shouldSendTo(getSender(data.channel, data.user, data.dp)))
|
|
||||||
doit.accept(data);
|
|
||||||
}
|
|
||||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
TBMCCoreAPI.SendException("Error while sending mesasge to Discord!", ex);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processMCToDiscord() {
|
||||||
|
try {
|
||||||
|
TBMCChatEvent e;
|
||||||
|
Instant time;
|
||||||
|
try {
|
||||||
|
val se = sendevents.take(); // Wait until an element is available
|
||||||
|
e = se.getKey();
|
||||||
|
time = se.getValue();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
sendtask.cancel();
|
||||||
|
sendtask = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String authorPlayer = "[" + DPUtils.sanitizeString(e.getChannel().DisplayName) + "] " //
|
||||||
|
+ (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") //
|
||||||
|
+ (DPUtils.sanitizeString(e.getSender() instanceof Player //
|
||||||
|
? ((Player) e.getSender()).getDisplayName() //
|
||||||
|
: e.getSender().getName()));
|
||||||
|
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
||||||
|
.withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(),
|
||||||
|
e.getChannel().color.getGreen(), e.getChannel().color.getBlue()));
|
||||||
|
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "")
|
||||||
|
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false);
|
||||||
|
if (e.getSender() instanceof Player)
|
||||||
|
DPUtils.embedWithHead(
|
||||||
|
embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id="
|
||||||
|
+ ((Player) e.getSender()).getUniqueId()),
|
||||||
|
e.getSender().getName());
|
||||||
|
else if (e.getSender() instanceof DiscordSenderBase)
|
||||||
|
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL())
|
||||||
|
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id="
|
||||||
|
+ ((DiscordSenderBase) e.getSender()).getUser().getStringID()); // TODO: Constant/method to get URLs like this
|
||||||
|
// embed.withFooterText(e.getChannel().DisplayName);
|
||||||
|
embed.withTimestamp(time);
|
||||||
|
final long nanoTime = System.nanoTime();
|
||||||
|
Consumer<LastMsgData> doit = lastmsgdata -> {
|
||||||
|
final EmbedObject embedObject = embed.build();
|
||||||
|
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
||||||
|
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
||||||
|
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|
||||||
|
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
|
||||||
|
lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, "",
|
||||||
|
embedObject); // TODO Use ChromaBot API
|
||||||
|
lastmsgdata.time = nanoTime;
|
||||||
|
lastmsgdata.mcchannel = e.getChannel();
|
||||||
|
lastmsgdata.content = embedObject.description;
|
||||||
|
} else
|
||||||
|
try {
|
||||||
|
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
|
||||||
|
+ embedObject.description;// The message object doesn't get updated
|
||||||
|
final LastMsgData _lastmsgdata = lastmsgdata;
|
||||||
|
DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject));
|
||||||
|
} catch (MissingPermissionsException | DiscordException e1) {
|
||||||
|
TBMCCoreAPI.SendException("An error occurred while editing chat message!", e1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Checks if the given channel is different than where the message was sent from
|
||||||
|
Predicate<IChannel> isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase)
|
||||||
|
|| ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
|
||||||
|
|
||||||
|
if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp"))
|
||||||
|
&& isdifferentchannel.test(DiscordPlugin.chatchannel))
|
||||||
|
doit.accept(lastmsgdata == null
|
||||||
|
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null)
|
||||||
|
: lastmsgdata);
|
||||||
|
|
||||||
|
for (LastMsgData data : lastmsgPerUser) {
|
||||||
|
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
|
||||||
|
&& e.shouldSendTo(getSender(data.channel, data.user, data.dp)))
|
||||||
|
doit.accept(data);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
private static class LastMsgData {
|
private static class LastMsgData {
|
||||||
public IMessage message;
|
public IMessage message;
|
||||||
|
@ -265,6 +271,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
private BukkitTask rectask;
|
private BukkitTask rectask;
|
||||||
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
|
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
|
||||||
private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks
|
private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks
|
||||||
|
private Runnable recrun;
|
||||||
|
|
||||||
@Override // Discord
|
@Override // Discord
|
||||||
public void handle(MessageReceivedEvent ev) {
|
public void handle(MessageReceivedEvent ev) {
|
||||||
|
@ -288,133 +295,135 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
recevents.add(ev);
|
recevents.add(ev);
|
||||||
if (rectask != null)
|
if (rectask != null)
|
||||||
return;
|
return;
|
||||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
recrun = () -> { //Don't return in a while loop next time
|
||||||
while (true) {
|
processDiscordToMC();
|
||||||
@val
|
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing
|
||||||
sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent event;
|
};
|
||||||
try {
|
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing
|
||||||
event = recevents.take();
|
}
|
||||||
} catch (InterruptedException e1) {
|
|
||||||
rectask.cancel();
|
private void processDiscordToMC() {
|
||||||
|
@val
|
||||||
|
sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent event;
|
||||||
|
try {
|
||||||
|
event = recevents.take();
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
rectask.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
val sender = event.getMessage().getAuthor();
|
||||||
|
val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class);
|
||||||
|
String dmessage = event.getMessage().getContent();
|
||||||
|
try {
|
||||||
|
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user);
|
||||||
|
|
||||||
|
for (IUser u : event.getMessage().getMentions()) {
|
||||||
|
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
|
||||||
|
final String nick = u.getNicknameForGuild(DiscordPlugin.mainServer);
|
||||||
|
dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
BiConsumer<Channel, String> 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
|
||||||
|
DPUtils.perform(() -> {
|
||||||
|
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
||||||
|
event.getMessage().delete();
|
||||||
|
});
|
||||||
|
final String cmd = dmessage.substring(1).toLowerCase();
|
||||||
|
if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds)
|
||||||
|
.noneMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) {
|
||||||
|
// Command not whitelisted
|
||||||
|
dsender.sendMessage("Sorry, you can only access these commands:\n"
|
||||||
|
+ Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc)
|
||||||
|
.collect(Collectors.joining(", "))
|
||||||
|
+ (user.getConnectedID(TBMCPlayer.class) == null
|
||||||
|
? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in "
|
||||||
|
+ DiscordPlugin.botchannel.mention()
|
||||||
|
+ "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"
|
||||||
|
: "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
val sender = event.getMessage().getAuthor();
|
if (lastlist > 5) {
|
||||||
val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class);
|
ListC = 0;
|
||||||
String dmessage = event.getMessage().getContent();
|
lastlist = 0;
|
||||||
try {
|
}
|
||||||
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user);
|
if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
|
||||||
|
{
|
||||||
for (IUser u : event.getMessage().getMentions()) {
|
dsender.sendMessage("Stop it. You know the answer.");
|
||||||
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
|
lastlist = 0;
|
||||||
final String nick = u.getNicknameForGuild(DiscordPlugin.mainServer);
|
} else {
|
||||||
dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName()));
|
int spi = cmd.indexOf(' ');
|
||||||
}
|
final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi);
|
||||||
|
Optional<Channel> ch = Channel.getChannels().stream()
|
||||||
BiConsumer<Channel, String> sendChatMessage = (channel, msg) -> //
|
.filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny();
|
||||||
TBMCChatAPI.SendChatMessage(channel, dsender,
|
if (!ch.isPresent())
|
||||||
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
|
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
||||||
.getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n"))
|
() -> VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd));
|
||||||
: ""));
|
else {
|
||||||
|
Channel chc = ch.get();
|
||||||
boolean react = false;
|
if (!chc.ID.equals(Channel.GlobalChat.ID)
|
||||||
|
&& !event.getMessage().getChannel().isPrivate())
|
||||||
if (dmessage.startsWith("/")) { // Ingame command
|
dsender.sendMessage(
|
||||||
DPUtils.perform(() -> {
|
"You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels.");
|
||||||
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
|
||||||
event.getMessage().delete();
|
|
||||||
});
|
|
||||||
final String cmd = dmessage.substring(1).toLowerCase();
|
|
||||||
if (dsender instanceof DiscordSender && !Arrays.stream(UnconnectedCmds)
|
|
||||||
.anyMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) {
|
|
||||||
// Command not whitelisted
|
|
||||||
dsender.sendMessage("Sorry, you can only access these commands:\n"
|
|
||||||
+ Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc)
|
|
||||||
.collect(Collectors.joining(", "))
|
|
||||||
+ (user.getConnectedID(TBMCPlayer.class) == null
|
|
||||||
? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in "
|
|
||||||
+ DiscordPlugin.botchannel.mention()
|
|
||||||
+ "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"
|
|
||||||
: "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (lastlist > 5) {
|
|
||||||
ListC = 0;
|
|
||||||
lastlist = 0;
|
|
||||||
}
|
|
||||||
if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
|
|
||||||
{
|
|
||||||
dsender.sendMessage("Stop it. You know the answer.");
|
|
||||||
lastlist = 0;
|
|
||||||
} else {
|
|
||||||
int spi = cmd.indexOf(' ');
|
|
||||||
final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi);
|
|
||||||
Optional<Channel> ch = Channel.getChannels().stream()
|
|
||||||
.filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny();
|
|
||||||
if (!ch.isPresent())
|
|
||||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
|
||||||
() -> 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);
|
|
||||||
if (!oldch.ID.equals(chc.ID)) {
|
|
||||||
dsender.setMcchannel(chc);
|
|
||||||
if (chc instanceof ChatRoom)
|
|
||||||
((ChatRoom) chc).joinRoom(dsender);
|
|
||||||
} else
|
|
||||||
dsender.setMcchannel(Channel.GlobalChat);
|
|
||||||
dsender.sendMessage("You're now talking in: "
|
|
||||||
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
|
||||||
} else { // Send single message
|
|
||||||
sendChatMessage.accept(chc, cmd.substring(spi + 1));
|
|
||||||
react = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastlistp = (short) Bukkit.getOnlinePlayers().size();
|
|
||||||
} else {// Not a command
|
|
||||||
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
|
|
||||||
&& !event.getChannel().isPrivate())
|
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0,
|
|
||||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
|
||||||
: dsender.getName()) + " pinned a message on Discord.");
|
|
||||||
else {
|
else {
|
||||||
sendChatMessage.accept(dsender.getMcchannel(), dmessage);
|
if (spi == -1) // Switch channels
|
||||||
react = true;
|
{
|
||||||
}
|
val oldch = dsender.getMcchannel();
|
||||||
}
|
if (oldch instanceof ChatRoom)
|
||||||
if (react) {
|
((ChatRoom) oldch).leaveRoom(dsender);
|
||||||
try {
|
if (!oldch.ID.equals(chc.ID)) {
|
||||||
/*
|
dsender.setMcchannel(chc);
|
||||||
* System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription())
|
if (chc instanceof ChatRoom)
|
||||||
* .collect(Collectors.joining("\n")));
|
((ChatRoom) chc).joinRoom(dsender);
|
||||||
*/
|
} else
|
||||||
if (lastmsgfromd != null) {
|
dsender.setMcchannel(Channel.GlobalChat);
|
||||||
DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(),
|
dsender.sendMessage("You're now talking in: "
|
||||||
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
|
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
||||||
|
} else { // Send single message
|
||||||
|
sendChatMessage.accept(chc, cmd.substring(spi + 1));
|
||||||
|
react = true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
|
||||||
}
|
}
|
||||||
lastmsgfromd = event.getMessage();
|
|
||||||
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
lastlistp = (short) Bukkit.getOnlinePlayers().size();
|
||||||
return;
|
} else {// Not a command
|
||||||
|
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
|
||||||
|
&& !event.getChannel().isPrivate())
|
||||||
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0,
|
||||||
|
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||||
|
: dsender.getName()) + " pinned a message on Discord.");
|
||||||
|
else {
|
||||||
|
sendChatMessage.accept(dsender.getMcchannel(), dmessage);
|
||||||
|
react = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
if (react) {
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
* System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription())
|
||||||
|
* .collect(Collectors.joining("\n")));
|
||||||
|
*/
|
||||||
|
if (lastmsgfromd != null) {
|
||||||
|
DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(),
|
||||||
|
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
||||||
|
}
|
||||||
|
lastmsgfromd = event.getMessage();
|
||||||
|
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue