It compiles!

And I thought this is gonna be easy
#93
This commit is contained in:
Norbi Peti 2019-04-25 02:50:55 +02:00
parent 2500572e0d
commit e2e8a58c4e
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
16 changed files with 173 additions and 190 deletions

View file

@ -1,27 +0,0 @@
package buttondevteam.discordplugin;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@RequiredArgsConstructor
public class AsyncDiscordEvent<T extends sx.blah.discord.api.events.Event> extends Event implements Cancellable {
private final @Getter T event;
@Getter
@Setter
private boolean cancelled;
private static final HandlerList handlers = new HandlerList();
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View file

@ -16,8 +16,8 @@ import java.util.regex.Matcher;
public final class DPUtils { public final class DPUtils {
public static EmbedCreateSpec embedWithHead(EmbedCreateSpec ecs, String playername, String profileUrl) { public static EmbedCreateSpec embedWithHead(EmbedCreateSpec ecs, String displayname, String playername, String profileUrl) {
return ecs.setAuthor(playername, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png"); return ecs.setAuthor(displayname, profileUrl, "https://minotar.net/avatar/" + playername + "/32.png");
} }
/** /**

View file

@ -73,6 +73,13 @@ public class DiscordPlugin extends ButtonPlugin {
return DPUtils.roleData(getIConfig(), "modRole", "Moderator"); return DPUtils.roleData(getIConfig(), "modRole", "Moderator");
} }
/**
* The invite link to show by /discord invite. If empty, it defaults to the first invite if the bot has access.
*/
public ConfigData<String> InviteLink() {
return getIConfig().getData("inviteLink", "");
}
@Override @Override
public void pluginEnable() { public void pluginEnable() {
try { try {

View file

@ -1,10 +0,0 @@
package buttondevteam.discordplugin;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.MissingPermissionsException;
import sx.blah.discord.util.RateLimitException;
@FunctionalInterface
public interface DiscordRunnable {
void run() throws DiscordException, RateLimitException, MissingPermissionsException;
}

View file

@ -1,7 +1,6 @@
package buttondevteam.discordplugin.commands; package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
@ -28,34 +27,37 @@ public class ConnectCommand extends ICommand2DC {
@Command2.Subcommand @Command2.Subcommand
public boolean def(Command2DCSender sender, String Minecraftname) { public boolean def(Command2DCSender sender, String Minecraftname) {
val message = sender.getMessage(); val message = sender.getMessage();
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getId().asString())) { val channel = message.getChannel().block();
DiscordPlugin.sendMessageToChannel(message.getChannel(), val author = message.getAuthor().orElse(null);
"Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getId().asString()) + " with " + Minecraftname); if (author == null || channel == null) return true;
WaitingToConnect.inverse().remove(message.getAuthor().getId().asString()); if (WaitingToConnect.inverse().containsKey(author.getId().asString())) {
channel.createMessage(
"Replacing " + WaitingToConnect.inverse().get(author.getId().asString()) + " with " + Minecraftname).subscribe();
WaitingToConnect.inverse().remove(author.getId().asString());
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname); OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname);
if (p == null) { if (p == null) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found"); channel.createMessage("The specified Minecraft player cannot be found").subscribe();
return true; return true;
} }
try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) {
DiscordPlayer dp = pl.getAs(DiscordPlayer.class); DiscordPlayer dp = pl.getAs(DiscordPlayer.class);
if (dp != null && message.getAuthor().getId().asString().equals(dp.getDiscordID())) { if (dp != null && author.getId().asString().equals(dp.getDiscordID())) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); channel.createMessage("You already have this account connected.").subscribe();
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e);
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e); channel.createMessage("An internal error occured!\n" + e).subscribe();
} }
WaitingToConnect.put(p.getName(), message.getAuthor().getId().asString()); WaitingToConnect.put(p.getName(), author.getId().asString());
DiscordPlugin.sendMessageToChannel(message.getChannel(), channel.createMessage(
"Alright! Now accept the connection in Minecraft from the account " + Minecraftname "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."); + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.").subscribe();
if (p.isOnline()) if (p.isOnline())
((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#" ((Player) p).sendMessage("§bTo connect with the Discord account " + author.getUsername() + "#"
+ message.getAuthor().getDiscriminator() + " do /discord accept"); + author.getDiscriminator() + " do /discord accept");
return true; return true;
} }

View file

@ -11,10 +11,14 @@ import buttondevteam.lib.chat.CommandClass;
public class DebugCommand extends ICommand2DC { public class DebugCommand extends ICommand2DC {
@Command2.Subcommand @Command2.Subcommand
public boolean def(Command2DCSender sender, String args) { public boolean def(Command2DCSender sender, String args) {
if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get())) sender.getMessage().getAuthorAsMember()
sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled")); .map(m -> m.getRoleIds().stream().anyMatch(r -> r.equals(DiscordPlugin.plugin.ModRole().get().getId())))
else .subscribe(success -> {
sender.sendMessage("you need to be a moderator to use this command."); if (success)
return true; sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled"));
} else
sender.sendMessage("you need to be a moderator to use this command.");
});
return true;
}
} }

View file

@ -7,13 +7,11 @@ import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
import discord4j.core.object.entity.Message;
import discord4j.core.object.entity.User;
import lombok.val; import lombok.val;
import sx.blah.discord.handle.obj.User;
import sx.blah.discord.handle.obj.Message;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@CommandClass(helpText = { @CommandClass(helpText = {
"User information", // "User information", //
@ -25,20 +23,21 @@ public class UserinfoCommand extends ICommand2DC {
public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) { public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) {
val message = sender.getMessage(); val message = sender.getMessage();
User target = null; User target = null;
val channel = message.getChannel().block();
assert channel != null;
if (user == null || user.length() == 0) if (user == null || user.length() == 0)
target = message.getAuthor(); target = message.getAuthor().orElse(null);
else { else {
final Optional<User> firstmention = message.getMentions().stream() @SuppressWarnings("OptionalGetWithoutIsPresent") final User firstmention = message.getUserMentions()
.filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelf().getId().asString())).findFirst(); .filter(m -> !m.getId().asString().equals(DiscordPlugin.dc.getSelfId().get().asString())).blockFirst();
if (firstmention.isPresent()) if (firstmention != null)
target = firstmention.get(); target = firstmention;
else if (user.contains("#")) { else if (user.contains("#")) {
String[] targettag = user.split("#"); String[] targettag = user.split("#");
final List<User> targets = getUsers(message, targettag[0]); final List<User> targets = getUsers(message, targettag[0]);
if (targets.size() == 0) { if (targets.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), channel.createMessage("The user cannot be found (by name): " + user).subscribe();
"The user cannot be found (by name): " + user); return true;
return true;
} }
for (User ptarget : targets) { for (User ptarget : targets) {
if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) {
@ -47,44 +46,47 @@ public class UserinfoCommand extends ICommand2DC {
} }
} }
if (target == null) { if (target == null) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), channel.createMessage("The user cannot be found (by discriminator): " + user + "(Found " + targets.size()
"The user cannot be found (by discriminator): " + user + "(Found " + targets.size() + " users with the name.)").subscribe();
+ " users with the name.)"); return true;
return true;
} }
} else { } else {
final List<User> targets = getUsers(message, user); final List<User> targets = getUsers(message, user);
if (targets.size() == 0) { if (targets.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), channel.createMessage("The user cannot be found on Discord: " + user).subscribe();
"The user cannot be found on Discord: " + user); return true;
return true;
} }
if (targets.size() > 1) { if (targets.size() > 1) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), channel.createMessage("Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.").subscribe();
"Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping."); return true;
return true;
} }
target = targets.get(0); target = targets.get(0);
} }
} }
try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getId().asString(), DiscordPlayer.class)) { if (target == null) {
StringBuilder uinfo = new StringBuilder("User info for ").append(target.getName()).append(":\n"); sender.sendMessage("An error occurred.");
uinfo.append(dp.getInfo(InfoTarget.Discord)); return true;
DiscordPlugin.sendMessageToChannel(message.getChannel(), uinfo.toString());
} catch (Exception e) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while getting the user!");
TBMCCoreAPI.SendException("Error while getting info about " + target.getName() + "!", e);
} }
return true; try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getId().asString(), DiscordPlayer.class)) {
StringBuilder uinfo = new StringBuilder("User info for ").append(target.getUsername()).append(":\n");
uinfo.append(dp.getInfo(InfoTarget.Discord));
channel.createMessage(uinfo.toString()).subscribe();
} catch (Exception e) {
channel.createMessage("An error occured while getting the user!").subscribe();
TBMCCoreAPI.SendException("Error while getting info about " + target.getUsername() + "!", e);
}
return true;
} }
private List<User> getUsers(Message message, String args) { private List<User> getUsers(Message message, String args) {
final List<User> targets; final List<User> targets;
if (message.getChannel().isPrivate()) val guild = message.getGuild().block();
targets = DiscordPlugin.dc.getUsers().stream().filter(u -> u.getName().equalsIgnoreCase(args)) if (guild == null) //Private channel
.collect(Collectors.toList()); targets = DiscordPlugin.dc.getUsers().filter(u -> u.getUsername().equalsIgnoreCase(args))
.collectList().block();
else else
targets = message.getGuild().getUsersByName(args, true); targets = guild.getMembers().filter(m -> m.getUsername().equalsIgnoreCase(args))
.map(m -> (User) m).collectList().block();
return targets; return targets;
} }

