Refactoring & made mcchat teleport config
This commit is contained in:
parent
95af050517
commit
038cb98f1a
22 changed files with 488 additions and 445 deletions
|
@ -1,10 +1,11 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import buttondevteam.discordplugin.playerfaker.DiscordFakePlayer;
|
||||
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import lombok.Getter;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -12,8 +13,8 @@ public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlay
|
|||
private static int nextEntityId = 10000;
|
||||
private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener;
|
||||
|
||||
public DiscordConnectedPlayer(IUser user, MessageChannel channel, UUID uuid, String mcname) {
|
||||
super(user, channel, nextEntityId++, uuid, mcname);
|
||||
public DiscordConnectedPlayer(User user, MessageChannel channel, UUID uuid, String mcname, MinecraftChatModule module) {
|
||||
super(user, channel, nextEntityId++, uuid, mcname ,module);
|
||||
vanillaCmdListener = new VanillaCommandListener<>(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public class DiscordPlayer extends ChromaGamerBase {
|
|||
|
||||
/**
|
||||
* Returns true if player has the private Minecraft chat enabled. For setting the value, see
|
||||
* {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.MessageChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)}
|
||||
* {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.MessageChannel, boolean, sx.blah.discord.handle.obj.User, DiscordPlayer)}
|
||||
*/
|
||||
public boolean isMinecraftChatEnabled() {
|
||||
return MCChatPrivate.isMinecraftChatEnabled(this);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.advancement.Advancement;
|
||||
|
@ -26,8 +28,6 @@ import org.bukkit.potion.PotionEffect;
|
|||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.util.Vector;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
|
@ -38,7 +38,7 @@ public class DiscordPlayerSender extends DiscordSenderBase implements IMCPlayer<
|
|||
protected Player player;
|
||||
private @Getter VanillaCommandListener<DiscordPlayerSender> vanillaCmdListener;
|
||||
|
||||
public DiscordPlayerSender(IUser user, MessageChannel channel, Player player) {
|
||||
public DiscordPlayerSender(User user, MessageChannel channel, Player player) {
|
||||
super(user, channel);
|
||||
this.player = player;
|
||||
vanillaCmdListener = new VanillaCommandListener<DiscordPlayerSender>(this);
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.bukkit.permissions.Permission;
|
|||
import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -18,12 +18,12 @@ public class DiscordSender extends DiscordSenderBase implements CommandSender {
|
|||
|
||||
private String name;
|
||||
|
||||
public DiscordSender(IUser user, MessageChannel channel) {
|
||||
public DiscordSender(User user, MessageChannel channel) {
|
||||
super(user, channel);
|
||||
name = user == null ? "Discord user" : user.getDisplayName(DiscordPlugin.mainServer);
|
||||
}
|
||||
|
||||
public DiscordSender(IUser user, MessageChannel channel, String name) {
|
||||
public DiscordSender(User user, MessageChannel channel, String name) {
|
||||
super(user, channel);
|
||||
this.name = name;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
public abstract class DiscordSenderBase implements CommandSender {
|
||||
/**
|
||||
* May be null.
|
||||
*/
|
||||
protected IUser user;
|
||||
protected User user;
|
||||
protected MessageChannel channel;
|
||||
|
||||
protected DiscordSenderBase(IUser user, MessageChannel channel) {
|
||||
protected DiscordSenderBase(User user, MessageChannel channel) {
|
||||
this.user = user;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public abstract class DiscordSenderBase implements CommandSender {
|
|||
*
|
||||
* @return The user or null.
|
||||
*/
|
||||
public IUser getUser() {
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public abstract class DiscordSenderBase implements CommandSender {
|
|||
* @return A Chroma user of Discord or a Discord user of Chroma
|
||||
*/
|
||||
public DiscordPlayer getChromaUser() {
|
||||
if (chromaUser == null) chromaUser = DiscordPlayer.getUser(user.getStringID(), DiscordPlayer.class);
|
||||
if (chromaUser == null) chromaUser = DiscordPlayer.getUser(user.getId().asString(), DiscordPlayer.class);
|
||||
return chromaUser;
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,7 @@ public abstract class DiscordSenderBase implements CommandSender {
|
|||
msgtosend += "\n" + sendmsg;
|
||||
if (sendtask == null)
|
||||
sendtask = Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
DiscordPlugin.sendMessageToChannel(channel,
|
||||
(!broadcast && user != null ? user.mention() + "\n" : "") + msgtosend.trim());
|
||||
channel.createMessage((!broadcast && user != null ? user.getMention() + "\n" : "") + msgtosend.trim());
|
||||
sendtask = null;
|
||||
msgtosend = "";
|
||||
}, 4); // Waits a 0.2 second to gather all/most of the different messages
|
||||
|
|
|
@ -28,10 +28,10 @@ public class ConnectCommand extends ICommand2DC {
|
|||
@Command2.Subcommand
|
||||
public boolean def(Command2DCSender sender, String Minecraftname) {
|
||||
val message = sender.getMessage();
|
||||
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) {
|
||||
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getId().asString())) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + Minecraftname);
|
||||
WaitingToConnect.inverse().remove(message.getAuthor().getStringID());
|
||||
"Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getId().asString()) + " with " + Minecraftname);
|
||||
WaitingToConnect.inverse().remove(message.getAuthor().getId().asString());
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname);
|
||||
|
@ -41,7 +41,7 @@ public class ConnectCommand extends ICommand2DC {
|
|||
}
|
||||
try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) {
|
||||
DiscordPlayer dp = pl.getAs(DiscordPlayer.class);
|
||||
if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) {
|
||||
if (dp != null && message.getAuthor().getId().asString().equals(dp.getDiscordID())) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected.");
|
||||
return true;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class ConnectCommand extends ICommand2DC {
|
|||
TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e);
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e);
|
||||
}
|
||||
WaitingToConnect.put(p.getName(), message.getAuthor().getStringID());
|
||||
WaitingToConnect.put(p.getName(), message.getAuthor().getId().asString());
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"Alright! Now accept the connection in Minecraft from the account " + Minecraftname
|
||||
+ " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.");
|
||||
|
|
|
@ -8,7 +8,7 @@ import buttondevteam.lib.chat.CommandClass;
|
|||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
|
||||
import lombok.val;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
import sx.blah.discord.handle.obj.Message;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -24,23 +24,23 @@ public class UserinfoCommand extends ICommand2DC {
|
|||
@Command2.Subcommand
|
||||
public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) {
|
||||
val message = sender.getMessage();
|
||||
IUser target = null;
|
||||
User target = null;
|
||||
if (user == null || user.length() == 0)
|
||||
target = message.getAuthor();
|
||||
else {
|
||||
final Optional<IUser> firstmention = message.getMentions().stream()
|
||||
.filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst();
|
||||
final Optional<User> firstmention = message.getMentions().stream()
|
||||
.filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelf().getId().asString())).findFirst();
|
||||
if (firstmention.isPresent())
|
||||
target = firstmention.get();
|
||||
else if (user.contains("#")) {
|
||||
String[] targettag = user.split("#");
|
||||
final List<IUser> targets = getUsers(message, targettag[0]);
|
||||
final List<User> targets = getUsers(message, targettag[0]);
|
||||
if (targets.size() == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"The user cannot be found (by name): " + user);
|
||||
return true;
|
||||
}
|
||||
for (IUser ptarget : targets) {
|
||||
for (User ptarget : targets) {
|
||||
if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) {
|
||||
target = ptarget;
|
||||
break;
|
||||
|
@ -53,7 +53,7 @@ public class UserinfoCommand extends ICommand2DC {
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
final List<IUser> targets = getUsers(message, user);
|
||||
final List<User> targets = getUsers(message, user);
|
||||
if (targets.size() == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"The user cannot be found on Discord: " + user);
|
||||
|
@ -67,7 +67,7 @@ public class UserinfoCommand extends ICommand2DC {
|
|||
target = targets.get(0);
|
||||
}
|
||||
}
|
||||
try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getStringID(), DiscordPlayer.class)) {
|
||||
try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getId().asString(), DiscordPlayer.class)) {
|
||||
StringBuilder uinfo = new StringBuilder("User info for ").append(target.getName()).append(":\n");
|
||||
uinfo.append(dp.getInfo(InfoTarget.Discord));
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), uinfo.toString());
|
||||
|
@ -78,8 +78,8 @@ public class UserinfoCommand extends ICommand2DC {
|
|||
return true;
|
||||
}
|
||||
|
||||
private List<IUser> getUsers(Message message, String args) {
|
||||
final List<IUser> targets;
|
||||
private List<User> getUsers(Message message, String args) {
|
||||
final List<User> targets;
|
||||
if (message.getChannel().isPrivate())
|
||||
targets = DiscordPlugin.dc.getUsers().stream().filter(u -> u.getName().equalsIgnoreCase(args))
|
||||
.collect(Collectors.toList());
|
||||
|
|
|
@ -135,7 +135,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
|
|||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& event.getUser().getRolesForGuild(channel.getGuild()).stream()
|
||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||
.anyMatch(r -> r.getId().asLong() == devrole.getId().asLong())
|
||||
&& channel.getGuild().getUsersByRole(devrole).stream()
|
||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||
|
|
|
@ -3,6 +3,10 @@ package buttondevteam.discordplugin.listeners;
|
|||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.commands.Command2DCSender;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import discord4j.core.object.entity.Message;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.PrivateChannel;
|
||||
import lombok.val;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
import sx.blah.discord.handle.obj.Message;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
@ -16,22 +20,28 @@ public class CommandListener {
|
|||
* @return Whether it ran the command
|
||||
*/
|
||||
public static boolean runCommand(Message message, boolean mentionedonly) {
|
||||
if (message.getContent().length() == 0)
|
||||
if (message.getContent().isEmpty())
|
||||
return false; //Pin messages and such, let the mcchat listener deal with it
|
||||
final MessageChannel channel = message.getChannel();
|
||||
final MessageChannel channel = message.getChannel().block();
|
||||
@SuppressWarnings("OptionalGetWithoutIsPresent") val content = message.getContent().get();
|
||||
if (channel == null) return false;
|
||||
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
||||
if (!message.getChannel().isPrivate()
|
||||
&& !(message.getContent().charAt(0) == DiscordPlugin.getPrefix()
|
||||
&& channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) //
|
||||
if (!(channel instanceof PrivateChannel)
|
||||
&& !(content.charAt(0) == DiscordPlugin.getPrefix()
|
||||
&& channel.getId().asString().equals(DiscordPlugin.plugin.CommandChannel().get().getId().asString()))) //
|
||||
return false;
|
||||
message.getChannel().setTypingStatus(true); // Fun
|
||||
channel.type().subscribe(); // Fun
|
||||
}
|
||||
final StringBuilder cmdwithargs = new StringBuilder(message.getContent());
|
||||
final String mention = DiscordPlugin.dc.getOurUser().mention(false);
|
||||
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
|
||||
final StringBuilder cmdwithargs = new StringBuilder(content);
|
||||
val self=DiscordPlugin.dc.getSelf().block();
|
||||
if(self==null) return false;
|
||||
val member=self.asMember(DiscordPlugin.mainServer.getId()).block();
|
||||
if(member==null) return false;
|
||||
final String mention = self.getMention();
|
||||
final String mentionNick = member.getNicknameMention();
|
||||
boolean gotmention = checkanddeletemention(cmdwithargs, mention, message);
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
|
||||
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(IRole::mention)::iterator)
|
||||
for (String mentionRole : (Iterable<String>) message.getRoleMentions().filter(r -> member.getRoles().filter(r)).map(IRole::mention)::iterator) //TODO: Remove all that matches
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
|
||||
if (mentionedonly && !gotmention) {
|
||||
message.getChannel().setTypingStatus(false);
|
||||
|
|
|
@ -8,13 +8,13 @@ import buttondevteam.lib.player.TBMCPlayerJoinEvent;
|
|||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
|
||||
public class MCListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
|
||||
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
|
||||
@SuppressWarnings("ConstantConditions") IUser user = DiscordPlugin.dc
|
||||
@SuppressWarnings("ConstantConditions") User user = DiscordPlugin.dc
|
||||
.getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get())));
|
||||
e.getPlayer().sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator()
|
||||
+ " do /discord accept");
|
||||
|
@ -29,7 +29,7 @@ public class MCListener implements Listener {
|
|||
DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class);
|
||||
if (dp == null || dp.getDiscordID() == null || dp.getDiscordID().equals(""))
|
||||
return;
|
||||
IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
||||
User user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
||||
e.addInfo("Discord tag: " + user.getName() + "#" + user.getDiscriminator());
|
||||
e.addInfo(user.getPresence().getStatus().toString());
|
||||
if (user.getPresence().getActivity().isPresent() && user.getPresence().getText().isPresent())
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ChannelconCommand extends ICommand2DC {
|
|||
message.reply("MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.");
|
||||
return true;
|
||||
}
|
||||
val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class);
|
||||
val dp = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class);
|
||||
val chp = dp.getAs(TBMCPlayer.class);
|
||||
if (chp == null) {
|
||||
message.reply("you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>");
|
||||
|
@ -140,7 +140,7 @@ public class ChannelconCommand extends ICommand2DC {
|
|||
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
|
||||
"You also need to have your Minecraft account connected. In " + DPUtils.botmention() + " use " + DiscordPlugin.getPrefix() + "connect <mcname>.", //
|
||||
"Call this command from the channel you want to use.", //
|
||||
"Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon <mcchannel>", //
|
||||
"Usage: @" + DiscordPlugin.dc.getSelf().getName() + " channelcon <mcchannel>", //
|
||||
"Use the ID (command) of the channel, for example `g` for the global chat.", //
|
||||
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
|
||||
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in " + DPUtils.botmention() + ".", //
|
||||
|
|
|
@ -24,7 +24,7 @@ public class MCChatCommand extends ICommand2DC {
|
|||
message.reply("this command can only be issued in a direct message with the bot.");
|
||||
return true;
|
||||
}
|
||||
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
|
||||
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class)) {
|
||||
boolean mcchat = !user.isMinecraftChatEnabled();
|
||||
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
|
||||
message.reply("Minecraft chat " + (mcchat //
|
||||
|
|
|
@ -4,10 +4,12 @@ import buttondevteam.core.component.channel.Channel;
|
|||
import buttondevteam.core.component.channel.ChatRoom;
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.TextChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import discord4j.core.object.util.Snowflake;
|
||||
import lombok.NonNull;
|
||||
import lombok.val;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
@ -21,7 +23,7 @@ public class MCChatCustom {
|
|||
*/
|
||||
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
||||
|
||||
public static void addCustomChat(MessageChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
|
||||
public static void addCustomChat(MessageChannel channel, String groupid, Channel mcchannel, User user, DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
|
||||
if (mcchannel instanceof ChatRoom) {
|
||||
((ChatRoom) mcchannel).joinRoom(dcp);
|
||||
if (groupid == null) groupid = mcchannel.getGroupID(dcp);
|
||||
|
@ -30,19 +32,19 @@ public class MCChatCustom {
|
|||
lastmsgCustom.add(lmd);
|
||||
}
|
||||
|
||||
public static boolean hasCustomChat(MessageChannel channel) {
|
||||
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
public static boolean hasCustomChat(Snowflake channel) {
|
||||
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getId().asLong() == channel.asLong());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CustomLMD getCustomChat(MessageChannel channel) {
|
||||
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
|
||||
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()).findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static boolean removeCustomChat(MessageChannel channel) {
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getId().asLong());
|
||||
return lastmsgCustom.removeIf(lmd -> {
|
||||
if (lmd.channel.getLongID() != channel.getLongID())
|
||||
if (lmd.channel.getId().asLong() != channel.getId().asLong())
|
||||
return false;
|
||||
if (lmd.mcchannel instanceof ChatRoom)
|
||||
((ChatRoom) lmd.mcchannel).leaveRoom(lmd.dcp);
|
||||
|
@ -61,9 +63,9 @@ public class MCChatCustom {
|
|||
public int toggles;
|
||||
public Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles;
|
||||
|
||||
private CustomLMD(@NonNull MessageChannel channel, @NonNull IUser user,
|
||||
private CustomLMD(@NonNull MessageChannel channel, @NonNull User user,
|
||||
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
|
||||
super(channel, user);
|
||||
super((TextChannel) channel, user);
|
||||
groupID = groupid;
|
||||
this.mcchannel = mcchannel;
|
||||
this.dcp = dcp;
|
||||
|
|
|
@ -14,6 +14,11 @@ import buttondevteam.lib.chat.ChatMessage;
|
|||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.PrivateChannel;
|
||||
import discord4j.core.object.entity.TextChannel;
|
||||
import discord4j.core.spec.EmbedCreateSpec;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -22,7 +27,7 @@ import org.bukkit.event.Listener;
|
|||
import org.bukkit.scheduler.BukkitTask;
|
||||
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.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
import sx.blah.discord.handle.obj.Message;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
|
@ -41,10 +46,10 @@ import java.util.function.Predicate;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class MCChatListener implements Listener {
|
||||
private BukkitTask sendtask;
|
||||
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
|
||||
private Runnable sendrunnable;
|
||||
private static Thread sendthread;
|
||||
private BukkitTask sendtask;
|
||||
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
|
||||
private Runnable sendrunnable;
|
||||
private static Thread sendthread;
|
||||
private final MinecraftChatModule module;
|
||||
|
||||
public MCChatListener(MinecraftChatModule minecraftChatModule) {
|
||||
|
@ -52,359 +57,361 @@ public class MCChatListener implements Listener {
|
|||
}
|
||||
|
||||
@EventHandler // Minecraft
|
||||
public void onMCChat(TBMCChatEvent ev) {
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
|
||||
return;
|
||||
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
||||
if (sendtask != null)
|
||||
return;
|
||||
sendrunnable = () -> {
|
||||
sendthread = Thread.currentThread();
|
||||
processMCToDiscord();
|
||||
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
|
||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||
};
|
||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||
}
|
||||
public void onMCChat(TBMCChatEvent ev) {
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
|
||||
return;
|
||||
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
||||
if (sendtask != null)
|
||||
return;
|
||||
sendrunnable = () -> {
|
||||
sendthread = Thread.currentThread();
|
||||
processMCToDiscord();
|
||||
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
|
||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||
};
|
||||
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
|
||||
}
|
||||
|
||||
private void processMCToDiscord() {
|
||||
try {
|
||||
TBMCChatEvent e;
|
||||
Instant time;
|
||||
val se = sendevents.take(); // Wait until an element is available
|
||||
e = se.getKey();
|
||||
time = se.getValue();
|
||||
private void processMCToDiscord() {
|
||||
try {
|
||||
TBMCChatEvent e;
|
||||
Instant time;
|
||||
val se = sendevents.take(); // Wait until an element is available
|
||||
e = se.getKey();
|
||||
time = se.getValue();
|
||||
|
||||
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " //
|
||||
+ ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") //
|
||||
+ (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player //
|
||||
? ((Player) e.getSender()).getDisplayName() //
|
||||
: e.getSender().getName()));
|
||||
val color = e.getChannel().Color().get();
|
||||
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
||||
.withDescription(e.getMessage()).withColor(new Color(color.getRed(),
|
||||
color.getGreen(), 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();
|
||||
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())
|
||||
|| 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 MCChatUtils.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
|
||||
// Or if it was from MC
|
||||
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " //
|
||||
+ ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") //
|
||||
+ (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player //
|
||||
? ((Player) e.getSender()).getDisplayName() //
|
||||
: e.getSender().getName()));
|
||||
val color = e.getChannel().Color().get();
|
||||
final EmbedCreateSpec embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
||||
.withDescription(e.getMessage()).withColor(new Color(color.getRed(),
|
||||
color.getGreen(), 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().getId().asString()); // TODO: Constant/method to get URLs like this
|
||||
// embed.withFooterText(e.getChannel().DisplayName);
|
||||
embed.withTimestamp(time);
|
||||
final long nanoTime = System.nanoTime();
|
||||
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())
|
||||
|| 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
|
||||
lastmsgdata.message.edit(mes -> mes.setEmbed(ecs -> embedObject)).block();
|
||||
} 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
|
||||
// Or if it was from MC
|
||||
Predicate<MessageChannel> isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase)
|
||||
|| ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
|
||||
|| ((DiscordSenderBase) e.getSender()).getChannel().getId().asLong() != ch.getId().asLong();
|
||||
|
||||
if (e.getChannel().isGlobal()
|
||||
&& (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get())))
|
||||
doit.accept(MCChatUtils.lastmsgdata == null
|
||||
? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannel().get(), null)
|
||||
: MCChatUtils.lastmsgdata);
|
||||
if (e.getChannel().isGlobal()
|
||||
&& (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get())))
|
||||
doit.accept(MCChatUtils.lastmsgdata == null
|
||||
? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData((TextChannel) module.chatChannel().get(), null)
|
||||
: MCChatUtils.lastmsgdata);
|
||||
|
||||
for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) {
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(data.channel))
|
||||
&& e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user)))
|
||||
doit.accept(data);
|
||||
}
|
||||
for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) {
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(data.channel))
|
||||
&& e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user)))
|
||||
doit.accept(data);
|
||||
}
|
||||
|
||||
val iterator = MCChatCustom.lastmsgCustom.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
val lmd = iterator.next();
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
||||
&& e.getChannel().ID.equals(lmd.mcchannel.ID) //If it's from a command, the command msg has been deleted, so we need to send it
|
||||
&& e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58
|
||||
if (e.shouldSendTo(lmd.dcp)) //Check original user's permissions
|
||||
doit.accept(lmd);
|
||||
else {
|
||||
iterator.remove(); //If the user no longer has permission, remove the connection
|
||||
DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) { //Stop if interrupted anywhere
|
||||
sendtask.cancel();
|
||||
sendtask = null;
|
||||
} catch (Exception ex) {
|
||||
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
|
||||
}
|
||||
}
|
||||
val iterator = MCChatCustom.lastmsgCustom.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
val lmd = iterator.next();
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
||||
&& e.getChannel().ID.equals(lmd.mcchannel.ID) //If it's from a command, the command msg has been deleted, so we need to send it
|
||||
&& e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58
|
||||
if (e.shouldSendTo(lmd.dcp)) //Check original user's permissions
|
||||
doit.accept(lmd);
|
||||
else {
|
||||
iterator.remove(); //If the user no longer has permission, remove the connection
|
||||
DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) { //Stop if interrupted anywhere
|
||||
sendtask.cancel();
|
||||
sendtask = null;
|
||||
} catch (Exception ex) {
|
||||
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChatPreprocess(TBMCChatPreprocessEvent event) {
|
||||
int start = -1;
|
||||
while ((start = event.getMessage().indexOf('@', start + 1)) != -1) {
|
||||
int mid = event.getMessage().indexOf('#', start + 1);
|
||||
if (mid == -1)
|
||||
return;
|
||||
int end_ = event.getMessage().indexOf(' ', mid + 1);
|
||||
if (end_ == -1)
|
||||
end_ = event.getMessage().length();
|
||||
final int end = end_;
|
||||
final int startF = start;
|
||||
DiscordPlugin.dc.getUsersByName(event.getMessage().substring(start + 1, mid)).stream()
|
||||
.filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).findAny()
|
||||
.ifPresent(user -> event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getName()
|
||||
+ (event.getMessage().length() > end ? event.getMessage().substring(end) : ""))); // TODO: Add formatting
|
||||
start = end; // Skip any @s inside the mention
|
||||
}
|
||||
}
|
||||
@EventHandler
|
||||
public void onChatPreprocess(TBMCChatPreprocessEvent event) {
|
||||
int start = -1;
|
||||
while ((start = event.getMessage().indexOf('@', start + 1)) != -1) {
|
||||
int mid = event.getMessage().indexOf('#', start + 1);
|
||||
if (mid == -1)
|
||||
return;
|
||||
int end_ = event.getMessage().indexOf(' ', mid + 1);
|
||||
if (end_ == -1)
|
||||
end_ = event.getMessage().length();
|
||||
final int end = end_;
|
||||
final int startF = start;
|
||||
val user = DiscordPlugin.dc.getUsers().filter(u -> u.getUsername().equals(event.getMessage().substring(startF + 1, mid)))
|
||||
.filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).blockFirst();
|
||||
if (user != null) //TODO: Nicknames
|
||||
event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getUsername()
|
||||
+ (event.getMessage().length() > end ? event.getMessage().substring(end) : "")); // TODO: Add formatting
|
||||
start = end; // Skip any @s inside the mention
|
||||
}
|
||||
}
|
||||
|
||||
// ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
|
||||
// Offline public chat......x............................................
|
||||
// Online public chat.......x...........................................x
|
||||
// Offline private chat.....x.......................x....................
|
||||
// Online private chat......x.......................x...................x
|
||||
// If online and enabling private chat, don't login
|
||||
// If leaving the server and private chat is enabled (has ConnectedPlayer), call login in a task on lowest priority
|
||||
// If private chat is enabled and joining the server, logout the fake player on highest priority
|
||||
// If online and disabling private chat, don't logout
|
||||
// The maps may not contain the senders for UnconnectedSenders
|
||||
// ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
|
||||
// Offline public chat......x............................................
|
||||
// Online public chat.......x...........................................x
|
||||
// Offline private chat.....x.......................x....................
|
||||
// Online private chat......x.......................x...................x
|
||||
// If online and enabling private chat, don't login
|
||||
// If leaving the server and private chat is enabled (has ConnectedPlayer), call login in a task on lowest priority
|
||||
// If private chat is enabled and joining the server, logout the fake player on highest priority
|
||||
// If online and disabling private chat, don't logout
|
||||
// The maps may not contain the senders for UnconnectedSenders
|
||||
|
||||
/**
|
||||
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
|
||||
*
|
||||
* @param wait Wait 5 seconds for the threads to stop
|
||||
*/
|
||||
public static void stop(boolean wait) {
|
||||
if (sendthread != null) sendthread.interrupt();
|
||||
if (recthread != null) recthread.interrupt();
|
||||
try {
|
||||
if (sendthread != null) {
|
||||
sendthread.interrupt();
|
||||
if (wait)
|
||||
sendthread.join(5000);
|
||||
}
|
||||
if (recthread != null) {
|
||||
recthread.interrupt();
|
||||
if (wait)
|
||||
recthread.join(5000);
|
||||
}
|
||||
MCChatUtils.lastmsgdata = null;
|
||||
MCChatPrivate.lastmsgPerUser.clear();
|
||||
MCChatCustom.lastmsgCustom.clear();
|
||||
MCChatUtils.lastmsgfromd.clear();
|
||||
MCChatUtils.ConnectedSenders.clear();
|
||||
MCChatUtils.UnconnectedSenders.clear();
|
||||
recthread = sendthread = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace(); //This thread shouldn't be interrupted
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
|
||||
*
|
||||
* @param wait Wait 5 seconds for the threads to stop
|
||||
*/
|
||||
public static void stop(boolean wait) {
|
||||
if (sendthread != null) sendthread.interrupt();
|
||||
if (recthread != null) recthread.interrupt();
|
||||
try {
|
||||
if (sendthread != null) {
|
||||
sendthread.interrupt();
|
||||
if (wait)
|
||||
sendthread.join(5000);
|
||||
}
|
||||
if (recthread != null) {
|
||||
recthread.interrupt();
|
||||
if (wait)
|
||||
recthread.join(5000);
|
||||
}
|
||||
MCChatUtils.lastmsgdata = null;
|
||||
MCChatPrivate.lastmsgPerUser.clear();
|
||||
MCChatCustom.lastmsgCustom.clear();
|
||||
MCChatUtils.lastmsgfromd.clear();
|
||||
MCChatUtils.ConnectedSenders.clear();
|
||||
MCChatUtils.UnconnectedSenders.clear();
|
||||
recthread = sendthread = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace(); //This thread shouldn't be interrupted
|
||||
}
|
||||
}
|
||||
|
||||
private BukkitTask rectask;
|
||||
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
|
||||
private Runnable recrun;
|
||||
private static Thread recthread;
|
||||
private BukkitTask rectask;
|
||||
private LinkedBlockingQueue<MessageCreateEvent> recevents = new LinkedBlockingQueue<>();
|
||||
private Runnable recrun;
|
||||
private static Thread recthread;
|
||||
|
||||
// Discord
|
||||
public boolean handleDiscord(MessageReceivedEvent ev) {
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class))
|
||||
return false;
|
||||
val author = ev.getMessage().getAuthor();
|
||||
final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getChannel());
|
||||
if (ev.getMessage().getChannel().getLongID() != module.chatChannel().get().getLongID()
|
||||
&& !(ev.getMessage().getChannel().isPrivate() && MCChatPrivate.isMinecraftChatEnabled(author.getStringID()))
|
||||
&& !hasCustomChat)
|
||||
public boolean handleDiscord(MessageCreateEvent ev) {
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class))
|
||||
return false;
|
||||
val author = ev.getMessage().getAuthor();
|
||||
final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getMessage().getChannelId());
|
||||
val channel = ev.getMessage().getChannel().block();
|
||||
if (ev.getMessage().getChannelId().asLong() != module.chatChannel().get().getId().asLong()
|
||||
&& !(channel instanceof PrivateChannel
|
||||
&& author.map(u -> MCChatPrivate.isMinecraftChatEnabled(u.getId().asString())).orElse(false)
|
||||
&& !hasCustomChat))
|
||||
return false; //Chat isn't enabled on this channel
|
||||
if (ev.getMessage().getChannel().isPrivate() //Only in private chat
|
||||
&& ev.getMessage().getContent().length() < "/mcchat<>".length()
|
||||
&& ev.getMessage().getContent().replace("/", "")
|
||||
.equalsIgnoreCase("mcchat")) //Either mcchat or /mcchat
|
||||
if (channel instanceof PrivateChannel //Only in private chat
|
||||
&& ev.getMessage().getContent().isPresent()
|
||||
&& ev.getMessage().getContent().get().length() < "/mcchat<>".length()
|
||||
&& ev.getMessage().getContent().get().replace("/", "")
|
||||
.equalsIgnoreCase("mcchat")) //Either mcchat or /mcchat
|
||||
return false; //Allow disabling the chat if needed
|
||||
if (CommandListener.runCommand(ev.getMessage(), true))
|
||||
return true; //Allow running commands in chat channels
|
||||
MCChatUtils.resetLastMessage(ev.getChannel());
|
||||
recevents.add(ev);
|
||||
if (rectask != null)
|
||||
return true;
|
||||
recrun = () -> { //Don't return in a while loop next time
|
||||
recthread = Thread.currentThread();
|
||||
processDiscordToMC();
|
||||
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
|
||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing
|
||||
};
|
||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing
|
||||
if (CommandListener.runCommand(ev.getMessage(), true))
|
||||
return true; //Allow running commands in chat channels
|
||||
MCChatUtils.resetLastMessage(channel);
|
||||
recevents.add(ev);
|
||||
if (rectask != null)
|
||||
return true;
|
||||
recrun = () -> { //Don't return in a while loop next time
|
||||
recthread = Thread.currentThread();
|
||||
processDiscordToMC();
|
||||
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
|
||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing
|
||||
};
|
||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
String dmessage = event.getMessage().getContent();
|
||||
try {
|
||||
final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender);
|
||||
val user = dsender.getChromaUser();
|
||||
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();
|
||||
String dmessage = event.getMessage().getContent();
|
||||
try {
|
||||
final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender);
|
||||
val user = dsender.getChromaUser();
|
||||
|
||||
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()));
|
||||
}
|
||||
for (User 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()));
|
||||
}
|
||||
for (MessageChannel ch : event.getMessage().getChannelMentions()) {
|
||||
dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting
|
||||
}
|
||||
dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting
|
||||
}
|
||||
|
||||
dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?)
|
||||
dmessage = dmessage.replaceAll(":(\\S+)\\|type_(?:(\\d)|(1)_2):", ":$1::skin-tone-$2:"); //Convert to Discord's format so it still shows up
|
||||
dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?)
|
||||
dmessage = dmessage.replaceAll(":(\\S+)\\|type_(?:(\\d)|(1)_2):", ":$1::skin-tone-$2:"); //Convert to Discord's format so it still shows up
|
||||
|
||||
Function<String, String> getChatMessage = msg -> //
|
||||
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
|
||||
.getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n"))
|
||||
: "");
|
||||
Function<String, String> getChatMessage = msg -> //
|
||||
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
|
||||
.getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n"))
|
||||
: "");
|
||||
|
||||
MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel());
|
||||
MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel());
|
||||
|
||||
boolean react = false;
|
||||
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);
|
||||
final String cmdlowercased = cmd.toLowerCase();
|
||||
if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream()
|
||||
.noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) {
|
||||
// Command not whitelisted
|
||||
dsender.sendMessage("Sorry, you can only access these commands:\n"
|
||||
+ module.whitelistedCommands().get().stream().map(uc -> "/" + uc)
|
||||
.collect(Collectors.joining(", "))
|
||||
+ (user.getConnectedID(TBMCPlayer.class) == null
|
||||
? "\nTo access your commands, first please connect your accounts, using /connect in "
|
||||
+ DPUtils.botmention()
|
||||
+ "\nThen y"
|
||||
: "\nY")
|
||||
+ "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!");
|
||||
return;
|
||||
}
|
||||
val ev = new TBMCCommandPreprocessEvent(dsender, dmessage);
|
||||
Bukkit.getPluginManager().callEvent(ev);
|
||||
if (ev.isCancelled())
|
||||
return;
|
||||
int spi = cmdlowercased.indexOf(' ');
|
||||
final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi);
|
||||
Optional<Channel> ch = Channel.getChannels()
|
||||
.filter(c -> c.ID.equalsIgnoreCase(topcmd)
|
||||
|| (c.IDs().get().length > 0
|
||||
&& Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
|
||||
if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync
|
||||
() -> { //TODO: Better handling...
|
||||
val channel = user.channel();
|
||||
val chtmp = channel.get();
|
||||
if (clmd != null) {
|
||||
channel.set(clmd.mcchannel); //Hack to send command in the channel
|
||||
} //TODO: Permcheck isn't implemented for commands
|
||||
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
|
||||
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
|
||||
if (clmd != null)
|
||||
channel.set(chtmp);
|
||||
});
|
||||
else {
|
||||
Channel chc = ch.get();
|
||||
if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate())
|
||||
dsender.sendMessage(
|
||||
"You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels.");
|
||||
else {
|
||||
if (spi == -1) // Switch channels
|
||||
{
|
||||
val channel = dsender.getChromaUser().channel();
|
||||
val oldch = channel.get();
|
||||
if (oldch instanceof ChatRoom)
|
||||
((ChatRoom) oldch).leaveRoom(dsender);
|
||||
if (!oldch.ID.equals(chc.ID)) {
|
||||
channel.set(chc);
|
||||
if (chc instanceof ChatRoom)
|
||||
((ChatRoom) chc).joinRoom(dsender);
|
||||
} else
|
||||
channel.set(Channel.GlobalChat);
|
||||
dsender.sendMessage("You're now talking in: "
|
||||
+ DPUtils.sanitizeString(channel.get().DisplayName().get()));
|
||||
} else { // Send single message
|
||||
final String msg = cmd.substring(spi + 1);
|
||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
||||
if (clmd == null)
|
||||
TBMCChatAPI.SendChatMessage(cmb.build(), chc);
|
||||
else
|
||||
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc);
|
||||
react = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {// Not a command
|
||||
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
|
||||
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) {
|
||||
val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp)
|
||||
: dsender.getChromaUser().channel().get().getRTR(dsender);
|
||||
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
|
||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||
: dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL);
|
||||
}
|
||||
else {
|
||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
||||
if (clmd != null)
|
||||
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), clmd.mcchannel);
|
||||
else
|
||||
TBMCChatAPI.SendChatMessage(cmb.build());
|
||||
react = true;
|
||||
}
|
||||
}
|
||||
if (react) {
|
||||
try {
|
||||
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
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
||||
}
|
||||
MCChatUtils.lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
|
||||
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
||||
}
|
||||
}
|
||||
if (dmessage.startsWith("/")) { // Ingame command
|
||||
DPUtils.perform(() -> {
|
||||
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
||||
event.getMessage().delete();
|
||||
});
|
||||
final String cmd = dmessage.substring(1);
|
||||
final String cmdlowercased = cmd.toLowerCase();
|
||||
if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream()
|
||||
.noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) {
|
||||
// Command not whitelisted
|
||||
dsender.sendMessage("Sorry, you can only access these commands:\n"
|
||||
+ module.whitelistedCommands().get().stream().map(uc -> "/" + uc)
|
||||
.collect(Collectors.joining(", "))
|
||||
+ (user.getConnectedID(TBMCPlayer.class) == null
|
||||
? "\nTo access your commands, first please connect your accounts, using /connect in "
|
||||
+ DPUtils.botmention()
|
||||
+ "\nThen y"
|
||||
: "\nY")
|
||||
+ "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!");
|
||||
return;
|
||||
}
|
||||
val ev = new TBMCCommandPreprocessEvent(dsender, dmessage);
|
||||
Bukkit.getPluginManager().callEvent(ev);
|
||||
if (ev.isCancelled())
|
||||
return;
|
||||
int spi = cmdlowercased.indexOf(' ');
|
||||
final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi);
|
||||
Optional<Channel> ch = Channel.getChannels()
|
||||
.filter(c -> c.ID.equalsIgnoreCase(topcmd)
|
||||
|| (c.IDs().get().length > 0
|
||||
&& Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
|
||||
if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync
|
||||
() -> { //TODO: Better handling...
|
||||
val channel = user.channel();
|
||||
val chtmp = channel.get();
|
||||
if (clmd != null) {
|
||||
channel.set(clmd.mcchannel); //Hack to send command in the channel
|
||||
} //TODO: Permcheck isn't implemented for commands
|
||||
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
|
||||
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
|
||||
if (clmd != null)
|
||||
channel.set(chtmp);
|
||||
});
|
||||
else {
|
||||
Channel chc = ch.get();
|
||||
if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate())
|
||||
dsender.sendMessage(
|
||||
"You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels.");
|
||||
else {
|
||||
if (spi == -1) // Switch channels
|
||||
{
|
||||
val channel = dsender.getChromaUser().channel();
|
||||
val oldch = channel.get();
|
||||
if (oldch instanceof ChatRoom)
|
||||
((ChatRoom) oldch).leaveRoom(dsender);
|
||||
if (!oldch.ID.equals(chc.ID)) {
|
||||
channel.set(chc);
|
||||
if (chc instanceof ChatRoom)
|
||||
((ChatRoom) chc).joinRoom(dsender);
|
||||
} else
|
||||
channel.set(Channel.GlobalChat);
|
||||
dsender.sendMessage("You're now talking in: "
|
||||
+ DPUtils.sanitizeString(channel.get().DisplayName().get()));
|
||||
} else { // Send single message
|
||||
final String msg = cmd.substring(spi + 1);
|
||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
||||
if (clmd == null)
|
||||
TBMCChatAPI.SendChatMessage(cmb.build(), chc);
|
||||
else
|
||||
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc);
|
||||
react = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {// Not a command
|
||||
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
|
||||
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) {
|
||||
val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp)
|
||||
: dsender.getChromaUser().channel().get().getRTR(dsender);
|
||||
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
|
||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||
: dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL);
|
||||
} else {
|
||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
||||
if (clmd != null)
|
||||
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), clmd.mcchannel);
|
||||
else
|
||||
TBMCChatAPI.SendChatMessage(cmb.build());
|
||||
react = true;
|
||||
}
|
||||
}
|
||||
if (react) {
|
||||
try {
|
||||
val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getId().asLong());
|
||||
if (lmfd != null) {
|
||||
DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getSelf(),
|
||||
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);
|
||||
}
|
||||
MCChatUtils.lastmsgfromd.put(event.getChannel().getId().asLong(), event.getMessage());
|
||||
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface InterruptibleConsumer<T> {
|
||||
void accept(T value) throws TimeoutException, InterruptedException;
|
||||
}
|
||||
@FunctionalInterface
|
||||
private interface InterruptibleConsumer<T> {
|
||||
void accept(T value) throws TimeoutException, InterruptedException;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.bukkit.event.Event;
|
|||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import sx.blah.discord.handle.obj.IPrivateChannel;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -22,7 +22,7 @@ public class MCChatPrivate {
|
|||
*/
|
||||
static ArrayList<MCChatUtils.LastMsgData> lastmsgPerUser = new ArrayList<>();
|
||||
|
||||
public static boolean privateMCChat(MessageChannel channel, boolean start, IUser user, DiscordPlayer dp) {
|
||||
public static boolean privateMCChat(MessageChannel channel, boolean start, User 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());
|
||||
|
@ -39,10 +39,10 @@ public class MCChatPrivate {
|
|||
}
|
||||
} // ---- PermissionsEx warning is normal on logout ----
|
||||
if (!start)
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getId().asLong());
|
||||
return start //
|
||||
? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs
|
||||
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong());
|
||||
}
|
||||
|
||||
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
|
||||
|
@ -51,7 +51,7 @@ public class MCChatPrivate {
|
|||
|
||||
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));
|
||||
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getId().asString().equals(did));
|
||||
}
|
||||
|
||||
public static void logoutAll() {
|
||||
|
|
|
@ -81,7 +81,7 @@ public class MCChatUtils {
|
|||
return addSender(senders, user.getId().asLong(), sender);
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<Long, HashMap<Channel, T>> senders,
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<Long, HashMap<MessageChannel, T>> senders,
|
||||
long did, T sender) {
|
||||
var map = senders.get(did);
|
||||
if (map == null)
|
||||
|
@ -91,8 +91,8 @@ public class MCChatUtils {
|
|||
return sender;
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T getSender(HashMap<Long, HashMap<Channel, T>> senders,
|
||||
Channel channel, User user) {
|
||||
public static <T extends DiscordSenderBase> T getSender(HashMap<Long, HashMap<MessageChannel, T>> senders,
|
||||
MessageChannel channel, User user) {
|
||||
var map = senders.get(user.getId().asLong());
|
||||
if (map != null)
|
||||
return map.get(channel);
|
||||
|
@ -172,7 +172,7 @@ public class MCChatUtils {
|
|||
}
|
||||
|
||||
public static void forAllowedMCChat(Consumer<MessageChannel> action, TBMCSystemChatEvent event) {
|
||||
if (notEnabled()) return
|
||||
if (notEnabled()) return;
|
||||
if (event.getChannel().isGlobal())
|
||||
action.accept(module.chatChannel().get());
|
||||
for (LastMsgData data : MCChatPrivate.lastmsgPerUser)
|
||||
|
@ -188,7 +188,7 @@ public class MCChatUtils {
|
|||
/**
|
||||
* 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(Channel channel, final User author) {
|
||||
static DiscordSenderBase getSender(MessageChannel channel, final User 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
|
||||
|
@ -206,13 +206,13 @@ public class MCChatUtils {
|
|||
*/
|
||||
public static void resetLastMessage(Channel channel) {
|
||||
if (notEnabled()) return;
|
||||
if (channel.getLongID() == module.chatChannel().get().getLongID()) {
|
||||
if (channel.getId().asLong() == module.chatChannel().get().getId().asLong()) {
|
||||
(lastmsgdata == null ? lastmsgdata = new LastMsgData(module.chatChannel().get(), 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()) {
|
||||
if (data.channel.getId().asLong() == channel.getId().asLong()) {
|
||||
data.message = null;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.bukkit.event.player.PlayerLoginEvent.Result;
|
|||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.BroadcastMessageEvent;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.User;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
import sx.blah.discord.util.MissingPermissionsException;
|
||||
|
||||
|
@ -115,7 +115,7 @@ class MCListener implements Listener {
|
|||
final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
|
||||
.getAs(DiscordPlayer.class);
|
||||
if (p == null) return;
|
||||
final IUser user = DiscordPlugin.dc.getUserByID(
|
||||
final User user = DiscordPlugin.dc.getUserByID(
|
||||
Long.parseLong(p.getDiscordID()));
|
||||
if (e.getValue())
|
||||
user.addRole(role);
|
||||
|
@ -149,7 +149,7 @@ class MCListener implements Listener {
|
|||
: event.getSender().getName();
|
||||
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
|
||||
val yeehaw = DiscordPlugin.mainServer.getEmojiByName("YEEHAW");
|
||||
MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getStringID() + ">s" : " YEEHAWs")));
|
||||
MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getId().asString() + ">s" : " YEEHAWs")));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
|
@ -9,6 +9,9 @@ import buttondevteam.lib.TBMCSystemChatEvent;
|
|||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import com.google.common.collect.Lists;
|
||||
import discord4j.core.event.domain.message.MessageCreateEvent;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.util.Snowflake;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -23,7 +26,8 @@ import java.util.stream.Collectors;
|
|||
* Provides Minecraft chat connection to Discord. Commands may be used either in a public chat (limited) or in a DM.
|
||||
*/
|
||||
public class MinecraftChatModule extends Component<DiscordPlugin> {
|
||||
private @Getter MCChatListener listener;
|
||||
private @Getter
|
||||
MCChatListener listener;
|
||||
|
||||
/*public MCChatListener getListener() { //It doesn't want to generate
|
||||
return listener; - And now ButtonProcessor didn't look beyond this - return instead of continue...
|
||||
|
@ -58,11 +62,20 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
|
|||
return getConfig().getData("excludedPlugins", new String[]{"ProtocolLib", "LibsDisguises", "JourneyMapServer"});
|
||||
}
|
||||
|
||||
/**
|
||||
* If this setting is on then players logged in through the 'mcchat' command will be able to teleport using plugin commands.
|
||||
* They can then use commands like /tpahere to teleport others to that place.<br />
|
||||
* If this is off, then teleporting will have no effect.
|
||||
*/
|
||||
public ConfigData<Boolean> allowFakePlayerTeleports() {
|
||||
return getConfig().getData("allowFakePlayerTeleports", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
if (DPUtils.disableIfConfigError(this, chatChannel())) return;
|
||||
listener = new MCChatListener(this);
|
||||
DiscordPlugin.dc.getDispatcher().registerListener(listener);
|
||||
DiscordPlugin.dc.getEventDispatcher().on(MessageCreateEvent.class).subscribe(listener::handleDiscord);
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled
|
||||
getPlugin().getManager().registerCommand(new MCChatCommand());
|
||||
|
@ -76,17 +89,17 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
|
|||
for (val chconkey : chconkeys) {
|
||||
val chcon = chcons.getConfigurationSection(chconkey);
|
||||
val mcch = Channel.getChannels().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
|
||||
val ch = DiscordPlugin.dc.getChannelByID(chcon.getLong("chid"));
|
||||
val ch = DiscordPlugin.dc.getChannelById(Snowflake.of(chcon.getLong("chid"))).block();
|
||||
val did = chcon.getLong("did");
|
||||
val user = DiscordPlugin.dc.fetchUser(did);
|
||||
val user = DiscordPlugin.dc.getUserById(Snowflake.of(did)).block();
|
||||
val groupid = chcon.getString("groupid");
|
||||
val toggles = chcon.getInt("toggles");
|
||||
val brtoggles = chcon.getStringList("brtoggles");
|
||||
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
||||
continue;
|
||||
Bukkit.getScheduler().runTask(getPlugin(), () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase)
|
||||
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
||||
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet()));
|
||||
val dcp = new DiscordConnectedPlayer(user, (MessageChannel) ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"), this);
|
||||
MCChatCustom.addCustomChat((MessageChannel) ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -97,10 +110,10 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
|
|||
val chcons = MCChatCustom.getCustomChats();
|
||||
val chconsc = getConfig().getConfig().createSection("chcons");
|
||||
for (val chcon : chcons) {
|
||||
val chconc = chconsc.createSection(chcon.channel.getStringID());
|
||||
val chconc = chconsc.createSection(chcon.channel.getId().asString());
|
||||
chconc.set("mcchid", chcon.mcchannel.ID);
|
||||
chconc.set("chid", chcon.channel.getLongID());
|
||||
chconc.set("did", chcon.user.getLongID());
|
||||
chconc.set("chid", chcon.channel.getId().asLong());
|
||||
chconc.set("did", chcon.user.getId().asLong());
|
||||
chconc.set("mcuid", chcon.dcp.getUniqueId().toString());
|
||||
chconc.set("mcname", chcon.dcp.getName());
|
||||
chconc.set("groupid", chcon.groupID);
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package buttondevteam.discordplugin.playerfaker;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.DiscordSenderBase;
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.*;
|
||||
|
@ -11,8 +15,6 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
|||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.Vector;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -20,10 +22,11 @@ import java.util.*;
|
|||
@Setter
|
||||
@SuppressWarnings("deprecated")
|
||||
public abstract class DiscordEntity extends DiscordSenderBase implements Entity {
|
||||
protected DiscordEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) {
|
||||
protected DiscordEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) {
|
||||
super(user, channel);
|
||||
this.entityId = entityId;
|
||||
uniqueId = uuid;
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
private HashMap<String, MetadataValue> metadata = new HashMap<String, MetadataValue>();
|
||||
|
@ -34,6 +37,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity
|
|||
private EntityDamageEvent lastDamageCause;
|
||||
private final Set<String> scoreboardTags = new HashSet<String>();
|
||||
private final UUID uniqueId;
|
||||
private final MinecraftChatModule module;
|
||||
|
||||
@Override
|
||||
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
|
||||
|
@ -42,7 +46,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity
|
|||
|
||||
@Override
|
||||
public List<MetadataValue> getMetadata(String metadataKey) {
|
||||
return Arrays.asList(metadata.get(metadataKey)); // Who needs multiple data anyways
|
||||
return Collections.singletonList(metadata.get(metadataKey)); // Who needs multiple data anyways
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,31 +95,35 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity
|
|||
|
||||
@Override
|
||||
public boolean teleport(Location location) {
|
||||
this.location = location;
|
||||
if (module.allowFakePlayerTeleports().get())
|
||||
this.location = location;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(Location location, TeleportCause cause) {
|
||||
this.location = location;
|
||||
if (module.allowFakePlayerTeleports().get())
|
||||
this.location = location;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(Entity destination) {
|
||||
this.location = destination.getLocation();
|
||||
if (module.allowFakePlayerTeleports().get())
|
||||
this.location = destination.getLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(Entity destination, TeleportCause cause) {
|
||||
this.location = destination.getLocation();
|
||||
if (module.allowFakePlayerTeleports().get())
|
||||
this.location = destination.getLocation();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> getNearbyEntities(double x, double y, double z) {
|
||||
return Arrays.asList();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,7 +171,7 @@ public abstract class DiscordEntity extends DiscordSenderBase implements Entity
|
|||
|
||||
@Override
|
||||
public List<Entity> getPassengers() {
|
||||
return Arrays.asList();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package buttondevteam.discordplugin.playerfaker;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.Delegate;
|
||||
import org.bukkit.*;
|
||||
|
@ -16,16 +19,14 @@ import org.bukkit.map.MapView;
|
|||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DiscordFakePlayer extends DiscordHumanEntity implements Player {
|
||||
protected DiscordFakePlayer(IUser user, MessageChannel channel, int entityId, UUID uuid, String mcname) {
|
||||
super(user, channel, entityId, uuid);
|
||||
protected DiscordFakePlayer(User user, MessageChannel channel, int entityId, UUID uuid, String mcname, MinecraftChatModule module) {
|
||||
super(user, channel, entityId, uuid, module);
|
||||
perm = new PermissibleBase(Bukkit.getOfflinePlayer(uuid));
|
||||
name = mcname;
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ public class DiscordFakePlayer extends DiscordHumanEntity implements Player {
|
|||
|
||||
@Override
|
||||
public String getCustomName() {
|
||||
return user.getName();
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,7 +128,7 @@ public class DiscordFakePlayer extends DiscordHumanEntity implements Player {
|
|||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return user.getDisplayName(DiscordPlugin.mainServer);
|
||||
return Objects.requireNonNull(user.asMember(DiscordPlugin.mainServer.getId()).block()).getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package buttondevteam.discordplugin.playerfaker;
|
||||
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -8,14 +11,12 @@ import org.bukkit.entity.HumanEntity;
|
|||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.inventory.*;
|
||||
import org.bukkit.inventory.InventoryView.Property;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class DiscordHumanEntity extends DiscordLivingEntity implements HumanEntity {
|
||||
protected DiscordHumanEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) {
|
||||
super(user, channel, entityId, uuid);
|
||||
protected DiscordHumanEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) {
|
||||
super(user, channel, entityId, uuid, module);
|
||||
}
|
||||
|
||||
private PlayerInventory inv = new DiscordPlayerInventory(this);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package buttondevteam.discordplugin.playerfaker;
|
||||
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import discord4j.core.object.entity.MessageChannel;
|
||||
import discord4j.core.object.entity.User;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Location;
|
||||
|
@ -16,15 +19,13 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.handle.obj.MessageChannel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class DiscordLivingEntity extends DiscordEntity implements LivingEntity {
|
||||
|
||||
protected DiscordLivingEntity(IUser user, MessageChannel channel, int entityId, UUID uuid) {
|
||||
super(user, channel, entityId, uuid);
|
||||
protected DiscordLivingEntity(User user, MessageChannel channel, int entityId, UUID uuid, MinecraftChatModule module) {
|
||||
super(user, channel, entityId, uuid, module);
|
||||
}
|
||||
|
||||
private @Getter EntityEquipment equipment = new DiscordEntityEquipment(this);
|
||||
|
|
Loading…
Reference in a new issue