Refactoring & made mcchat teleport config

This commit is contained in:
Norbi Peti 2019-04-24 13:29:52 +02:00
parent 95af050517
commit 038cb98f1a
22 changed files with 488 additions and 445 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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.");

View file

@ -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());

View file

@ -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())

View file

@ -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);

View file

@ -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())

View file

@ -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() + ".", //

View file

@ -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 //

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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() {

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);