View file

@ -3,10 +3,11 @@ package buttondevteam.discordplugin.exceptions;
import buttondevteam.core.ComponentManager; import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCDebugMessageEvent; import buttondevteam.lib.TBMCDebugMessageEvent;
import discord4j.core.object.entity.MessageChannel;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
public class DebugMessageListener implements Listener{ public class DebugMessageListener implements Listener {
@EventHandler @EventHandler
public void onDebugMessage(TBMCDebugMessageEvent e) { public void onDebugMessage(TBMCDebugMessageEvent e) {
SendMessage(e.getDebugMessage()); SendMessage(e.getDebugMessage());
@ -17,13 +18,15 @@ public class DebugMessageListener implements Listener{
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(ExceptionListenerModule.class)) if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(ExceptionListenerModule.class))
return; return;
try { try {
MessageChannel mc = ExceptionListenerModule.getChannel();
if (mc == null) return;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("```").append("\n"); sb.append("```").append("\n");
if (message.length() > 2000) if (message.length() > 2000)
message = message.substring(0, 2000); message = message.substring(0, 2000);
sb.append(message).append("\n"); sb.append(message).append("\n");
sb.append("```"); sb.append("```");
DiscordPlugin.sendMessageToChannel(ExceptionListenerModule.getChannel(), sb.toString()); mc.createMessage(sb.toString()).subscribe();
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }

View file

@ -19,7 +19,7 @@ public class CommandListener {
* @return Whether it ran the command * @return Whether it ran the command
*/ */
public static boolean runCommand(Message message, boolean mentionedonly) { public static boolean runCommand(Message message, boolean mentionedonly) {
if (message.getContent().isEmpty()) if (!message.getContent().isPresent())
return false; //Pin messages and such, let the mcchat listener deal with it return false; //Pin messages and such, let the mcchat listener deal with it
final MessageChannel channel = message.getChannel().block(); final MessageChannel channel = message.getChannel().block();
@SuppressWarnings("OptionalGetWithoutIsPresent") val content = message.getContent().get(); @SuppressWarnings("OptionalGetWithoutIsPresent") val content = message.getContent().get();

View file

@ -1,5 +1,6 @@
package buttondevteam.discordplugin.mcchat; package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.Command2DCSender; import buttondevteam.discordplugin.commands.Command2DCSender;
@ -7,6 +8,7 @@ import buttondevteam.discordplugin.commands.ICommand2DC;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import discord4j.core.object.entity.PrivateChannel;
import lombok.val; import lombok.val;
@CommandClass(helpText = { @CommandClass(helpText = {
@ -20,18 +22,20 @@ public class MCChatCommand extends ICommand2DC {
@Command2.Subcommand @Command2.Subcommand
public boolean def(Command2DCSender sender) { public boolean def(Command2DCSender sender) {
val message = sender.getMessage(); val message = sender.getMessage();
if (!message.getChannel().isPrivate()) { val channel = message.getChannel().block();
DPUtils.reply(message, null, "this command can only be issued in a direct message with the bot."); @SuppressWarnings("OptionalGetWithoutIsPresent") val author = message.getAuthor().get();
if (!(channel instanceof PrivateChannel)) {
DPUtils.reply(message, null, "this command can only be issued in a direct message with the bot.").subscribe();
return true; return true;
} }
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getId().asString(), DiscordPlayer.class)) { try (final DiscordPlayer user = DiscordPlayer.getUser(author.getId().asString(), DiscordPlayer.class)) {
boolean mcchat = !user.isMinecraftChatEnabled(); boolean mcchat = !user.isMinecraftChatEnabled();
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user); MCChatPrivate.privateMCChat(channel, mcchat, author, user);
DPUtils.reply(message, null, "Minecraft chat " + (mcchat // DPUtils.reply(message, null, "Minecraft chat " + (mcchat //
? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." // ? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
: "disabled.")); : "disabled.")).subscribe();
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e); TBMCCoreAPI.SendException("Error while setting mcchat for user " + author.getUsername() + "#" + author.getDiscriminator(), e);
} }
return true; return true;
} // TODO: Pin channel switching to indicate the current channel } // TODO: Pin channel switching to indicate the current channel

View file

@ -15,10 +15,8 @@ import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import com.vdurmont.emoji.EmojiParser; import com.vdurmont.emoji.EmojiParser;
import discord4j.core.event.domain.message.MessageCreateEvent; import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.MessageChannel; import discord4j.core.object.Embed;
import discord4j.core.object.entity.PrivateChannel; import discord4j.core.object.entity.*;
import discord4j.core.object.entity.TextChannel;
import discord4j.core.object.entity.User;
import discord4j.core.spec.EmbedCreateSpec; import discord4j.core.spec.EmbedCreateSpec;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -34,6 +32,7 @@ import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -75,46 +74,39 @@ public class MCChatListener implements Listener {
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " // final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName().get()) + "] " //
+ ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") // + ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") //
+ (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player // + (DPUtils.sanitizeStringNoEscape(ThorpeUtils.getDisplayName(e.getSender())));
? ((Player) e.getSender()).getDisplayName() //
: e.getSender().getName()));
val color = e.getChannel().Color().get(); val color = e.getChannel().Color().get();
final EmbedCreateSpec embed = new EmbedBuilder().withAuthorName(authorPlayer) final Consumer<EmbedCreateSpec> embed = ecs -> {
.withDescription(e.getMessage()).withColor(new Color(color.getRed(), ecs.setDescription(e.getMessage()).setColor(new Color(color.getRed(),
color.getGreen(), color.getBlue())); color.getGreen(), color.getBlue()));
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "") if (e.getSender() instanceof Player)
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false); DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(),
if (e.getSender() instanceof Player) "https://tbmcplugins.github.io/profile.html?type=minecraft&id="
DPUtils.embedWithHead( + ((Player) e.getSender()).getUniqueId());
embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id=" else if (e.getSender() instanceof DiscordSenderBase)
+ ((Player) e.getSender()).getUniqueId()), ecs.setAuthor(authorPlayer, "https://tbmcplugins.github.io/profile.html?type=discord&id=" // TODO: Constant/method to get URLs like this
e.getSender().getName()); + ((DiscordSenderBase) e.getSender()).getUser().getId().asString(),
else if (e.getSender() instanceof DiscordSenderBase) ((DiscordSenderBase) e.getSender()).getUser().getAvatarUrl());
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL()) else
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id=" DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), null);
+ ((DiscordSenderBase) e.getSender()).getUser().getId().asString()); // TODO: Constant/method to get URLs like this ecs.setTimestamp(time);
// embed.withFooterText(e.getChannel().DisplayName); };
embed.withTimestamp(time);
final long nanoTime = System.nanoTime(); final long nanoTime = System.nanoTime();
InterruptibleConsumer<MCChatUtils.LastMsgData> doit = lastmsgdata -> { InterruptibleConsumer<MCChatUtils.LastMsgData> doit = lastmsgdata -> {
final EmbedObject embedObject = embed.build(); if (lastmsgdata.message == null
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted() || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().map(Embed.Author::getName).orElse(null))
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120 || lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) { || !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, "", lastmsgdata.message = lastmsgdata.channel.createEmbed(embed).block();
embedObject); // TODO Use ChromaBot API
lastmsgdata.time = nanoTime; lastmsgdata.time = nanoTime;
lastmsgdata.mcchannel = e.getChannel(); lastmsgdata.mcchannel = e.getChannel();
lastmsgdata.content = embedObject.description; lastmsgdata.content = e.getMessage();
} else } else {
try { lastmsgdata.content = lastmsgdata.content + "\n"
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n" + e.getMessage(); // The message object doesn't get updated
+ embedObject.description;// The message object doesn't get updated lastmsgdata.message.edit(mes -> mes.setEmbed(embed.andThen(ecs ->
lastmsgdata.message.edit(mes -> mes.setEmbed(ecs -> embedObject)).block(); ecs.setDescription(lastmsgdata.content)))).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 // Checks if the given channel is different than where the message was sent from
// Or if it was from MC // Or if it was from MC
@ -124,12 +116,12 @@ public class MCChatListener implements Listener {
if (e.getChannel().isGlobal() if (e.getChannel().isGlobal()
&& (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get()))) && (e.isFromCommand() || isdifferentchannel.test(module.chatChannel().get())))
doit.accept(MCChatUtils.lastmsgdata == null doit.accept(MCChatUtils.lastmsgdata == null
? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData((TextChannel) module.chatChannel().get(), null) ? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(module.chatChannel().get(), null)
: MCChatUtils.lastmsgdata); : MCChatUtils.lastmsgdata);
for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) { for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) {
if ((e.isFromCommand() || isdifferentchannel.test(data.channel)) if ((e.isFromCommand() || isdifferentchannel.test(data.channel))
&& e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user))) && e.shouldSendTo(MCChatUtils.getSender(data.channel.getId(), data.user)))
doit.accept(data); doit.accept(data);
} }
@ -143,7 +135,7 @@ public class MCChatListener implements Listener {
doit.accept(lmd); doit.accept(lmd);
else { else {
iterator.remove(); //If the user no longer has permission, remove the connection 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."); lmd.channel.createMessage("The user no longer has permission to view the channel, connection removed.").subscribe();
} }
} }
} }
@ -271,13 +263,16 @@ public class MCChatListener implements Listener {
final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannelId(), sender); final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannelId(), sender);
val user = dsender.getChromaUser(); val user = dsender.getChromaUser();
for (User u : event.getMessage().getUserMentions()) { //TODO: Role mentions for (User u : event.getMessage().getUserMentions().toIterable()) { //TODO: Role mentions
dmessage = dmessage.replace(u.me(false), "@" + u.getName()); // TODO: IG Formatting dmessage = dmessage.replace(u.getMention(), "@" + u.getUsername()); // TODO: IG Formatting
final String nick = u.getNicknameForGuild(DiscordPlugin.mainServer); val m = u.asMember(DiscordPlugin.mainServer.getId()).block();
dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); if (m != null) {
final String nick = m.getDisplayName();
dmessage = dmessage.replace(m.getNicknameMention(), "@" + nick);
}
} }
for (MessageChannel ch : event.getMessage().getChannelMentions()) { for (GuildChannel ch : event.getGuild().flux().flatMap(Guild::getChannels).toIterable()) {
dmessage = dmessage.replace(ch.mention(), "#" + ch.getName()); // TODO: IG Formatting dmessage = dmessage.replace(ch.getMention(), "#" + ch.getName()); // TODO: IG Formatting
} }
dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?) dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?)
@ -285,18 +280,18 @@ public class MCChatListener implements Listener {
Function<String, String> getChatMessage = msg -> // Function<String, String> getChatMessage = msg -> //
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
.getAttachments().stream().map(Message.Attachment::getUrl).collect(Collectors.joining("\n")) .getAttachments().stream().map(Attachment::getUrl).collect(Collectors.joining("\n"))
: ""); : "");
MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel()); MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getMessage().getChannelId());
boolean react = false; boolean react = false;
val sendChannel = event.getMessage().getChannel().block();
boolean isPrivate = sendChannel instanceof PrivateChannel;
if (dmessage.startsWith("/")) { // Ingame command if (dmessage.startsWith("/")) { // Ingame command
DPUtils.perform(() -> { if (!isPrivate)
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) event.getMessage().delete().subscribe();
event.getMessage().delete();
});
final String cmd = dmessage.substring(1); final String cmd = dmessage.substring(1);
final String cmdlowercased = cmd.toLowerCase(); final String cmdlowercased = cmd.toLowerCase();
if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream() if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream()
@ -338,7 +333,7 @@ public class MCChatListener implements Listener {
}); });
else { else {
Channel chc = ch.get(); Channel chc = ch.get();
if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate()) if (!chc.isGlobal() && !isPrivate)
dsender.sendMessage( dsender.sendMessage(
"You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels."); "You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels.");
else { else {
@ -369,7 +364,7 @@ public class MCChatListener implements Listener {
} }
} else {// Not a command } else {// Not a command
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) { && !isPrivate && event.getMessage().getType() == Message.Type.CHANNEL_PINNED_MESSAGE) {
val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp) val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp)
: dsender.getChromaUser().channel().get().getRTR(dsender); : dsender.getChromaUser().channel().get().getRTR(dsender);
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr, TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
@ -386,16 +381,15 @@ public class MCChatListener implements Listener {
} }
if (react) { if (react) {
try { try {
val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getId().asLong()); val lmfd = MCChatUtils.lastmsgfromd.get(event.getMessage().getChannelId().asLong());
if (lmfd != null) { if (lmfd != null) {
DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getSelf(), lmfd.removeSelfReaction(DiscordPlugin.DELIVERED_REACTION).subscribe(); // Remove it no matter what, we know it's there 99.99% of the time
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
} }
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e); TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
} }
MCChatUtils.lastmsgfromd.put(event.getChannel().getId().asLong(), event.getMessage()); MCChatUtils.lastmsgfromd.put(event.getMessage().getChannelId().asLong(), event.getMessage());
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION)); event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION).subscribe();
} }
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e); TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);

