Update D4J and some bugfixes

The update fixes the numerous errors about a missing status constant
Remove test check (#114)
Improvements and checking for admin permission (#115)
It also checks for channel perms now
This commit is contained in:
Norbi Peti 2019-11-28 00:16:58 +01:00
parent 19463963e3
commit 3a94b6191b
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
7 changed files with 65 additions and 45 deletions

View file

@ -183,7 +183,7 @@
<dependency>
<groupId>com.discord4j</groupId>
<artifactId>discord4j-core</artifactId>
<version>3.0.10</version>
<version>3.0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
<dependency>

View file

@ -157,12 +157,27 @@ public final class DPUtils {
return false;
}
/**
* Send a response in the form of "@User, message". Use Mono.empty() if you don't have a channel object.
*
* @param original The original message to reply to
* @param channel The channel to send the message in, defaults to the original
* @param message The message to send
* @return A mono to send the message
*/
public static Mono<Message> reply(Message original, @Nullable MessageChannel channel, String message) {
Mono<MessageChannel> ch;
if (channel == null)
ch = original.getChannel();
else
ch = Mono.just(channel);
return reply(original, ch, message);
}
/**
* @see #reply(Message, MessageChannel, String)
*/
public static Mono<Message> reply(Message original, Mono<MessageChannel> ch, String message) {
return ch.flatMap(chan -> chan.createMessage((original.getAuthor().isPresent()
? original.getAuthor().get().getMention() + ", " : "") + message));
}

View file

@ -44,7 +44,6 @@ import java.awt.*;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@ -196,14 +195,6 @@ public class DiscordPlugin extends ButtonPlugin {
getConfig().set("serverup", true);
saveConfig();
if (TBMCCoreAPI.IsTestServer() && !Objects.requireNonNull(dc.getSelf().block()).getUsername().toLowerCase().contains("test")) {
TBMCCoreAPI.SendException(
"Won't load because we're in testing mode and not using a separate account.",
new Exception(
"The plugin refuses to load until you change the token to a testing account. (The account needs to have \"test\" in its name.)"
+ "\nYou can disable test mode in ChromaCore config."));
Bukkit.getPluginManager().disablePlugin(this);
}
TBMCCoreAPI.SendUnsentExceptions();
TBMCCoreAPI.SendUnsentDebugMessages();

View file

@ -96,7 +96,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
}
if (msglowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
{
DPUtils.reply(message, null, "Stop it. You know the answer.").subscribe();
DPUtils.reply(message, Mono.empty(), "stop it. You know the answer.").subscribe();
lastlist = 0;
lastlistp = (short) Bukkit.getOnlinePlayers().size();
return true; //Handled
@ -108,7 +108,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
if (usableServerReadyStrings.size() == 0)
fm.createUsableServerReadyStrings();
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size()));
DPUtils.reply(message, null, fm.serverReadyAnswers().get().get(next)).subscribe();
DPUtils.reply(message, Mono.empty(), fm.serverReadyAnswers().get().get(next)).subscribe();
return false; //Still process it as a command/mcchat if needed
}
return false;

View file

@ -62,7 +62,7 @@ public class CommandListener {
try {
timings.printElapsed("F");
if (!DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmdwithargsString))
return DPUtils.reply(message, channel, "Unknown command. Do " + DiscordPlugin.getPrefix() + "help for help.\n" + cmdwithargsString)
return DPUtils.reply(message, channel, "unknown command. Do " + DiscordPlugin.getPrefix() + "help for help.\n" + cmdwithargsString)
.map(m -> false);
} catch (Exception e) {
TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e);

View file

@ -9,12 +9,17 @@ import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.player.TBMCPlayer;
import discord4j.core.object.entity.GuildChannel;
import discord4j.core.object.entity.Message;
import discord4j.core.object.entity.MessageChannel;
import discord4j.core.object.entity.User;
import discord4j.core.object.util.Permission;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.bukkit.Bukkit;
import reactor.core.publisher.Mono;
import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
@ -22,6 +27,7 @@ import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@SuppressWarnings("SimplifyOptionalCallChains") //Java 11
@CommandClass(helpText = {"Channel connect", //
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
@ -36,28 +42,29 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class ChannelconCommand extends ICommand2DC {
private final MinecraftChatModule module;
@Command2.Subcommand
public boolean remove(Command2DCSender sender) {
val message = sender.getMessage();
if (checkPerms(message)) return true;
if (checkPerms(message, null)) return true;
if (MCChatCustom.removeCustomChat(message.getChannelId()))
DPUtils.reply(message, null, "channel connection removed.").subscribe();
DPUtils.reply(message, Mono.empty(), "channel connection removed.").subscribe();
else
DPUtils.reply(message, null, "this channel isn't connected.").subscribe();
DPUtils.reply(message, Mono.empty(), "this channel isn't connected.").subscribe();
return true;
}
@Command2.Subcommand
public boolean toggle(Command2DCSender sender, @Command2.OptionalArg String toggle) {
val message = sender.getMessage();
if (checkPerms(message)) return true;
if (checkPerms(message, null)) return true;
val cc = MCChatCustom.getCustomChat(message.getChannelId());
if (cc == null)
return respond(sender, "this channel isn't connected.");
Supplier<String> togglesString = () -> Arrays.stream(ChannelconBroadcast.values()).map(t -> t.toString().toLowerCase() + ": " + ((cc.toggles & t.flag) == 0 ? "disabled" : "enabled")).collect(Collectors.joining("\n"))
+ "\n\n" + TBMCSystemChatEvent.BroadcastTarget.stream().map(target -> target.getName() + ": " + (cc.brtoggles.contains(target) ? "enabled" : "disabled")).collect(Collectors.joining("\n"));
if (toggle == null) {
DPUtils.reply(message, null, "toggles:\n" + togglesString.get()).subscribe();
DPUtils.reply(message, Mono.empty(), "toggles:\n" + togglesString.get()).subscribe();
return true;
}
String arg = toggle.toUpperCase();
@ -65,7 +72,7 @@ public class ChannelconCommand extends ICommand2DC {
if (!b.isPresent()) {
val bt = TBMCSystemChatEvent.BroadcastTarget.get(arg);
if (bt == null) {
DPUtils.reply(message, null, "cannot find toggle. Toggles:\n" + togglesString.get()).subscribe();
DPUtils.reply(message, Mono.empty(), "cannot find toggle. Toggles:\n" + togglesString.get()).subscribe();
return true;
}
final boolean add;
@ -83,7 +90,7 @@ public class ChannelconCommand extends ICommand2DC {
//1 1 | 0
// XOR
cc.toggles ^= b.get().flag;
DPUtils.reply(message, null, "'" + b.get().toString().toLowerCase() + "' " + ((cc.toggles & b.get().flag) == 0 ? "disabled" : "enabled")).subscribe();
DPUtils.reply(message, Mono.empty(), "'" + b.get().toString().toLowerCase() + "' " + ((cc.toggles & b.get().flag) == 0 ? "disabled" : "enabled")).subscribe();
return true;
}
@ -94,12 +101,13 @@ public class ChannelconCommand extends ICommand2DC {
sender.sendMessage("channel connection is not allowed on this Minecraft server.");
return true;
}
if (checkPerms(message)) return true;
val channel = message.getChannel().block();
if (checkPerms(message, channel)) return true;
if (MCChatCustom.hasCustomChat(message.getChannelId()))
return respond(sender, "this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it.");
val chan = Channel.getChannels().filter(ch -> ch.ID.equalsIgnoreCase(channelID) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(channelID)))).findAny();
if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
DPUtils.reply(message, null, "MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.").subscribe();
DPUtils.reply(message, channel, "MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.").subscribe();
return true;
}
if (!message.getAuthor().isPresent()) return true;
@ -107,19 +115,18 @@ public class ChannelconCommand extends ICommand2DC {
val dp = DiscordPlayer.getUser(author.getId().asString(), DiscordPlayer.class);
val chp = dp.getAs(TBMCPlayer.class);
if (chp == null) {
DPUtils.reply(message, null, "you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>").subscribe();
DPUtils.reply(message, channel, "you need to connect your Minecraft account. On the main server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>").subscribe();
return true;
}
val channel = message.getChannel().block();
DiscordConnectedPlayer dcp = DiscordConnectedPlayer.create(message.getAuthor().get(), channel, chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName(), module);
//Using a fake player with no login/logout, should be fine for this event
String groupid = chan.get().getGroupID(dcp);
if (groupid == null && !(chan.get() instanceof ChatRoom)) { //ChatRooms don't allow it unless the user joins, which happens later
DPUtils.reply(message, null, "sorry, you cannot use that Minecraft channel.").subscribe();
DPUtils.reply(message, channel, "sorry, you cannot use that Minecraft channel.").subscribe();
return true;
}
if (chan.get() instanceof ChatRoom) { //ChatRooms don't work well
DPUtils.reply(message, null, "chat rooms are not supported yet.").subscribe();
DPUtils.reply(message, channel, "chat rooms are not supported yet.").subscribe();
return true;
}
/*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
@ -128,16 +135,23 @@ public class ChannelconCommand extends ICommand2DC {
}*/ //TODO: "Channel admins" that can connect channels?
MCChatCustom.addCustomChat(channel, groupid, chan.get(), author, dcp, 0, new HashSet<>());
if (chan.get() instanceof ChatRoom)
DPUtils.reply(message, null, "alright, connection made to the room!").subscribe();
DPUtils.reply(message, channel, "alright, connection made to the room!").subscribe();
else
DPUtils.reply(message, null, "alright, connection made to group `" + groupid + "`!").subscribe();
DPUtils.reply(message, channel, "alright, connection made to group `" + groupid + "`!").subscribe();
return true;
}
@SuppressWarnings("ConstantConditions")
private boolean checkPerms(Message message) {
if (!message.getAuthorAsMember().block().getBasePermissions().block().contains(Permission.MANAGE_CHANNELS)) {
DPUtils.reply(message, null, "you need to have manage permissions for this channel!").subscribe();
private boolean checkPerms(Message message, @Nullable MessageChannel channel) {
if (channel == null)
channel = message.getChannel().block();
if (!(channel instanceof GuildChannel)) {
DPUtils.reply(message, channel, "you can only use this command in a server!").subscribe();
return true;
}
var perms = ((GuildChannel) channel).getEffectivePermissions(message.getAuthor().map(User::getId).get()).block();
if (!perms.contains(Permission.ADMINISTRATOR) && !perms.contains(Permission.MANAGE_CHANNELS)) {
DPUtils.reply(message, channel, "you need to have manage permissions for this channel!").subscribe();
return true;
}
return false;
@ -145,17 +159,17 @@ public class ChannelconCommand extends ICommand2DC {
@Override
public String[] getHelpText(Method method, Command2.Subcommand ann) {
return new String[]{ //
"Channel connect", //
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
"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.", //
return new String[]{ //
"Channel connect", //
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
"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: " + Objects.requireNonNull(DiscordPlugin.dc.getSelf().block()).getMention() + " 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() + ".", //
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=" + DiscordPlugin.dc.getApplicationInfo().map(info -> info.getId().asString()).blockOptional().orElse("Unknown") + "&scope=bot&permissions=268509264>"
};
}
"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() + ".", //
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=" + DiscordPlugin.dc.getApplicationInfo().map(info -> info.getId().asString()).blockOptional().orElse("Unknown") + "&scope=bot&permissions=268509264>"
};
}
}

View file

@ -33,13 +33,13 @@ public class MCChatCommand extends ICommand2DC {
val channel = message.getChannel().block();
@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();
DPUtils.reply(message, channel, "this command can only be issued in a direct message with the bot.").subscribe();
return true;
}
try (final DiscordPlayer user = DiscordPlayer.getUser(author.getId().asString(), DiscordPlayer.class)) {
boolean mcchat = !user.isMinecraftChatEnabled();
MCChatPrivate.privateMCChat(channel, mcchat, author, user);
DPUtils.reply(message, null, "Minecraft chat " + (mcchat //
DPUtils.reply(message, channel, "Minecraft chat " + (mcchat //
? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
: "disabled.")).subscribe();
} catch (Exception e) {