() {
@Override
diff --git a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java
index 2f99b56..c23b8fa 100755
--- a/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java
+++ b/src/main/java/buttondevteam/discordplugin/listeners/MCListener.java
@@ -5,21 +5,11 @@ import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
import buttondevteam.lib.player.TBMCPlayerJoinEvent;
-import lombok.val;
-import org.bukkit.Bukkit;
-import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerCommandEvent;
-import org.bukkit.plugin.AuthorNagException;
-import org.bukkit.plugin.Plugin;
-import org.bukkit.plugin.RegisteredListener;
import sx.blah.discord.handle.obj.IUser;
-import java.util.Arrays;
-import java.util.logging.Level;
-
public class MCListener implements Listener {
@EventHandler
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
@@ -50,67 +40,4 @@ public class MCListener implements Listener {
public void onServerCommand(ServerCommandEvent e) {
DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped
}
-
- private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises", "JourneyMapServer"}; //TODO: Make configurable
-
- public static void callEventExcludingSome(Event event) {
- callEventExcluding(event, false, EXCLUDED_PLUGINS);
- }
-
- /**
- * Calls an event with the given details.
- *
- * This method only synchronizes when the event is not asynchronous.
- *
- * @param event Event details
- * @param only Flips the operation and includes the listed plugins
- * @param plugins The plugins to exclude. Not case sensitive.
- */
- public static void callEventExcluding(Event event, boolean only, String... plugins) { // Copied from Spigot-API and modified a bit
- if (event.isAsynchronous()) {
- if (Thread.holdsLock(Bukkit.getPluginManager())) {
- throw new IllegalStateException(
- event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
- }
- if (Bukkit.getServer().isPrimaryThread()) {
- throw new IllegalStateException(
- event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
- }
- fireEventExcluding(event, only, plugins);
- } else {
- synchronized (Bukkit.getPluginManager()) {
- fireEventExcluding(event, only, plugins);
- }
- }
- }
-
- private static void fireEventExcluding(Event event, boolean only, String... plugins) {
- HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API
- RegisteredListener[] listeners = handlers.getRegisteredListeners();
- val server = Bukkit.getServer();
-
- for (RegisteredListener registration : listeners) {
- if (!registration.getPlugin().isEnabled()
- || Arrays.stream(plugins).anyMatch(p -> only ^ p.equalsIgnoreCase(registration.getPlugin().getName())))
- continue; // Modified to exclude plugins
-
- try {
- registration.callEvent(event);
- } catch (AuthorNagException ex) {
- Plugin plugin = registration.getPlugin();
-
- if (plugin.isNaggable()) {
- plugin.setNaggable(false);
-
- server.getLogger().log(Level.SEVERE,
- String.format("Nag author(s): '%s' of '%s' about the following: %s",
- plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(),
- ex.getMessage()));
- }
- } catch (Throwable ex) {
- server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to "
- + registration.getPlugin().getDescription().getFullName(), ex);
- }
- }
- }
}
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java
new file mode 100644
index 0000000..2bd2bb6
--- /dev/null
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java
@@ -0,0 +1,150 @@
+package buttondevteam.discordplugin.mcchat;
+
+import buttondevteam.core.component.channel.Channel;
+import buttondevteam.core.component.channel.ChatRoom;
+import buttondevteam.discordplugin.*;
+import buttondevteam.discordplugin.commands.Command2DCSender;
+import buttondevteam.discordplugin.commands.ICommand2DC;
+import buttondevteam.lib.TBMCSystemChatEvent;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.player.TBMCPlayer;
+import lombok.val;
+import org.bukkit.Bukkit;
+import sx.blah.discord.handle.obj.IMessage;
+import sx.blah.discord.handle.obj.Permissions;
+import sx.blah.discord.util.PermissionUtils;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+@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.", //
+ "You also need to have your Minecraft account connected. In #bot use /connect .", //
+ "Call this command from the channel you want to use.", //
+ "Usage: @Bot channelcon ", //
+ "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 / prefix only works in #bot.", //
+ "Invite link: " //
+})
+public class ChannelconCommand extends ICommand2DC {
+ @Command2.Subcommand
+ public boolean remove(Command2DCSender sender) {
+ val message = sender.getMessage();
+ if (checkPerms(message)) return true;
+ if (MCChatCustom.removeCustomChat(message.getChannel()))
+ message.reply("channel connection removed.");
+ else
+ message.reply("this channel isn't connected.");
+ return true;
+ }
+
+ @Command2.Subcommand
+ public boolean toggle(Command2DCSender sender, @Command2.OptionalArg String toggle) {
+ val message = sender.getMessage();
+ if (checkPerms(message)) return true;
+ val cc = MCChatCustom.getCustomChat(message.getChannel());
+ if (cc == null)
+ return respond(sender, "this channel isn't connected.");
+ Supplier 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) {
+ message.reply("toggles:\n" + togglesString.get());
+ return true;
+ }
+ String arg = toggle.toUpperCase();
+ val b = Arrays.stream(ChannelconBroadcast.values()).filter(t -> t.toString().equals(arg)).findAny();
+ if (!b.isPresent()) {
+ val bt = TBMCSystemChatEvent.BroadcastTarget.get(arg);
+ if (bt == null) {
+ message.reply("cannot find toggle. Toggles:\n" + togglesString.get());
+ return true;
+ }
+ final boolean add;
+ if (add = !cc.brtoggles.contains(bt))
+ cc.brtoggles.add(bt);
+ else
+ cc.brtoggles.remove(bt);
+ return respond(sender, "'" + bt.getName() + "' " + (add ? "en" : "dis") + "abled");
+ }
+ //A B | F
+ //------- A: original - B: mask - F: new
+ //0 0 | 0
+ //0 1 | 1
+ //1 0 | 1
+ //1 1 | 0
+ // XOR
+ cc.toggles ^= b.get().flag;
+ message.reply("'" + b.get().toString().toLowerCase() + "' " + ((cc.toggles & b.get().flag) == 0 ? "disabled" : "enabled"));
+ return true;
+ }
+
+ @Command2.Subcommand
+ public boolean def(Command2DCSender sender, String channelID) {
+ val message = sender.getMessage();
+ if (checkPerms(message)) return true;
+ if (MCChatCustom.hasCustomChat(message.getChannel()))
+ 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)
+ 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 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 ");
+ return true;
+ }
+ DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName());
+ //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
+ message.reply("sorry, you cannot use that Minecraft channel.");
+ return true;
+ }
+ if (chan.get() instanceof ChatRoom) { //ChatRooms don't work well
+ message.reply("chat rooms are not supported yet.");
+ return true;
+ }
+ /*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
+ message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm.");
+ return true;
+ }*/ //TODO: "Channel admins" that can connect channels?
+ MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0, new HashSet<>());
+ if (chan.get() instanceof ChatRoom)
+ message.reply("alright, connection made to the room!");
+ else
+ message.reply("alright, connection made to group `" + groupid + "`!");
+ return true;
+ }
+
+ private boolean checkPerms(IMessage message) {
+ if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) {
+ message.reply("you need to have manage permissions for this channel!");
+ return true;
+ }
+ return false;
+ }
+
+ @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 .", //
+ "Call this command from the channel you want to use.", //
+ "Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon ", //
+ "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: " // TODO: Set correct client ID
+ };
+ }
+}
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java
index 3c05f02..23af46f 100755
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java
@@ -2,44 +2,38 @@ package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
-import buttondevteam.discordplugin.commands.DiscordCommandBase;
+import buttondevteam.discordplugin.commands.Command2DCSender;
+import buttondevteam.discordplugin.commands.ICommand2DC;
import buttondevteam.lib.TBMCCoreAPI;
-import sx.blah.discord.handle.obj.IMessage;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
+import lombok.val;
-public class MCChatCommand extends DiscordCommandBase {
+@CommandClass(helpText = {
+ "MC Chat",
+ "This command enables or disables the Minecraft chat in private messages.", //
+ "It can be useful if you don't want your messages to be visible, for example when talking in a private channel.", //
+ "You can also run all of the ingame commands you have access to using this command, if you have your accounts connected." //
+})
+public class MCChatCommand extends ICommand2DC {
- @Override
- public String getCommandName() {
- return "mcchat";
- }
-
- @Override //TODO: Only register if module is enabled
- public boolean run(IMessage message, String args) {
+ @Command2.Subcommand
+ public boolean def(Command2DCSender sender) {
+ val message = sender.getMessage();
if (!message.getChannel().isPrivate()) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(),
- "This command can only be issued in a direct message with the bot.");
+ 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)) {
boolean mcchat = !user.isMinecraftChatEnabled();
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
- DiscordPlugin.sendMessageToChannel(message.getChannel(),
- "Minecraft chat " + (mcchat //
- ? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
- : "disabled."));
+ message.reply("Minecraft chat " + (mcchat //
+ ? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
+ : "disabled."));
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
}
return true;
- }
-
- @Override
- public String[] getHelpText() {
- return new String[] { //
- DiscordPlugin.getPrefix() + "mcchat enables or disables the Minecraft chat in private messages.", //
- "It can be useful if you don't want your messages to be visible, for example when talking in a private channel.", //
- "You can also run all of the ingame commands you have access to using this command, if you have your accounts connected." //
- }; // TODO: Pin channel switching to indicate the current channel
- }
+ } // TODO: Pin channel switching to indicate the current channel
}
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java
index fe0769a..3d1b52f 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java
@@ -1,7 +1,9 @@
package buttondevteam.discordplugin.mcchat;
import buttondevteam.core.component.channel.Channel;
+import buttondevteam.core.component.channel.ChatRoom;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
+import buttondevteam.lib.TBMCSystemChatEvent;
import lombok.NonNull;
import lombok.val;
import sx.blah.discord.handle.obj.IChannel;
@@ -11,6 +13,7 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
public class MCChatCustom {
/**
@@ -18,8 +21,12 @@ public class MCChatCustom {
*/
static ArrayList lastmsgCustom = new ArrayList<>();
- public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
- val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
+ public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles, Set brtoggles) {
+ if (mcchannel instanceof ChatRoom) {
+ ((ChatRoom) mcchannel).joinRoom(dcp);
+ if (groupid == null) groupid = mcchannel.getGroupID(dcp);
+ }
+ val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles, brtoggles);
lastmsgCustom.add(lmd);
}
@@ -34,7 +41,13 @@ public class MCChatCustom {
public static boolean removeCustomChat(IChannel channel) {
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
- return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
+ return lastmsgCustom.removeIf(lmd -> {
+ if (lmd.channel.getLongID() != channel.getLongID())
+ return false;
+ if (lmd.mcchannel instanceof ChatRoom)
+ ((ChatRoom) lmd.mcchannel).leaveRoom(lmd.dcp);
+ return true;
+ });
}
public static List getCustomChats() {
@@ -46,14 +59,16 @@ public class MCChatCustom {
public final Channel mcchannel;
public final DiscordConnectedPlayer dcp;
public int toggles;
+ public Set brtoggles;
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
- @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
+ @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, Set brtoggles) {
super(channel, user);
groupID = groupid;
this.mcchannel = mcchannel;
this.dcp = dcp;
this.toggles = toggles;
+ this.brtoggles = brtoggles;
}
}
}
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java
index 6c90870..5113f3c 100755
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatListener.java
@@ -9,10 +9,7 @@ import buttondevteam.discordplugin.DiscordSender;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.listeners.CommandListener;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
-import buttondevteam.lib.TBMCChatEvent;
-import buttondevteam.lib.TBMCChatPreprocessEvent;
-import buttondevteam.lib.TBMCCommandPreprocessEvent;
-import buttondevteam.lib.TBMCCoreAPI;
+import buttondevteam.lib.*;
import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayer;
@@ -377,7 +374,7 @@ public class MCChatListener implements Listener {
: 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.");
+ : dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL);
}
else {
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java
index 877d415..7d87376 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatPrivate.java
@@ -15,8 +15,6 @@ import sx.blah.discord.handle.obj.IUser;
import java.util.ArrayList;
-import static buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome;
-
public class MCChatPrivate {
/**
@@ -60,11 +58,11 @@ public class MCChatPrivate {
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
for (val valueEntry : entry.getValue().entrySet())
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
- callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
+ MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
MCChatUtils.ConnectedSenders.clear();
}
private static void callEventSync(Event event) {
- Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> callEventExcludingSome(event));
+ Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> MCChatUtils.callEventExcludingSome(event));
}
}
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java
index cd45dbe..3f04e56 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java
@@ -8,17 +8,25 @@ import buttondevteam.lib.TBMCSystemChatEvent;
import io.netty.util.collection.LongObjectHashMap;
import lombok.RequiredArgsConstructor;
import lombok.experimental.var;
+import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.plugin.AuthorNagException;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.RegisteredListener;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IUser;
import javax.annotation.Nullable;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;
+import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -172,7 +180,7 @@ public class MCChatUtils {
if (event.shouldSendTo(getSender(data.channel, data.user)))
action.accept(data.channel);
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
- if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
+ if (!clmd.brtoggles.contains(event.getTarget()))
return false;
return event.shouldSendTo(clmd.dcp);
}).map(clmd -> clmd.channel).forEach(action);
@@ -213,6 +221,69 @@ public class MCChatUtils {
//If it gets here, it's sending a message to a non-chat channel
}
+ public static void callEventExcludingSome(Event event) {
+ if (notEnabled()) return;
+ callEventExcluding(event, false, module.excludedPlugins().get());
+ }
+
+ /**
+ * Calls an event with the given details.
+ *
+ * This method only synchronizes when the event is not asynchronous.
+ *
+ * @param event Event details
+ * @param only Flips the operation and includes the listed plugins
+ * @param plugins The plugins to exclude. Not case sensitive.
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static void callEventExcluding(Event event, boolean only, String... plugins) { // Copied from Spigot-API and modified a bit
+ if (event.isAsynchronous()) {
+ if (Thread.holdsLock(Bukkit.getPluginManager())) {
+ throw new IllegalStateException(
+ event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
+ }
+ if (Bukkit.getServer().isPrimaryThread()) {
+ throw new IllegalStateException(
+ event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
+ }
+ fireEventExcluding(event, only, plugins);
+ } else {
+ synchronized (Bukkit.getPluginManager()) {
+ fireEventExcluding(event, only, plugins);
+ }
+ }
+ }
+
+ private static void fireEventExcluding(Event event, boolean only, String... plugins) {
+ HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API
+ RegisteredListener[] listeners = handlers.getRegisteredListeners();
+ val server = Bukkit.getServer();
+
+ for (RegisteredListener registration : listeners) {
+ if (!registration.getPlugin().isEnabled()
+ || Arrays.stream(plugins).anyMatch(p -> only ^ p.equalsIgnoreCase(registration.getPlugin().getName())))
+ continue; // Modified to exclude plugins
+
+ try {
+ registration.callEvent(event);
+ } catch (AuthorNagException ex) {
+ Plugin plugin = registration.getPlugin();
+
+ if (plugin.isNaggable()) {
+ plugin.setNaggable(false);
+
+ server.getLogger().log(Level.SEVERE,
+ String.format("Nag author(s): '%s' of '%s' about the following: %s",
+ plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(),
+ ex.getMessage()));
+ }
+ } catch (Throwable ex) {
+ server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to "
+ + registration.getPlugin().getDescription().getFullName(), ex);
+ }
+ }
+ }
+
@RequiredArgsConstructor
public static class LastMsgData {
public IMessage message;
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java
index ca34d8c..3ed7bcf 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java
@@ -3,8 +3,10 @@ package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.*;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
+import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.player.*;
import com.earth2me.essentials.CommandSource;
+import lombok.RequiredArgsConstructor;
import lombok.val;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.ess3.api.events.MuteStatusChangeEvent;
@@ -26,14 +28,17 @@ import sx.blah.discord.handle.obj.IUser;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.MissingPermissionsException;
+@RequiredArgsConstructor
class MCListener implements Listener {
+ private final MinecraftChatModule module;
+
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerLogin(PlayerLoginEvent e) {
if (e.getResult() != Result.ALLOWED)
return;
MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
- .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
- .ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
+ .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
+ .ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
}
@EventHandler(priority = EventPriority.LOWEST)
@@ -46,9 +51,9 @@ class MCListener implements Listener {
if (dp != null) {
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
- new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
+ new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
- new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
+ new DiscordPlayerSender(user, module.chatChannel().get(), p)); //Stored per-channel
}
final String message = e.GetPlayer().PlayerName().get() + " joined the game";
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
@@ -61,13 +66,13 @@ class MCListener implements Listener {
if (e.getPlayer() instanceof DiscordConnectedPlayer)
return; // Only care about real users
MCChatUtils.OnlineSenders.entrySet()
- .removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
+ .removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
- () -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
- .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
- .ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
+ () -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
+ .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
+ .ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
- ChromaBot.getInstance()::updatePlayerList, 5);
+ ChromaBot.getInstance()::updatePlayerList, 5);
final String message = e.GetPlayer().PlayerName().get() + " left the game";
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
}
@@ -90,32 +95,41 @@ class MCListener implements Listener {
if (e.isCancelled() || !base.isOnline())
return;
final String msg = base.getDisplayName()
- + " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
+ + " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
}
+ private ConfigData muteRole() {
+ return DPUtils.roleData(module.getConfig(), "muteRole", "Muted");
+ }
+
@EventHandler
public void onPlayerMute(MuteStatusChangeEvent e) {
try {
DPUtils.performNoWait(() -> {
- final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L); //TODO: Config
+ final IRole role = muteRole().get();
+ if (role == null) return;
final CommandSource source = e.getAffected().getSource();
if (!source.isPlayer())
return;
final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
- .getAs(DiscordPlayer.class);
+ .getAs(DiscordPlayer.class);
if (p == null) return;
final IUser user = DiscordPlugin.dc.getUserByID(
- Long.parseLong(p.getDiscordID()));
+ Long.parseLong(p.getDiscordID()));
if (e.getValue())
user.addRole(role);
else
user.removeRole(role);
- DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName());
+ val modlog = module.modlogChannel().get();
+ String msg = (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName();
+ if (modlog != null)
+ DiscordPlugin.sendMessageToChannel(modlog, msg);
+ DPUtils.getLogger().info(msg);
});
} catch (DiscordException | MissingPermissionsException ex) {
TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!",
- ex);
+ ex);
}
}
@@ -132,9 +146,10 @@ class MCListener implements Listener {
@EventHandler
public void onYEEHAW(TBMCYEEHAWEvent event) { //TODO: Inherit from the chat event base to have channel support
String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName()
- : event.getSender().getName();
+ : event.getSender().getName();
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
- MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
+ val yeehaw = DiscordPlugin.mainServer.getEmojiByName("YEEHAW");
+ MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getStringID() + ">s" : " YEEHAWs")));
}
@EventHandler
diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java
index 55d68d6..509ea66 100644
--- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java
+++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java
@@ -5,6 +5,7 @@ import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI;
+import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import com.google.common.collect.Lists;
@@ -14,30 +15,58 @@ import org.bukkit.Bukkit;
import sx.blah.discord.handle.obj.IChannel;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.UUID;
+import java.util.stream.Collectors;
-public class MinecraftChatModule extends Component {
+/**
+ * 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 {
private @Getter MCChatListener listener;
public MCChatListener getListener() { //It doesn't want to generate
return listener;
}
+ /**
+ * A list of commands that can be used in public chats - Warning: Some plugins will treat players as OPs, always test before allowing a command!
+ */
public ConfigData> whitelistedCommands() {
return getConfig().getData("whitelistedCommands", () -> Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw", "lenny", "rp", "plugins"));
}
+ /**
+ * The channel to use as the public Minecraft chat - everything public gets broadcasted here
+ */
public ConfigData chatChannel() {
return DPUtils.channelData(getConfig(), "chatChannel", 239519012529111040L);
}
+ /**
+ * The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute
+ */
+ public ConfigData modlogChannel() {
+ return DPUtils.channelData(getConfig(), "modlogChannel", 283840717275791360L);
+ }
+
+ /**
+ * 0 * The plugins to exclude from fake player events used for the 'mcchat' command - some plugins may crash, add them here
+ */
+ public ConfigData excludedPlugins() {
+ return getConfig().getData("excludedPlugins", new String[]{"ProtocolLib", "LibsDisguises", "JourneyMapServer"});
+ }
+
@Override
protected void enable() {
+ if (DPUtils.disableIfConfigError(this, chatChannel())) return;
listener = new MCChatListener(this);
DiscordPlugin.dc.getDispatcher().registerListener(listener);
TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin());
- TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), 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 ChannelconCommand());
val chcons = getConfig().getConfig().getConfigurationSection("chcons");
if (chcons == null) //Fallback to old place
@@ -52,11 +81,12 @@ public class MinecraftChatModule extends Component {
val user = DiscordPlugin.dc.fetchUser(did);
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);
+ MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet()));
});
}
}
@@ -75,7 +105,8 @@ public class MinecraftChatModule extends Component {
chconc.set("mcname", chcon.dcp.getName());
chconc.set("groupid", chcon.groupID);
chconc.set("toggles", chcon.toggles);
+ chconc.set("brtoggles", chcon.brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::getName).collect(Collectors.toList()));
}
MCChatListener.stop(true);
- } //TODO: Use ComponentManager.isEnabled() at other places too, instead of SafeMode
+ }
}
diff --git a/src/main/java/buttondevteam/discordplugin/mccommands/ReloadMCCommand.java b/src/main/java/buttondevteam/discordplugin/mccommands/ReloadMCCommand.java
new file mode 100644
index 0000000..01433c9
--- /dev/null
+++ b/src/main/java/buttondevteam/discordplugin/mccommands/ReloadMCCommand.java
@@ -0,0 +1,26 @@
+package buttondevteam.discordplugin.mccommands;
+
+import buttondevteam.discordplugin.DiscordPlugin;
+import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.chat.TBMCCommandBase;
+import org.bukkit.command.CommandSender;
+
+@CommandClass(path = "discord reload")
+public class ReloadMCCommand extends TBMCCommandBase {
+ @Override
+ public boolean OnCommand(CommandSender sender, String alias, String[] args) {
+ if (DiscordPlugin.plugin.tryReloadConfig())
+ sender.sendMessage("§bConfig reloaded."); //TODO: Convert to new command system
+ else
+ sender.sendMessage("§cFailed to reload config.");
+ return true;
+ }
+
+ @Override
+ public String[] GetHelpText(String alias) {
+ return new String[]{
+ "Reload",
+ "Reloads the config. To apply some changes, you may need to also run /discord reset."
+ };
+ }
+}
diff --git a/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java b/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java
index 7bf3d2b..8806647 100644
--- a/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java
+++ b/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java
@@ -3,7 +3,6 @@ package buttondevteam.discordplugin.role;
import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
-import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import lombok.val;
@@ -19,12 +18,12 @@ import java.awt.*;
import java.util.List;
import java.util.stream.Collectors;
-public class GameRoleModule extends Component {
+public class GameRoleModule extends Component {
public List GameRoles;
@Override
protected void enable() {
- DiscordCommandBase.registerCommand("role", new RoleCommand(this));
+ getPlugin().getManager().registerCommand(new RoleCommand(this));
GameRoles = DiscordPlugin.mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
}
@@ -41,30 +40,34 @@ public class GameRoleModule extends Component {
val grm = ComponentManager.getIfEnabled(GameRoleModule.class);
if (grm == null) return;
val GameRoles = grm.GameRoles;
+ val logChannel = grm.logChannel().get();
if (roleEvent instanceof RoleCreateEvent) {
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
if (roleEvent.getRole().isDeleted() || !grm.isGameRole(roleEvent.getRole()))
return; //Deleted or not a game role
GameRoles.add(roleEvent.getRole().getName());
- DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Added " + roleEvent.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
+ if (logChannel != null)
+ DiscordPlugin.sendMessageToChannel(logChannel, "Added " + roleEvent.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
}, 100);
} else if (roleEvent instanceof RoleDeleteEvent) {
- if (GameRoles.remove(roleEvent.getRole().getName()))
- DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + roleEvent.getRole().getName() + " as a game role.");
+ if (GameRoles.remove(roleEvent.getRole().getName()) && logChannel != null)
+ DiscordPlugin.sendMessageToChannel(logChannel, "Removed " + roleEvent.getRole().getName() + " as a game role.");
} else if (roleEvent instanceof RoleUpdateEvent) {
val event = (RoleUpdateEvent) roleEvent;
if (!grm.isGameRole(event.getNewRole())) {
- if (GameRoles.remove(event.getOldRole().getName()))
- DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
+ if (GameRoles.remove(event.getOldRole().getName()) && logChannel != null)
+ DiscordPlugin.sendMessageToChannel(logChannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
} else {
if (GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
return;
boolean removed = GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
- if (removed)
- DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
- else
- DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
+ if (logChannel != null) {
+ if (removed)
+ DiscordPlugin.sendMessageToChannel(logChannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
+ else
+ DiscordPlugin.sendMessageToChannel(logChannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
+ }
}
}
}
@@ -74,6 +77,7 @@ public class GameRoleModule extends Component {
return false; //Only allow on the main server
val rc = new Color(149, 165, 166, 0);
return r.getColor().equals(rc)
- && r.getPosition() < DiscordPlugin.mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role
+ && DiscordPlugin.dc.getOurUser().getRolesForGuild(DiscordPlugin.mainServer)
+ .stream().anyMatch(or -> r.getPosition() < or.getPosition()); //Below one of our roles
}
}
diff --git a/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java b/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java
index 1534e2b..19d78cf 100755
--- a/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java
+++ b/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java
@@ -2,15 +2,18 @@ package buttondevteam.discordplugin.role;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
-import buttondevteam.discordplugin.commands.DiscordCommandBase;
+import buttondevteam.discordplugin.commands.Command2DCSender;
+import buttondevteam.discordplugin.commands.ICommand2DC;
import buttondevteam.lib.TBMCCoreAPI;
-import sx.blah.discord.handle.obj.IMessage;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
import sx.blah.discord.handle.obj.IRole;
import java.util.List;
import java.util.stream.Collectors;
-public class RoleCommand extends DiscordCommandBase { //TODO: Use Command2's parser
+@CommandClass
+public class RoleCommand extends ICommand2DC {
private GameRoleModule grm;
@@ -18,83 +21,64 @@ public class RoleCommand extends DiscordCommandBase { //TODO: Use Command2's par
this.grm = grm;
}
- @Override
- public String getCommandName() {
- return "role";
+ @Command2.Subcommand(helpText = {
+ "Add role",
+ "This command adds a role to your account."
+ })
+ public boolean add(Command2DCSender sender, @Command2.TextArg String rolename) {
+ final IRole role = checkAndGetRole(sender, rolename);
+ if (role == null)
+ return true;
+ try {
+ DPUtils.perform(() -> sender.getMessage().getAuthor().addRole(role));
+ sender.sendMessage("added role.");
+ } catch (Exception e) {
+ TBMCCoreAPI.SendException("Error while adding role!", e);
+ sender.sendMessage("an error occured while adding the role.");
+ }
+ return true;
+ }
+
+ @Command2.Subcommand(helpText = {
+ "Remove role",
+ "This command removes a role from your account."
+ })
+ public boolean remove(Command2DCSender sender, @Command2.TextArg String rolename) {
+ final IRole role = checkAndGetRole(sender, rolename);
+ if (role == null)
+ return true;
+ try {
+ DPUtils.perform(() -> sender.getMessage().getAuthor().removeRole(role));
+ sender.sendMessage("removed role.");
+ } catch (Exception e) {
+ TBMCCoreAPI.SendException("Error while removing role!", e);
+ sender.sendMessage("an error occured while removing the role.");
+ }
+ return true;
+ }
+
+ @Command2.Subcommand
+ public void list(Command2DCSender sender) {
+ sender.sendMessage("list of roles:\n" + grm.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
}
- @Override
- public boolean run(IMessage message, String args) {
- if (args.length() == 0)
- return false;
- String[] argsa = splitargs(args);
- if (argsa[0].equalsIgnoreCase("add")) {
- final IRole role = checkAndGetRole(message, argsa, "This command adds a role to your account.");
- if (role == null)
- return true;
- try {
- DPUtils.perform(() -> message.getAuthor().addRole(role));
- DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added role.");
- } catch (Exception e) {
- TBMCCoreAPI.SendException("Error while adding role!", e);
- DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role.");
- }
- } else if (argsa[0].equalsIgnoreCase("remove")) {
- final IRole role = checkAndGetRole(message, argsa, "This command removes a role from your account.");
- if (role == null)
- return true;
- try {
- DPUtils.perform(() -> message.getAuthor().removeRole(role));
- DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed role.");
- } catch (Exception e) {
- TBMCCoreAPI.SendException("Error while removing role!", e);
- DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role.");
- }
- } else if (argsa[0].equalsIgnoreCase("list")) {
- listRoles(message);
- } else return false;
- return true;
- }
-
- private void listRoles(IMessage message) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(),
- "List of roles:\n" + grm.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
- }
-
- private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) {
- if (argsa.length < 2) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(), usage + "\nUsage: " + argsa[0] + " ");
+ private IRole checkAndGetRole(Command2DCSender sender, String rolename) {
+ if (!grm.GameRoles.contains(rolename)) {
+ sender.sendMessage("that role cannot be found.");
+ list(sender);
return null;
}
- StringBuilder rolename = new StringBuilder(argsa[1]);
- for (int i = 2; i < argsa.length; i++)
- rolename.append(" ").append(argsa[i]);
- if (!grm.GameRoles.contains(rolename.toString())) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(), "That role cannot be found.");
- listRoles(message);
- return null;
- }
- final List roles = DiscordPlugin.mainServer.getRolesByName(rolename.toString());
+ final List roles = DiscordPlugin.mainServer.getRolesByName(rolename);
if (roles.size() == 0) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(),
- "The specified role cannot be found on Discord! Removing from the list.");
- grm.GameRoles.remove(rolename.toString());
+ sender.sendMessage("the specified role cannot be found on Discord! Removing from the list.");
+ grm.GameRoles.remove(rolename);
return null;
}
if (roles.size() > 1) {
- DiscordPlugin.sendMessageToChannel(message.getChannel(),
- "There are more roles with this name. Why are there more roles with this name?");
+ sender.sendMessage("there are multiple roles with this name. Why are there multiple roles with this name?");
return null;
}
return roles.get(0);
}
- @Override
- public String[] getHelpText() {
- return new String[]{ //
- "Add or remove roles from yourself.", //
- "Usage: " + DiscordPlugin.getPrefix() + "role add|remove or role list", //
- };
- }
-
}