View file

@ -1,18 +1,19 @@
package buttondevteam.discordplugin.mcchat; package buttondevteam.discordplugin.mcchat;
import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.DiscordConnectedPlayer; import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.discordplugin.DiscordPlayer; import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import discord4j.core.object.entity.MessageChannel; import discord4j.core.object.entity.MessageChannel;
import discord4j.core.object.entity.PrivateChannel;
import discord4j.core.object.entity.TextChannel;
import discord4j.core.object.entity.User;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import sx.blah.discord.handle.obj.IPrivateChannel;
import sx.blah.discord.handle.obj.User;
import sx.blah.discord.handle.obj.MessageChannel;
import java.util.ArrayList; import java.util.ArrayList;
@ -28,13 +29,14 @@ public class MCChatPrivate {
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
val p = Bukkit.getPlayer(mcp.getUUID()); val p = Bukkit.getPlayer(mcp.getUUID());
val op = Bukkit.getOfflinePlayer(mcp.getUUID()); val op = Bukkit.getOfflinePlayer(mcp.getUUID());
val mcm = ComponentManager.getIfEnabled(MinecraftChatModule.class);
if (start) { if (start) {
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName(), mcm);
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender); MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender);
if (p == null)// Player is offline - If the player is online, that takes precedence if (p == null)// Player is offline - If the player is online, that takes precedence
callEventSync(new PlayerJoinEvent(sender, "")); callEventSync(new PlayerJoinEvent(sender, ""));
} else { } else {
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel, user); val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId(), user);
if (p == null)// Player is offline - If the player is online, that takes precedence if (p == null)// Player is offline - If the player is online, that takes precedence
callEventSync(new PlayerQuitEvent(sender, "")); callEventSync(new PlayerQuitEvent(sender, ""));
} }
@ -42,8 +44,8 @@ public class MCChatPrivate {
if (!start) if (!start)
MCChatUtils.lastmsgfromd.remove(channel.getId().asLong()); MCChatUtils.lastmsgfromd.remove(channel.getId().asLong());
return start // return start //
? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs ? lastmsgPerUser.add(new MCChatUtils.LastMsgData((TextChannel) channel, user)) // Doesn't support group DMs
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong()); : lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong());
} }
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) { public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
@ -52,7 +54,8 @@ public class MCChatPrivate {
public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this
return lastmsgPerUser.stream() return lastmsgPerUser.stream()
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getId().asString().equals(did)); .anyMatch(lmd -> ((PrivateChannel) lmd.channel)
.getRecipientIds().stream().anyMatch(u -> u.asString().equals(did)));
} }
public static void logoutAll() { public static void logoutAll() {

View file

@ -3,6 +3,7 @@ package buttondevteam.discordplugin.mcchat;
import buttondevteam.core.ComponentManager; import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.*; import buttondevteam.discordplugin.*;
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.TBMCSystemChatEvent;
import discord4j.core.object.entity.*; import discord4j.core.object.entity.*;
import discord4j.core.object.util.Snowflake; import discord4j.core.object.util.Snowflake;
@ -60,7 +61,12 @@ public class MCChatUtils {
} }
private static void updatePL(LastMsgData lmd) { private static void updatePL(LastMsgData lmd) {
String topic = lmd.channel.getTopic().orElse(""); if (!(lmd.channel instanceof TextChannel)) {
TBMCCoreAPI.SendException("Failed to update player list for channel " + lmd.channel.getId(),
new Exception("The channel isn't a (guild) text channel."));
return;
}
String topic = ((TextChannel) lmd.channel).getTopic().orElse("");
if (topic.length() == 0) if (topic.length() == 0)
topic = ".\n----\nMinecraft chat\n----\n."; topic = ".\n----\nMinecraft chat\n----\n.";
String[] s = topic.split("\\n----\\n"); String[] s = topic.split("\\n----\\n");
@ -70,7 +76,7 @@ public class MCChatUtils {
+ " online"; + " online";
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream() s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", ")); .map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
lmd.channel.edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait ((TextChannel) lmd.channel).edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait
} }
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders, public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
@ -204,7 +210,7 @@ public class MCChatUtils {
public static void resetLastMessage(Channel channel) { public static void resetLastMessage(Channel channel) {
if (notEnabled()) return; if (notEnabled()) return;
if (channel.getId().asLong() == module.chatChannel().get().getId().asLong()) { if (channel.getId().asLong() == module.chatChannel().get().getId().asLong()) {
(lastmsgdata == null ? lastmsgdata = new LastMsgData((TextChannel) module.chatChannel().get(), null) (lastmsgdata == null ? lastmsgdata = new LastMsgData(module.chatChannel().get(), null)
: lastmsgdata).message = null; : lastmsgdata).message = null;
return; return;
} // Don't set the whole object to null, the player and channel information should be preserved } // Don't set the whole object to null, the player and channel information should be preserved
@ -285,8 +291,8 @@ public class MCChatUtils {
public Message message; public Message message;
public long time; public long time;
public String content; public String content;
public final TextChannel channel; public final MessageChannel channel;
public Channel mcchannel; public buttondevteam.core.component.channel.Channel mcchannel;
public final User user; public final User user;
} }
} }

View file

@ -78,7 +78,7 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin());
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled
getPlugin().getManager().registerCommand(new MCChatCommand()); getPlugin().getManager().registerCommand(new MCChatCommand());
getPlugin().getManager().registerCommand(new ChannelconCommand()); getPlugin().getManager().registerCommand(new ChannelconCommand(this));
val chcons = getConfig().getConfig().getConfigurationSection("chcons"); val chcons = getConfig().getConfig().getConfigurationSection("chcons");
if (chcons == null) //Fallback to old place if (chcons == null) //Fallback to old place

View file

@ -8,16 +8,15 @@ import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.discordplugin.commands.VersionCommand; import buttondevteam.discordplugin.commands.VersionCommand;
import buttondevteam.discordplugin.mcchat.MCChatUtils; import buttondevteam.discordplugin.mcchat.MCChatUtils;
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.Command2MCSender;
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.chat.ICommand2MC;
import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase; import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import reactor.core.publisher.Mono;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -98,11 +97,16 @@ public class DiscordMCCommand extends ICommand2MC {
"Shows an invite link to the server" "Shows an invite link to the server"
}) })
public void invite(CommandSender sender) { public void invite(CommandSender sender) {
val inv=DiscordPlugin.mainServer.getExtendedInvites().stream().findAny(); //TODO: Needs manage server perms String invi = DiscordPlugin.plugin.InviteLink().get();
if (!inv.isPresent()) if (invi.length() > 0) {
sender.sendMessage("§cNo invites found for the server."); sender.sendMessage("§bInvite link: " + invi);
else return;
sender.sendMessage("§bInvite link: https://discord.gg/"+inv.get().getCode()); }
DiscordPlugin.mainServer.getInvites().limitRequest(1)
.switchIfEmpty(Mono.fromRunnable(() -> sender.sendMessage("§cNo invites found for the server.")))
.subscribe(inv -> {//TODO: Needs manage server perms
sender.sendMessage("§bInvite link: https://discord.gg/" + inv.getCode());
});
} }
@Override @Override

View file

@ -1,9 +0,0 @@
package buttondevteam.discordplugin.mccommands;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.PlayerCommandBase;
@CommandClass(modOnly = false, path = "discord")
public abstract class DiscordMCCommandBase extends PlayerCommandBase {
}