From d08d32f73f0cba7e489fad369b6fa25f3c943132 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 9 Feb 2019 00:24:42 +0100 Subject: [PATCH 01/14] Started using new command system for DC cmds Some of the new files are a couple days old --- .../buttondevteam/discordplugin/DPUtils.java | 8 +++-- .../discordplugin/DiscordPlugin.java | 11 +++++++ .../discordplugin/commands/Command2DC.java | 32 +++++++++++++++++++ .../commands/Command2DCSender.java | 21 ++++++++++++ .../commands/DiscordCommandBase.java | 3 +- .../discordplugin/commands/ICommand2DC.java | 20 ++++++++++++ .../commands/VersionCommand.java | 23 +++++-------- 7 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 src/main/java/buttondevteam/discordplugin/commands/Command2DC.java create mode 100644 src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java create mode 100644 src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index 6b649ab..2da113e 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -2,6 +2,7 @@ package buttondevteam.discordplugin; import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.architecture.IHaveConfig; +import lombok.val; import org.bukkit.Bukkit; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IIDLinkedObject; @@ -112,8 +113,11 @@ public final class DPUtils { return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getChannelByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer) } - public static ConfigData roleData(IHaveConfig config, String key, long defID) { - return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getRoleByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer) + public static ConfigData roleData(IHaveConfig config, String key, String defName) { + return config.getDataPrimDef(key, defName, name -> { + val roles = DiscordPlugin.mainServer.getRolesByName((String) name); + return roles.size() > 0 ? roles.get(0) : null; //TODO: May not handle null properly + }, IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer) } /** diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 9187d52..40f90a9 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -1,7 +1,9 @@ package buttondevteam.discordplugin; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; +import buttondevteam.discordplugin.commands.Command2DC; import buttondevteam.discordplugin.commands.DiscordCommandBase; +import buttondevteam.discordplugin.commands.VersionCommand; import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.discordplugin.listeners.MCListener; @@ -18,6 +20,7 @@ import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.player.ChromaGamerBase; import com.google.common.io.Files; +import lombok.Getter; import lombok.val; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; @@ -46,6 +49,8 @@ public class DiscordPlugin extends ButtonPlugin implements IListener public static IDiscordClient dc; public static DiscordPlugin plugin; public static boolean SafeMode = true; + @Getter + private Command2DC manager; public ConfigData Prefix() { return getIConfig().getData("prefix", '/', str -> ((String) str).charAt(0), Object::toString); @@ -64,11 +69,16 @@ public class DiscordPlugin extends ButtonPlugin implements IListener return DPUtils.channelData(getIConfig(), "commandChannel", 239519012529111040L); } + public ConfigData ModRole() { + return DPUtils.roleData(getIConfig(), "modRole", "Moderator"); + } + @Override public void pluginEnable() { try { Bukkit.getLogger().info("Initializing DiscordPlugin..."); plugin = this; + manager = new Command2DC(); ClientBuilder cb = new ClientBuilder(); cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8)); dc = cb.login(); @@ -146,6 +156,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener new ChromaBot(this).updatePlayerList(); //Initialize ChromaBot - The MCCHatModule is tested to be enabled DiscordCommandBase.registerCommands(); + getManager().registerCommand(new VersionCommand()); if (ResetMCCommand.resetting) //These will only execute if the chat is enabled ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN) .withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java new file mode 100644 index 0000000..22565d9 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java @@ -0,0 +1,32 @@ +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.chat.Command2; + +import java.util.HashMap; +import java.util.function.Function; + +public class Command2DC extends Command2 { + private HashMap> subcommands = new HashMap<>(); + private HashMap, ParamConverter> paramConverters = new HashMap<>(); + + @Override + public void addParamConverter(Class cl, Function converter, String errormsg) { + addParamConverter(cl, converter, errormsg, paramConverters); + } + + @Override + public boolean handleCommand(Command2DCSender sender, String commandLine) throws Exception { + return handleCommand(sender, commandLine, subcommands, paramConverters); + } + + @Override + public void registerCommand(ICommand2DC command) { + registerCommand(command, subcommands, DiscordPlugin.getPrefix()); + } + + @Override + public boolean hasPermission(Command2DCSender sender, ICommand2DC command) { + return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()); + } +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java new file mode 100644 index 0000000..5a04166 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java @@ -0,0 +1,21 @@ +package buttondevteam.discordplugin.commands; + +import buttondevteam.lib.chat.Command2Sender; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import sx.blah.discord.handle.obj.IMessage; + +@RequiredArgsConstructor +public class Command2DCSender implements Command2Sender { + private final @Getter IMessage message; + + @Override + public void sendMessage(String message) { + this.message.reply(message); + } + + @Override + public void sendMessage(String[] message) { + this.message.reply(String.join("\n", message)); + } +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java index 947db5b..d05964f 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java @@ -27,12 +27,13 @@ public abstract class DiscordCommandBase { commands.put("mcchat", new MCChatCommand()); commands.put("channelcon", new ChannelconCommand()); commands.put("debug", new DebugCommand()); - commands.put("version", new VersionCommand()); } public static void runCommand(String cmd, String args, IMessage message) { debug("F"); //Not sure if needed DiscordCommandBase command = commands.get(cmd); + //if(command==null) + // DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmd+" "+args); //TODO! if (command == null) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "Unknown command: " + cmd + " with args: " + args + "\nDo '" diff --git a/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java b/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java new file mode 100644 index 0000000..c602c68 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java @@ -0,0 +1,20 @@ +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.chat.CommandClass; +import buttondevteam.lib.chat.ICommand2; +import lombok.Getter; +import lombok.val; + +public abstract class ICommand2DC extends ICommand2 { + public ICommand2DC() { + super(DiscordPlugin.plugin.getManager()); + val ann = getClass().getAnnotation(CommandClass.class); + if (ann == null) + modOnly = false; + else + modOnly = ann.modOnly(); + } + + private final @Getter boolean modOnly; +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java index 5908495..cf0ee8c 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java @@ -1,26 +1,19 @@ package buttondevteam.discordplugin.commands; import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.chat.CommandClass; import lombok.val; -import sx.blah.discord.handle.obj.IMessage; -public class VersionCommand extends DiscordCommandBase { - @Override - public String getCommandName() { - return "version"; - } - - @Override - public boolean run(IMessage message, String args) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), String.join("\n", getVersion())); +@CommandClass(helpText = { + "Version", + "Returns the plugin's version" +}) +public class VersionCommand extends ICommand2DC { + public boolean def(Command2DCSender sender) { + sender.sendMessage(getVersion()); return true; } - @Override - public String[] getHelpText() { - return VersionCommand.getVersion(); //Heh - } - public static String[] getVersion() { val desc = DiscordPlugin.plugin.getDescription(); return new String[]{ // From 9ba57fd9897d89ba7125d699241266594bec393e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 12 Feb 2019 22:38:59 +0100 Subject: [PATCH 02/14] Actually using the cmd sys, logger stuff Some of the new files are a couple days old Using the plugin's logger almost everywhere --- .../java/buttondevteam/discordplugin/DPUtils.java | 4 ++-- .../buttondevteam/discordplugin/DiscordPlugin.java | 6 +++--- .../broadcaster/GeneralEventBroadcasterModule.java | 3 +-- .../discordplugin/listeners/CommandListener.java | 12 +++++++++--- .../discordplugin/mcchat/MCChatListener.java | 7 ++----- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index 2da113e..e415298 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -59,7 +59,7 @@ public final class DPUtils { return null; if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <-- // throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag."); - Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!"); + getLogger().warning("Waiting for a Discord request on the main thread!"); return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this } @@ -72,7 +72,7 @@ public final class DPUtils { return null; if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <-- // throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag."); - Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!"); + getLogger().warning("Waiting for a Discord request on the main thread!"); return RequestBuffer.request(action).get(); // Let the pros handle this } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 40f90a9..fc12fed 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -76,7 +76,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener @Override public void pluginEnable() { try { - Bukkit.getLogger().info("Initializing DiscordPlugin..."); + getLogger().info("Initializing..."); plugin = this; manager = new Command2DC(); ClientBuilder cb = new ClientBuilder(); @@ -284,7 +284,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { if (message.length() > 1980) { message = message.substring(0, 1980); - Bukkit.getLogger() + DPUtils.getLogger() .warning("Message was too long to send to discord and got truncated. In " + channel.getName()); } try { @@ -307,7 +307,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener } catch (TimeoutException | InterruptedException e) { throw e; } catch (Exception e) { - Bukkit.getLogger().warning( + DPUtils.getLogger().warning( "Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message); throw new RuntimeException(e); } diff --git a/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java b/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java index 8830f37..e8a71e7 100644 --- a/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java +++ b/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java @@ -4,7 +4,6 @@ import buttondevteam.discordplugin.DPUtils; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; import lombok.Getter; -import org.bukkit.Bukkit; public class GeneralEventBroadcasterModule extends Component { private static @Getter boolean hooked = false; @@ -13,7 +12,7 @@ public class GeneralEventBroadcasterModule extends Component { protected void enable() { try { PlayerListWatcher.hookUp(); - Bukkit.getLogger().info("Finished hooking into the player list"); + DPUtils.getLogger().info("Finished hooking into the player list"); hooked = true; } catch (Exception e) { TBMCCoreAPI.SendException("Error while hacking the player list!", e); diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index b6fe5c6..a9eae80 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -1,7 +1,8 @@ package buttondevteam.discordplugin.listeners; import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.discordplugin.commands.DiscordCommandBase; +import buttondevteam.discordplugin.commands.Command2DCSender; +import buttondevteam.lib.TBMCCoreAPI; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IRole; @@ -38,7 +39,12 @@ public class CommandListener { } message.getChannel().setTypingStatus(true); String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command - int index = cmdwithargsString.indexOf(" "); + try { + DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmdwithargsString); + } catch (Exception e) { + TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e); + } + /*int index = cmdwithargsString.indexOf(" "); String cmd; String args; if (index == -1) { @@ -48,7 +54,7 @@ public class CommandListener { cmd = cmdwithargsString.substring(0, index); args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces } - DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message); + DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);*/ message.getChannel().setTypingStatus(false); return true; } 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); From 13b168d23890275fe1c6a4f0935541064ae5e141 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 13 Feb 2019 15:21:57 +0100 Subject: [PATCH 03/14] Made all channels configurable Removed Vault repo, was unused and errors now Removed all channel fields from main class --- pom.xml | 502 +++++++++--------- .../discordplugin/DiscordPlugin.java | 35 +- .../exceptions/DebugMessageListener.java | 63 +-- .../exceptions/ExceptionListenerModule.java | 168 +++--- .../discordplugin/fun/FunModule.java | 9 +- .../discordplugin/mcchat/MCListener.java | 41 +- .../mcchat/MinecraftChatModule.java | 6 +- 7 files changed, 415 insertions(+), 409 deletions(-) diff --git a/pom.xml b/pom.xml index 0ccfe46..270da7f 100755 --- a/pom.xml +++ b/pom.xml @@ -1,251 +1,251 @@ - - 4.0.0 - - com.github.TBMCPlugins - DiscordPlugin - master-SNAPSHOT - jar - - DiscordPlugin - http://maven.apache.org - - - - src/main/java - - - src - - **/*.java - - - - src/main/resources - - *.properties - *.yml - *.csv - *.txt - - true - - - DiscordPlugin - - - maven-compiler-plugin - 3.6.2 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-shade-plugin - 2.4.2 - - - package - - shade - - - - - org.spigotmc:spigot-api - com.github.TBMCPlugins.ButtonCore:ButtonCore - net.ess3:Essentials - - - - - - - - org.apache.maven.plugins - maven-resources-plugin - 3.0.1 - - - copy - compile - - copy-resources - - - target - - - resources - - - - - - - - - maven-surefire-plugin - - false - - - - - - - - UTF-8 - - master - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - jcenter - http://jcenter.bintray.com - - - jitpack.io - https://jitpack.io - - - vault-repo - http://nexus.hc.to/content/repositories/pub_releases - - - Essentials - http://repo.ess3.net/content/repositories/essrel/ - - - projectlombok.org - http://projectlombok.org/mavenrepo - - - - - - - junit - junit - 3.8.1 - test - - - org.spigotmc - spigot-api - 1.12-R0.1-SNAPSHOT - provided - - - org.spigotmc - spigot - 1.12.2-R0.1-SNAPSHOT - provided - - - - - com.github.SizableShrimp - Discord4J - httprequestchange-SNAPSHOT - - - - org.slf4j - slf4j-jdk14 - 1.7.21 - - - com.github.TBMCPlugins.ButtonCore - ButtonCore - ${branch}-SNAPSHOT - provided - - - com.github.milkbowl - VaultAPI - master-SNAPSHOT - provided - - - net.ess3 - Essentials - 2.13.1 - provided - - - com.github.xaanit - D4J-OAuth - master-SNAPSHOT - - - - org.projectlombok - lombok - 1.16.16 - provided - - - - - org.objenesis - objenesis - 2.6 - test - - - com.vdurmont - emoji-java - 4.0.0 - - - - - - ci - - - env.TRAVIS_BRANCH - - - - - ${env.TRAVIS_BRANCH} - - - - + + 4.0.0 + + com.github.TBMCPlugins + DiscordPlugin + master-SNAPSHOT + jar + + DiscordPlugin + http://maven.apache.org + + + + src/main/java + + + src + + **/*.java + + + + src/main/resources + + *.properties + *.yml + *.csv + *.txt + + true + + + DiscordPlugin + + + maven-compiler-plugin + 3.6.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.2 + + + package + + shade + + + + + org.spigotmc:spigot-api + com.github.TBMCPlugins.ButtonCore:ButtonCore + net.ess3:Essentials + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + + copy + compile + + copy-resources + + + target + + + resources + + + + + + + + + maven-surefire-plugin + + false + + + + + + + + UTF-8 + + master + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + jcenter + http://jcenter.bintray.com + + + jitpack.io + https://jitpack.io + + + + Essentials + http://repo.ess3.net/content/repositories/essrel/ + + + projectlombok.org + http://projectlombok.org/mavenrepo + + + + + + + junit + junit + 3.8.1 + test + + + org.spigotmc + spigot-api + 1.12-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + 1.12.2-R0.1-SNAPSHOT + provided + + + + + com.github.SizableShrimp + Discord4J + httprequestchange-SNAPSHOT + + + + org.slf4j + slf4j-jdk14 + 1.7.21 + + + com.github.TBMCPlugins.ButtonCore + ButtonCore + ${branch}-SNAPSHOT + provided + + + com.github.milkbowl + VaultAPI + master-SNAPSHOT + provided + + + net.ess3 + Essentials + 2.13.1 + provided + + + com.github.xaanit + D4J-OAuth + master-SNAPSHOT + + + + org.projectlombok + lombok + 1.16.16 + provided + + + + + org.objenesis + objenesis + 2.6 + test + + + com.vdurmont + emoji-java + 4.0.0 + + + + + + ci + + + env.TRAVIS_BRANCH + + + + + ${env.TRAVIS_BRANCH} + + + + diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index fc12fed..eab7e6e 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -5,6 +5,7 @@ import buttondevteam.discordplugin.commands.Command2DC; import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.commands.VersionCommand; import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; +import buttondevteam.discordplugin.fun.FunModule; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.discordplugin.listeners.MCListener; import buttondevteam.discordplugin.mcchat.MCChatPrivate; @@ -89,18 +90,6 @@ public class DiscordPlugin extends ButtonPlugin implements IListener } } - public static IChannel botchannel; //Can be removed - public static IChannel annchannel; - public static IChannel genchannel; - public static IChannel chatchannel; - public static IChannel botroomchannel; - public static IChannel modlogchannel; - /** - * Don't send messages, just receive, the same channel is used when testing - */ - public static IChannel officechannel; - public static IChannel updatechannel; - public static IChannel devofficechannel; public static IGuild mainServer; public static IGuild devServer; @@ -119,31 +108,10 @@ public class DiscordPlugin extends ButtonPlugin implements IListener if (mainServer == null || devServer == null) return; // Retry if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable() - botchannel = mainServer.getChannelByID(209720707188260864L); // bot - annchannel = mainServer.getChannelByID(126795071927353344L); // announcements - genchannel = mainServer.getChannelByID(125813020357165056L); // general - chatchannel = mainServer.getChannelByID(249663564057411596L); // minecraft_chat - botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room - officechannel = devServer.getChannelByID(219626707458457603L); // developers-office - updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates - devofficechannel = officechannel; // developers-office - modlogchannel = mainServer.getChannelByID(283840717275791360L); // modlog dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft"); } else { - botchannel = devServer.getChannelByID(239519012529111040L); // bot-room - annchannel = botchannel; // bot-room - genchannel = botchannel; // bot-room - botroomchannel = botchannel;// bot-room - chatchannel = botchannel;// bot-room - officechannel = devServer.getChannelByID(219626707458457603L); // developers-office - updatechannel = botchannel; - devofficechannel = botchannel;// bot-room - modlogchannel = botchannel; // bot-room dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing"); } - if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null - || chatchannel == null || officechannel == null || updatechannel == null) - return; // Retry SafeMode = false; if (task != null) task.cancel(); @@ -153,6 +121,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener Component.registerComponent(this, new ExceptionListenerModule()); Component.registerComponent(this, new GameRoleModule()); //Needs the mainServer to be set Component.registerComponent(this, new AnnouncerModule()); + Component.registerComponent(this, new FunModule()); new ChromaBot(this).updatePlayerList(); //Initialize ChromaBot - The MCCHatModule is tested to be enabled DiscordCommandBase.registerCommands(); diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java b/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java index cca3e98..95c3cdb 100755 --- a/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java +++ b/src/main/java/buttondevteam/discordplugin/exceptions/DebugMessageListener.java @@ -1,31 +1,32 @@ -package buttondevteam.discordplugin.exceptions; - -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.lib.TBMCDebugMessageEvent; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -public class DebugMessageListener implements Listener{ - @EventHandler - public void onDebugMessage(TBMCDebugMessageEvent e) { - SendMessage(e.getDebugMessage()); - e.setSent(); - } - - private static void SendMessage(String message) { - if (DiscordPlugin.SafeMode) - return; - try { - StringBuilder sb = new StringBuilder(); - sb.append("```").append("\n"); - if (message.length() > 2000) - message = message.substring(0, 2000); - sb.append(message).append("\n"); - sb.append("```"); - DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString()); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - -} +package buttondevteam.discordplugin.exceptions; + +import buttondevteam.core.ComponentManager; +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.TBMCDebugMessageEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class DebugMessageListener implements Listener{ + @EventHandler + public void onDebugMessage(TBMCDebugMessageEvent e) { + SendMessage(e.getDebugMessage()); + e.setSent(); + } + + private static void SendMessage(String message) { + if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(ExceptionListenerModule.class)) + return; + try { + StringBuilder sb = new StringBuilder(); + sb.append("```").append("\n"); + if (message.length() > 2000) + message = message.substring(0, 2000); + sb.append(message).append("\n"); + sb.append("```"); + DiscordPlugin.sendMessageToChannel(ExceptionListenerModule.getChannel(), sb.toString()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + +} diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java index f491a24..6821e6f 100755 --- a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java +++ b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java @@ -1,76 +1,92 @@ -package buttondevteam.discordplugin.exceptions; - -import buttondevteam.core.ComponentManager; -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.TBMCExceptionEvent; -import buttondevteam.lib.architecture.Component; -import org.apache.commons.lang.exception.ExceptionUtils; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import sx.blah.discord.handle.obj.IRole; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class ExceptionListenerModule extends Component implements Listener { - private List lastthrown = new ArrayList<>(); - private List lastsourcemsg = new ArrayList<>(); - - @EventHandler - public void onException(TBMCExceptionEvent e) { - if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass())) - return; - if (lastthrown.stream() - .anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace()) - && (e.getException().getMessage() == null ? ex.getMessage() == null - : e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message - && lastsourcemsg.contains(e.getSourceMessage())) - return; - SendException(e.getException(), e.getSourceMessage()); - if (lastthrown.size() >= 10) - lastthrown.remove(0); - if (lastsourcemsg.size() >= 10) - lastsourcemsg.remove(0); - lastthrown.add(e.getException()); - lastsourcemsg.add(e.getSourceMessage()); - e.setHandled(); - } - - private static IRole coderRole; - - private static void SendException(Throwable e, String sourcemessage) { - try { - if (coderRole == null) - coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0); - StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder() - : new StringBuilder(coderRole.mention()).append("\n"); - sb.append(sourcemessage).append("\n"); - sb.append("```").append("\n"); - String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) - .filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam.")) - .collect(Collectors.joining("\n")); - if (stackTrace.length() > 1800) - stackTrace = stackTrace.substring(0, 1800); - sb.append(stackTrace).append("\n"); - sb.append("```"); - DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString()); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - @Override - protected void enable() { - Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin()); - TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin()); - } - - @Override - protected void disable() { - - } -} +package buttondevteam.discordplugin.exceptions; + +import buttondevteam.core.ComponentManager; +import buttondevteam.discordplugin.DPUtils; +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.TBMCExceptionEvent; +import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ConfigData; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import sx.blah.discord.handle.obj.IChannel; +import sx.blah.discord.handle.obj.IRole; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class ExceptionListenerModule extends Component implements Listener { + private List lastthrown = new ArrayList<>(); + private List lastsourcemsg = new ArrayList<>(); + + @EventHandler + public void onException(TBMCExceptionEvent e) { + if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass())) + return; + if (lastthrown.stream() + .anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace()) + && (e.getException().getMessage() == null ? ex.getMessage() == null + : e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message + && lastsourcemsg.contains(e.getSourceMessage())) + return; + SendException(e.getException(), e.getSourceMessage()); + if (lastthrown.size() >= 10) + lastthrown.remove(0); + if (lastsourcemsg.size() >= 10) + lastsourcemsg.remove(0); + lastthrown.add(e.getException()); + lastsourcemsg.add(e.getSourceMessage()); + e.setHandled(); + } + + private static IRole coderRole; + + private static void SendException(Throwable e, String sourcemessage) { + if (instance == null) return; + try { + if (coderRole == null) + coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0); + StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder() + : new StringBuilder(coderRole.mention()).append("\n"); + sb.append(sourcemessage).append("\n"); + sb.append("```").append("\n"); + String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) + .filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam.")) + .collect(Collectors.joining("\n")); + if (stackTrace.length() > 1800) + stackTrace = stackTrace.substring(0, 1800); + sb.append(stackTrace).append("\n"); + sb.append("```"); + DiscordPlugin.sendMessageToChannel(getChannel(), sb.toString()); //Instance isn't null here + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + private static ExceptionListenerModule instance; + + public static IChannel getChannel() { + if (instance != null) return instance.channel().get(); + return null; + } + + private ConfigData channel() { + return DPUtils.channelData(getConfig(), "channel", 239519012529111040L); + } + + @Override + protected void enable() { + instance = this; + Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin()); + TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin()); + } + + @Override + protected void disable() { + instance = null; + } +} diff --git a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java index 9565a53..c5bfd8d 100644 --- a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java +++ b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.fun; import buttondevteam.core.ComponentManager; +import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; @@ -12,6 +13,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent; +import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.StatusType; @@ -123,6 +125,11 @@ public class FunModule extends Component implements Listener { }, IRole::getName); } + + private ConfigData fullHouseChannel() { + return DPUtils.channelData(getConfig(), "fullHouseChannel", 219626707458457603L); + } + private static long lasttime = 0; public static void handleFullHouse(PresenceUpdateEvent event) { @@ -138,7 +145,7 @@ public class FunModule extends Component implements Listener { .noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE)) && lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime()) && Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) { - DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!", + DiscordPlugin.sendMessageToChannel(mod.fullHouseChannel().get(), "Full house!", new EmbedBuilder() .withImage( "https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png") diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java index ca34d8c..fbf9d27 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 -> buttondevteam.discordplugin.listeners.MCListener.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 -> buttondevteam.discordplugin.listeners.MCListener.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,36 @@ 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(); 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()); + DiscordPlugin.sendMessageToChannel(module.modlogChannel().get(), (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName()); }); } catch (DiscordException | MissingPermissionsException ex) { TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!", - ex); + ex); } } @@ -132,7 +141,7 @@ 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")); } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 55d68d6..3684a5f 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -32,12 +32,16 @@ public class MinecraftChatModule extends Component { return DPUtils.channelData(getConfig(), "chatChannel", 239519012529111040L); } + public ConfigData modlogChannel() { + return DPUtils.channelData(getConfig(), "modlogChannel", 283840717275791360L); + } + @Override protected void enable() { 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 val chcons = getConfig().getConfig().getConfigurationSection("chcons"); if (chcons == null) //Fallback to old place From 5a9986de4fa6bba673ae69ab59d5fca192dfd0a0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 16 Feb 2019 00:39:48 +0100 Subject: [PATCH 04/14] Command stuff fixed Replies sanitized, userinfo converted Manually removing spaces Tested --- .../discordplugin/DiscordPlugin.java | 2 + .../discordplugin/commands/Command2DC.java | 2 +- .../commands/Command2DCSender.java | 5 +- .../commands/DiscordCommandBase.java | 1 - .../discordplugin/commands/ICommand2DC.java | 2 +- .../commands/UserinfoCommand.java | 190 +++++++++--------- .../commands/VersionCommand.java | 2 + .../listeners/CommandListener.java | 26 +-- 8 files changed, 114 insertions(+), 116 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index eab7e6e..d62b773 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -3,6 +3,7 @@ package buttondevteam.discordplugin; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; import buttondevteam.discordplugin.commands.Command2DC; import buttondevteam.discordplugin.commands.DiscordCommandBase; +import buttondevteam.discordplugin.commands.UserinfoCommand; import buttondevteam.discordplugin.commands.VersionCommand; import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; import buttondevteam.discordplugin.fun.FunModule; @@ -126,6 +127,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener DiscordCommandBase.registerCommands(); getManager().registerCommand(new VersionCommand()); + getManager().registerCommand(new UserinfoCommand()); if (ResetMCCommand.resetting) //These will only execute if the chat is enabled ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN) .withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java index 22565d9..e61d43f 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java @@ -22,7 +22,7 @@ public class Command2DC extends Command2 { @Override public void registerCommand(ICommand2DC command) { - registerCommand(command, subcommands, DiscordPlugin.getPrefix()); + registerCommand(command, subcommands, DiscordPlugin.getPrefix()); //Needs to be configurable for the helps } @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java index 5a04166..a2281f9 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java @@ -1,5 +1,6 @@ package buttondevteam.discordplugin.commands; +import buttondevteam.discordplugin.DPUtils; import buttondevteam.lib.chat.Command2Sender; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -11,11 +12,11 @@ public class Command2DCSender implements Command2Sender { @Override public void sendMessage(String message) { - this.message.reply(message); + this.message.reply(DPUtils.sanitizeString(message)); } @Override public void sendMessage(String[] message) { - this.message.reply(String.join("\n", message)); + this.message.reply(DPUtils.sanitizeString(String.join("\n", message))); } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java index d05964f..7f38d45 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java @@ -22,7 +22,6 @@ public abstract class DiscordCommandBase { public static void registerCommands() { commands.put("connect", new ConnectCommand()); // TODO: API for adding commands? - commands.put("userinfo", new UserinfoCommand()); commands.put("help", new HelpCommand()); commands.put("mcchat", new MCChatCommand()); commands.put("channelcon", new ChannelconCommand()); diff --git a/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java b/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java index c602c68..6aae802 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ICommand2DC.java @@ -6,7 +6,7 @@ import buttondevteam.lib.chat.ICommand2; import lombok.Getter; import lombok.val; -public abstract class ICommand2DC extends ICommand2 { +public abstract class ICommand2DC extends ICommand2 { public ICommand2DC() { super(DiscordPlugin.plugin.getManager()); val ann = getClass().getAnnotation(CommandClass.class); diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java index b1dbf8b..7954002 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java @@ -1,99 +1,91 @@ -package buttondevteam.discordplugin.commands; - -import buttondevteam.discordplugin.DiscordPlayer; -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.player.ChromaGamerBase; -import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; -import sx.blah.discord.handle.obj.IMessage; -import sx.blah.discord.handle.obj.IUser; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -public class UserinfoCommand extends DiscordCommandBase { - - @Override - public String getCommandName() { - return "userinfo"; - } - - @Override - public boolean run(IMessage message, String args) { - IUser target = null; - if (args.length() == 0) - target = message.getAuthor(); - else { - final Optional firstmention = message.getMentions().stream() - .filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst(); - if (firstmention.isPresent()) - target = firstmention.get(); - else if (args.contains("#")) { - String[] targettag = args.split("#"); - final List targets = getUsers(message, targettag[0]); - if (targets.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by name): " + args); - return true; - } - for (IUser ptarget : targets) { - if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { - target = ptarget; - break; - } - } - if (target == null) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by discriminator): " + args + "(Found " + targets.size() - + " users with the name.)"); - return true; - } - } else { - final List targets = getUsers(message, args); - if (targets.size() == 0) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found on Discord: " + args); - return true; - } - if (targets.size() > 1) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping."); - return true; - } - target = targets.get(0); - } - } - try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getStringID(), DiscordPlayer.class)) { - StringBuilder uinfo = new StringBuilder("User info for ").append(target.getName()).append(":\n"); - uinfo.append(dp.getInfo(InfoTarget.Discord)); - DiscordPlugin.sendMessageToChannel(message.getChannel(), uinfo.toString()); - } 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; - } - - private List getUsers(IMessage message, String args) { - final List targets; - if (message.getChannel().isPrivate()) - targets = DiscordPlugin.dc.getUsers().stream().filter(u -> u.getName().equalsIgnoreCase(args)) - .collect(Collectors.toList()); - else - targets = message.getGuild().getUsersByName(args, true); - return targets; - } - - @Override - public String[] getHelpText() { - return new String[] { // - "---- User information ----", // - "Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", // - "If used without args, shows your info.", // - "Usage: " + DiscordPlugin.getPrefix() + "userinfo [username/nickname[#tag]/ping]", // - "Examples:\n" + DiscordPlugin.getPrefix() + "userinfo ChromaBot\n" + DiscordPlugin.getPrefix() + "userinfo ChromaBot#6338\n" + DiscordPlugin.getPrefix() + "userinfo @ChromaBot#6338" // - }; - } - -} +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordPlayer; +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; +import buttondevteam.lib.player.ChromaGamerBase; +import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; +import lombok.val; +import sx.blah.discord.handle.obj.IMessage; +import sx.blah.discord.handle.obj.IUser; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@CommandClass(helpText = { + "User information", // + "Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", // + "If used without args, shows your info.", // +}) +public class UserinfoCommand extends ICommand2DC { + @Command2.Subcommand + public boolean def(Command2DCSender sender, @Command2.OptionalArg String args) { + val message = sender.getMessage(); + IUser target = null; + if (args == null || args.length() == 0) + target = message.getAuthor(); + else { + final Optional firstmention = message.getMentions().stream() + .filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst(); + if (firstmention.isPresent()) + target = firstmention.get(); + else if (args.contains("#")) { + String[] targettag = args.split("#"); + final List targets = getUsers(message, targettag[0]); + if (targets.size() == 0) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "The user cannot be found (by name): " + args); + return true; + } + for (IUser ptarget : targets) { + if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) { + target = ptarget; + break; + } + } + if (target == null) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "The user cannot be found (by discriminator): " + args + "(Found " + targets.size() + + " users with the name.)"); + return true; + } + } else { + final List targets = getUsers(message, args); + if (targets.size() == 0) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "The user cannot be found on Discord: " + args); + return true; + } + if (targets.size() > 1) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping."); + return true; + } + target = targets.get(0); + } + } + try (DiscordPlayer dp = ChromaGamerBase.getUser(target.getStringID(), DiscordPlayer.class)) { + StringBuilder uinfo = new StringBuilder("User info for ").append(target.getName()).append(":\n"); + uinfo.append(dp.getInfo(InfoTarget.Discord)); + DiscordPlugin.sendMessageToChannel(message.getChannel(), uinfo.toString()); + } 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; + } + + private List getUsers(IMessage message, String args) { + final List targets; + if (message.getChannel().isPrivate()) + targets = DiscordPlugin.dc.getUsers().stream().filter(u -> u.getName().equalsIgnoreCase(args)) + .collect(Collectors.toList()); + else + targets = message.getGuild().getUsersByName(args, true); + return targets; + } + +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java index cf0ee8c..ac83243 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/VersionCommand.java @@ -1,6 +1,7 @@ package buttondevteam.discordplugin.commands; import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; import lombok.val; @@ -9,6 +10,7 @@ import lombok.val; "Returns the plugin's version" }) public class VersionCommand extends ICommand2DC { + @Command2.Subcommand public boolean def(Command2DCSender sender) { sender.sendMessage(getVersion()); return true; diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index a9eae80..4093b07 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -21,7 +21,7 @@ public class CommandListener { final IChannel channel = message.getChannel(); if (!mentionedonly) { //mentionedonly conditions are in CommonListeners if (!message.getChannel().isPrivate() - && !(message.getContent().charAt(0) == DiscordPlugin.getPrefix() + && !(message.getContent().charAt(0) == DiscordPlugin.getPrefix() && channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) // return false; message.getChannel().setTypingStatus(true); // Fun @@ -38,9 +38,10 @@ public class CommandListener { return false; } message.getChannel().setTypingStatus(true); - String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command + String cmdwithargsString = cmdwithargs.toString(); try { - DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmdwithargsString); + if (!DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmdwithargsString)) + message.reply("Unknown command. Do " + DiscordPlugin.getPrefix() + "help for help.\n" + cmdwithargsString); } catch (Exception e) { TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e); } @@ -61,18 +62,19 @@ public class CommandListener { private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) { if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text - if (cmdwithargs.length() > mention.length() + 1) - cmdwithargs.delete(0, - cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length()); - else - cmdwithargs.replace(0, cmdwithargs.length(), "help"); + if (cmdwithargs.length() > mention.length() + 1) { + int x = mention.length(), px = x; + while ((x = cmdwithargs.indexOf(" ", px + 1)) != -1) //Removes any space before the command + px = x; + cmdwithargs.delete(0, px + 1); + cmdwithargs.insert(0, DiscordPlugin.getPrefix()); //Always use the prefix for processing + } else + cmdwithargs.replace(0, cmdwithargs.length(), DiscordPlugin.getPrefix() + "help"); else { - if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/') - cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat - return false; + return false; //Don't treat / as mention, mentions can be used in public mcchat } if (cmdwithargs.length() == 0) - cmdwithargs.replace(0, cmdwithargs.length(), "help"); + cmdwithargs.replace(0, cmdwithargs.length(), DiscordPlugin.getPrefix() + "help"); return true; } } From 0cbc22eb7251d6d891267fad8698b785c1c71acb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 16 Feb 2019 14:08:37 +0100 Subject: [PATCH 05/14] Added support for broadcast toggles #89 --- .../commands/ChannelconCommand.java | 136 +++++++++++------- .../discordplugin/mcchat/MCChatCustom.java | 9 +- .../discordplugin/mcchat/MCChatUtils.java | 2 +- .../mcchat/MinecraftChatModule.java | 9 +- 4 files changed, 97 insertions(+), 59 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java index df9398a..445d194 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java @@ -3,6 +3,9 @@ package buttondevteam.discordplugin.commands; import buttondevteam.core.component.channel.Channel; import buttondevteam.discordplugin.*; import buttondevteam.discordplugin.mcchat.MCChatCustom; +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; @@ -10,61 +13,80 @@ 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.ArrayList; import java.util.Arrays; import java.util.function.Supplier; import java.util.stream.Collectors; -public class ChannelconCommand extends DiscordCommandBase { - @Override - public String getCommandName() { - return "channelcon"; - } +@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; + } - @Override - public boolean run(IMessage message, String args) { - if (args.length() == 0) - return false; - if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) { - message.reply("you need to have manage permissions for this channel!"); - return true; - } - if (MCChatCustom.hasCustomChat(message.getChannel())) { - if (args.toLowerCase().startsWith("remove")) { - if (MCChatCustom.removeCustomChat(message.getChannel())) - message.reply("channel connection removed."); - else - message.reply("wait what, couldn't remove channel connection."); - return true; - } - if (args.toLowerCase().startsWith("toggle")) { - val cc = MCChatCustom.getCustomChat(message.getChannel()); - assert cc != null; //It's not null - Supplier togglesString = () -> Arrays.stream(ChannelconBroadcast.values()).map(t -> t.toString().toLowerCase() + ": " + ((cc.toggles & t.flag) == 0 ? "disabled" : "enabled")).collect(Collectors.joining("\n")); - String[] argsa = args.split(" "); - if (argsa.length < 2) { - message.reply("toggles:\n" + togglesString.get()); - return true; - } - String arg = argsa[1].toUpperCase(); - val b = Arrays.stream(ChannelconBroadcast.values()).filter(t -> t.toString().equals(arg)).findAny(); - if (!b.isPresent()) { - message.reply("cannot find toggle. Toggles:\n" + togglesString.get()); - return true; - } - //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; - } - message.reply("this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it."); - 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()); + assert cc != null; //It's not null + 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(TBMCSystemChatEvent.BroadcastTarget::getName).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 args) { + 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(args) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny(); if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW) message.reply("MC channel with ID '" + args + "' not found! The ID is the command for it without the /."); @@ -87,13 +109,21 @@ public class ChannelconCommand extends DiscordCommandBase { 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); + MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0, new ArrayList<>()); message.reply("alright, connection made to group `" + groupid + "`!"); return true; } - @Override - public String[] getHelpText() { + 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) { 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).", // diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java index fe0769a..4c0a62a 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java @@ -2,6 +2,7 @@ package buttondevteam.discordplugin.mcchat; import buttondevteam.core.component.channel.Channel; import buttondevteam.discordplugin.DiscordConnectedPlayer; +import buttondevteam.lib.TBMCSystemChatEvent; import lombok.NonNull; import lombok.val; import sx.blah.discord.handle.obj.IChannel; @@ -18,8 +19,8 @@ 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, List brtoggles) { + val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles, brtoggles); lastmsgCustom.add(lmd); } @@ -46,14 +47,16 @@ public class MCChatCustom { public final Channel mcchannel; public final DiscordConnectedPlayer dcp; public int toggles; + public List 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, List 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/MCChatUtils.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java index cd45dbe..56582ba 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatUtils.java @@ -172,7 +172,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); diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 3684a5f..069ac47 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,7 +15,9 @@ 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 { private @Getter MCChatListener listener; @@ -56,11 +59,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.toList())); }); } } @@ -79,7 +83,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 + } } From 0c9da49adda26b81240aa128275a93f60bb2a6ea Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 17 Feb 2019 02:26:14 +0100 Subject: [PATCH 06/14] Brtoggle & cmd fix #89 Channelcon Attempted to support chat rooms in custom chat --- .../discordplugin/DiscordPlugin.java | 2 + .../commands/DiscordCommandBase.java | 1 - .../listeners/CommandListener.java | 9 +-- .../ChannelconCommand.java | 72 +++++++++++-------- .../discordplugin/mcchat/MCChatCustom.java | 20 ++++-- .../mcchat/MinecraftChatModule.java | 2 +- 6 files changed, 65 insertions(+), 41 deletions(-) rename src/main/java/buttondevteam/discordplugin/{commands => mcchat}/ChannelconCommand.java (69%) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index d62b773..feb43df 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -9,6 +9,7 @@ import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; import buttondevteam.discordplugin.fun.FunModule; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.discordplugin.listeners.MCListener; +import buttondevteam.discordplugin.mcchat.ChannelconCommand; import buttondevteam.discordplugin.mcchat.MCChatPrivate; import buttondevteam.discordplugin.mcchat.MCChatUtils; import buttondevteam.discordplugin.mcchat.MinecraftChatModule; @@ -128,6 +129,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener DiscordCommandBase.registerCommands(); getManager().registerCommand(new VersionCommand()); getManager().registerCommand(new UserinfoCommand()); + getManager().registerCommand(new ChannelconCommand()); if (ResetMCCommand.resetting) //These will only execute if the chat is enabled ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN) .withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm diff --git a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java index 7f38d45..61d5fa1 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java @@ -24,7 +24,6 @@ public abstract class DiscordCommandBase { commands.put("connect", new ConnectCommand()); // TODO: API for adding commands? commands.put("help", new HelpCommand()); commands.put("mcchat", new MCChatCommand()); - commands.put("channelcon", new ChannelconCommand()); commands.put("debug", new DebugCommand()); } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 4093b07..4bdf572 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -63,10 +63,11 @@ public class CommandListener { private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) { if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text if (cmdwithargs.length() > mention.length() + 1) { - int x = mention.length(), px = x; - while ((x = cmdwithargs.indexOf(" ", px + 1)) != -1) //Removes any space before the command - px = x; - cmdwithargs.delete(0, px + 1); + int i = cmdwithargs.indexOf(" ", mention.length()); + //noinspection StatementWithEmptyBody + for (; i < cmdwithargs.length() && cmdwithargs.charAt(i) == ' '; i++) + ; //Removes any space before the command + cmdwithargs.delete(0, i); cmdwithargs.insert(0, DiscordPlugin.getPrefix()); //Always use the prefix for processing } else cmdwithargs.replace(0, cmdwithargs.length(), DiscordPlugin.getPrefix() + "help"); diff --git a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java similarity index 69% rename from src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java rename to src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java index 445d194..ceb184b 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/ChannelconCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java @@ -1,8 +1,10 @@ -package buttondevteam.discordplugin.commands; +package buttondevteam.discordplugin.mcchat; import buttondevteam.core.component.channel.Channel; +import buttondevteam.core.component.channel.ChatRoom; import buttondevteam.discordplugin.*; -import buttondevteam.discordplugin.mcchat.MCChatCustom; +import buttondevteam.discordplugin.commands.Command2DCSender; +import buttondevteam.discordplugin.commands.ICommand2DC; import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; @@ -14,12 +16,12 @@ import sx.blah.discord.handle.obj.Permissions; import sx.blah.discord.util.PermissionUtils; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.function.Supplier; import java.util.stream.Collectors; -@CommandClass(helpText = {"---- Channel connect ---", // +@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 .", // @@ -47,9 +49,10 @@ public class ChannelconCommand extends ICommand2DC { val message = sender.getMessage(); if (checkPerms(message)) return true; val cc = MCChatCustom.getCustomChat(message.getChannel()); - assert cc != null; //It's not null + 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(TBMCSystemChatEvent.BroadcastTarget::getName).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; @@ -82,37 +85,44 @@ public class ChannelconCommand extends ICommand2DC { } @Command2.Subcommand - public boolean def(Command2DCSender sender, String args) { + 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(args) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny(); - if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW) - message.reply("MC channel with ID '" + args + "' 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) { - message.reply("sorry, that didn't work. You cannot use that Minecraft channel."); - return true; - } + 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 ArrayList<>()); - message.reply("alright, connection made to group `" + groupid + "`!"); - return true; - } + 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)) { @@ -123,9 +133,9 @@ public class ChannelconCommand extends ICommand2DC { } @Override - public String[] getHelpText(Method method) { + public String[] getHelpText(Method method, Command2.Subcommand ann) { return new String[]{ // - "---- Channel connect ---", // + "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 .", // diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java index 4c0a62a..3d1b52f 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCustom.java @@ -1,6 +1,7 @@ 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; @@ -12,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 { /** @@ -19,7 +21,11 @@ public class MCChatCustom { */ static ArrayList lastmsgCustom = new ArrayList<>(); - public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles, List brtoggles) { + 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); } @@ -35,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() { @@ -47,10 +59,10 @@ public class MCChatCustom { public final Channel mcchannel; public final DiscordConnectedPlayer dcp; public int toggles; - public List brtoggles; + public Set brtoggles; private CustomLMD(@NonNull IChannel channel, @NonNull IUser user, - @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, List brtoggles) { + @NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, Set brtoggles) { super(channel, user); groupID = groupid; this.mcchannel = mcchannel; diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 069ac47..2fc89da 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -64,7 +64,7 @@ public class MinecraftChatModule extends Component { continue; Bukkit.getScheduler().runTask(getPlugin(), () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase) val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname")); - MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toList())); + MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet())); }); } } From 325b094bf7903e8f35fd5853645bdaa758cc0c9d Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 22 Feb 2019 00:44:13 +0100 Subject: [PATCH 07/14] Converted all commands Well, haven't finished the role command --- .../discordplugin/AnnouncerModule.java | 2 +- .../discordplugin/DiscordPlugin.java | 11 +- .../GeneralEventBroadcasterModule.java | 3 +- .../discordplugin/commands/Command2DC.java | 18 +-- .../commands/ConnectCommand.java | 137 ++++++++---------- .../discordplugin/commands/DebugCommand.java | 23 ++- .../commands/DiscordCommandBase.java | 61 -------- .../discordplugin/commands/HelpCommand.java | 56 +++---- .../exceptions/ExceptionListenerModule.java | 2 +- .../discordplugin/fun/FunModule.java | 2 +- .../listeners/CommandListener.java | 11 -- .../discordplugin/mcchat/MCChatCommand.java | 46 +++--- .../mcchat/MinecraftChatModule.java | 4 +- .../discordplugin/role/GameRoleModule.java | 5 +- .../discordplugin/role/RoleCommand.java | 16 +- 15 files changed, 130 insertions(+), 267 deletions(-) delete mode 100755 src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java diff --git a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java b/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java index 866635f..a4b8fda 100644 --- a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java +++ b/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java @@ -16,7 +16,7 @@ import sx.blah.discord.handle.obj.IMessage; import java.io.File; import java.util.List; -public class AnnouncerModule extends Component { +public class AnnouncerModule extends Component { public ConfigData channel() { return DPUtils.channelData(getConfig(), "channel", 239519012529111040L); } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index feb43df..92bfcbb 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -1,15 +1,11 @@ package buttondevteam.discordplugin; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; -import buttondevteam.discordplugin.commands.Command2DC; -import buttondevteam.discordplugin.commands.DiscordCommandBase; -import buttondevteam.discordplugin.commands.UserinfoCommand; -import buttondevteam.discordplugin.commands.VersionCommand; +import buttondevteam.discordplugin.commands.*; import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; import buttondevteam.discordplugin.fun.FunModule; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.discordplugin.listeners.MCListener; -import buttondevteam.discordplugin.mcchat.ChannelconCommand; import buttondevteam.discordplugin.mcchat.MCChatPrivate; import buttondevteam.discordplugin.mcchat.MCChatUtils; import buttondevteam.discordplugin.mcchat.MinecraftChatModule; @@ -126,10 +122,11 @@ public class DiscordPlugin extends ButtonPlugin implements IListener Component.registerComponent(this, new FunModule()); new ChromaBot(this).updatePlayerList(); //Initialize ChromaBot - The MCCHatModule is tested to be enabled - DiscordCommandBase.registerCommands(); getManager().registerCommand(new VersionCommand()); getManager().registerCommand(new UserinfoCommand()); - getManager().registerCommand(new ChannelconCommand()); + getManager().registerCommand(new HelpCommand()); + getManager().registerCommand(new DebugCommand()); + getManager().registerCommand(new ConnectCommand()); if (ResetMCCommand.resetting) //These will only execute if the chat is enabled ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN) .withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm diff --git a/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java b/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java index e8a71e7..9b57812 100644 --- a/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java +++ b/src/main/java/buttondevteam/discordplugin/broadcaster/GeneralEventBroadcasterModule.java @@ -1,11 +1,12 @@ package buttondevteam.discordplugin.broadcaster; import buttondevteam.discordplugin.DPUtils; +import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; import lombok.Getter; -public class GeneralEventBroadcasterModule extends Component { +public class GeneralEventBroadcasterModule extends Component { private static @Getter boolean hooked = false; @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java index e61d43f..c2decdb 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java @@ -3,26 +3,10 @@ package buttondevteam.discordplugin.commands; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.chat.Command2; -import java.util.HashMap; -import java.util.function.Function; - public class Command2DC extends Command2 { - private HashMap> subcommands = new HashMap<>(); - private HashMap, ParamConverter> paramConverters = new HashMap<>(); - - @Override - public void addParamConverter(Class cl, Function converter, String errormsg) { - addParamConverter(cl, converter, errormsg, paramConverters); - } - - @Override - public boolean handleCommand(Command2DCSender sender, String commandLine) throws Exception { - return handleCommand(sender, commandLine, subcommands, paramConverters); - } - @Override public void registerCommand(ICommand2DC command) { - registerCommand(command, subcommands, DiscordPlugin.getPrefix()); //Needs to be configurable for the helps + super.registerCommand(command, DiscordPlugin.getPrefix()); //Needs to be configurable for the helps } @Override diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java index 6e16c09..54f63e0 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java @@ -1,76 +1,61 @@ -package buttondevteam.discordplugin.commands; - -import buttondevteam.discordplugin.DiscordPlayer; -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.player.TBMCPlayer; -import buttondevteam.lib.player.TBMCPlayerBase; -import com.google.common.collect.HashBiMap; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import sx.blah.discord.handle.obj.IMessage; - -public class ConnectCommand extends DiscordCommandBase { - - @Override - public String getCommandName() { - return "connect"; - } - - /** - * Key: Minecraft name
- * Value: Discord ID - */ - public static HashBiMap WaitingToConnect = HashBiMap.create(); - - @Override - public boolean run(IMessage message, String args) { - if (args.length() == 0) - return false; - if (args.contains(" ")) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Too many arguments.\nUsage: " + DiscordPlugin.getPrefix() + "connect "); - return true; - } - if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + args); - WaitingToConnect.inverse().remove(message.getAuthor().getStringID()); - } - @SuppressWarnings("deprecation") - OfflinePlayer p = Bukkit.getOfflinePlayer(args); - if (p == null) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found"); - return true; - } - try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { - DiscordPlayer dp = pl.getAs(DiscordPlayer.class); - if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); - return true; - } - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e); - } - WaitingToConnect.put(p.getName(), message.getAuthor().getStringID()); - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Alright! Now accept the connection in Minecraft from the account " + args - + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command."); - if (p.isOnline()) - ((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#" - + message.getAuthor().getDiscriminator() + " do /discord accept"); - return true; - } - - @Override - public String[] getHelpText() { - return new String[] { // - "---- Connect command ----", // - "This command lets you connect your account with a Minecraft account. This allows using the Minecraft chat and other things.", // - "Usage: /connect " // - }; - } - -} +package buttondevteam.discordplugin.commands; + +import buttondevteam.discordplugin.DiscordPlayer; +import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; +import buttondevteam.lib.player.TBMCPlayer; +import buttondevteam.lib.player.TBMCPlayerBase; +import com.google.common.collect.HashBiMap; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import sx.blah.discord.handle.obj.IMessage; + +@CommandClass(helpText = { + "Connect command", // + "This command lets you connect your account with a Minecraft account. This allows using the Minecraft chat and other things.", // +}) +public class ConnectCommand extends ICommand2DC { + + /** + * Key: Minecraft name
+ * Value: Discord ID + */ + public static HashBiMap WaitingToConnect = HashBiMap.create(); + + @Command2.Subcommand + public boolean def(IMessage message, String Minecraftname) { + if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + Minecraftname); + WaitingToConnect.inverse().remove(message.getAuthor().getStringID()); + } + @SuppressWarnings("deprecation") + OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname); + if (p == null) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found"); + return true; + } + try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) { + DiscordPlayer dp = pl.getAs(DiscordPlayer.class); + if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) { + DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected."); + return true; + } + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e); + DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured!\n" + e); + } + WaitingToConnect.put(p.getName(), message.getAuthor().getStringID()); + DiscordPlugin.sendMessageToChannel(message.getChannel(), + "Alright! Now accept the connection in Minecraft from the account " + Minecraftname + + " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command."); + if (p.isOnline()) + ((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#" + + message.getAuthor().getDiscriminator() + " do /discord accept"); + return true; + } + +} diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java index b37e2b8..c623a63 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java @@ -2,25 +2,20 @@ package buttondevteam.discordplugin.commands; import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.listeners.CommonListeners; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; import sx.blah.discord.handle.obj.IMessage; -public class DebugCommand extends DiscordCommandBase { - @Override - public String getCommandName() { - return "debug"; - } - - @Override - public boolean run(IMessage message, String args) { - if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) +@CommandClass(helpText = { + "Switches debug mode." +}) +public class DebugCommand extends ICommand2DC { + @Command2.Subcommand + public boolean def(IMessage message, String args) { + if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) //TODO: Make configurable message.reply("Debug " + (CommonListeners.debug() ? "enabled" : "disabled")); else message.reply("You need to be a moderator to use this command."); return true; } - - @Override - public String[] getHelpText() { - return new String[]{"Switches debug mode."}; - } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java b/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java deleted file mode 100755 index 61d5fa1..0000000 --- a/src/main/java/buttondevteam/discordplugin/commands/DiscordCommandBase.java +++ /dev/null @@ -1,61 +0,0 @@ -package buttondevteam.discordplugin.commands; - -import buttondevteam.discordplugin.DiscordPlugin; -import buttondevteam.discordplugin.mcchat.MCChatCommand; -import buttondevteam.lib.TBMCCoreAPI; -import sx.blah.discord.handle.obj.IMessage; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.stream.Collectors; - -import static buttondevteam.discordplugin.listeners.CommonListeners.debug; - -public abstract class DiscordCommandBase { - public abstract String getCommandName(); - - public abstract boolean run(IMessage message, String args); - - public abstract String[] getHelpText(); - - static final HashMap commands = new HashMap(); - - public static void registerCommands() { - commands.put("connect", new ConnectCommand()); // TODO: API for adding commands? - commands.put("help", new HelpCommand()); - commands.put("mcchat", new MCChatCommand()); - commands.put("debug", new DebugCommand()); - } - - public static void runCommand(String cmd, String args, IMessage message) { - debug("F"); //Not sure if needed - DiscordCommandBase command = commands.get(cmd); - //if(command==null) - // DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmd+" "+args); //TODO! - if (command == null) { - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Unknown command: " + cmd + " with args: " + args + "\nDo '" - + (message.getChannel().isPrivate() ? "" : message.getClient().getOurUser().mention() + " ") - + "help' for help"); - return; - } - debug("G"); - try { - if (!command.run(message, args)) - DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n"))); - } catch (Exception e) { - TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e); - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "An internal error occured while executing this command. For more technical details see the server-issues channel on the dev Discord."); - } - debug("H"); - } - - protected String[] splitargs(String args) { - return args.split("\\s+"); - } - - public static void registerCommand(String name, DiscordCommandBase dcb) { - commands.put(name, dcb); - } -} diff --git a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java index bcef6ea..0194dab 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/HelpCommand.java @@ -1,38 +1,18 @@ -package buttondevteam.discordplugin.commands; - -import buttondevteam.discordplugin.DiscordPlugin; -import sx.blah.discord.handle.obj.IMessage; - -import java.util.stream.Collectors; - -public class HelpCommand extends DiscordCommandBase { - - @Override - public String getCommandName() { - return "help"; - } - - @Override - public boolean run(IMessage message, String args) { - DiscordCommandBase argdc; - if (args.length() == 0) - DiscordPlugin.sendMessageToChannel(message.getChannel(), - "Available commands:\n" + DiscordCommandBase.commands.values().stream() - .map(dc -> DiscordPlugin.getPrefix() + dc.getCommandName()).collect(Collectors.joining("\n"))); - else - DiscordPlugin.sendMessageToChannel(message.getChannel(), - (argdc = DiscordCommandBase.commands.get(args)) == null ? "Command not found: " + args - : String.join("\n", argdc.getHelpText())); - return true; - } - - @Override - public String[] getHelpText() { - return new String[] { // - "---- Help command ----", // - "Shows some info about a command or lists the available commands.", // - "Usage: " + DiscordPlugin.getPrefix() + "help [command]"// - }; - } - -} +package buttondevteam.discordplugin.commands; + +import buttondevteam.lib.chat.CommandClass; + +@CommandClass(helpText = { + "Help command", // + "Shows some info about a command or lists the available commands.", // +}) +public class HelpCommand extends ICommand2DC { + @Override + public boolean def(Command2DCSender sender, String args) { + if (args.length() == 0) + sender.sendMessage(getManager().getCommandsText()); + else + sender.sendMessage("Soon:tm:"); //TODO + return true; + } +} diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java index 6821e6f..b868586 100755 --- a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java +++ b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java @@ -19,7 +19,7 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -public class ExceptionListenerModule extends Component implements Listener { +public class ExceptionListenerModule extends Component implements Listener { private List lastthrown = new ArrayList<>(); private List lastsourcemsg = new ArrayList<>(); diff --git a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java index c5bfd8d..d7fcc86 100644 --- a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java +++ b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java @@ -26,7 +26,7 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -public class FunModule extends Component implements Listener { +public class FunModule extends Component implements Listener { private static FunModule mod; private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 4bdf572..1980bdf 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -45,17 +45,6 @@ public class CommandListener { } catch (Exception e) { TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e); } - /*int index = cmdwithargsString.indexOf(" "); - String cmd; - String args; - if (index == -1) { - cmd = cmdwithargsString; - args = ""; - } else { - cmd = cmdwithargsString.substring(0, index); - args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces - } - DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);*/ message.getChannel().setTypingStatus(false); return true; } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java index 3c05f02..fbe4e38 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, String args) { + 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/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 2fc89da..2d6e50b 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -19,7 +19,7 @@ import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; -public class MinecraftChatModule extends Component { +public class MinecraftChatModule extends Component { private @Getter MCChatListener listener; public MCChatListener getListener() { //It doesn't want to generate @@ -45,6 +45,8 @@ public class MinecraftChatModule extends Component { DiscordPlugin.dc.getDispatcher().registerListener(listener); TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled + getPlugin().getManager().registerCommand(new MCChatCommand()); + getPlugin().getManager().registerCommand(new ChannelconCommand()); val chcons = getConfig().getConfig().getConfigurationSection("chcons"); if (chcons == null) //Fallback to old place diff --git a/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java b/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java index 7bf3d2b..45fe9ec 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()); } diff --git a/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java b/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java index 1534e2b..822eb1a 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.ICommand2DC; import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; import sx.blah.discord.handle.obj.IMessage; 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 { //TODO private GameRoleModule grm; @@ -18,13 +21,8 @@ public class RoleCommand extends DiscordCommandBase { //TODO: Use Command2's par this.grm = grm; } - @Override - public String getCommandName() { - return "role"; - } - - @Override - public boolean run(IMessage message, String args) { + @Command2.Subcommand + public boolean def(IMessage message, String args) { if (args.length() == 0) return false; String[] argsa = splitargs(args); From ca5fb90774c88ea790d3ce2cf194083c857dd16b Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 23 Feb 2019 00:33:10 +0100 Subject: [PATCH 08/14] Command system fixes In encounter order: Lowercasing message first character on the sender Command sender fixes Mention deleting fixed if there is no space Added error handler to the message receive event Converted role command --- .../commands/Command2DCSender.java | 7 +- .../commands/ConnectCommand.java | 5 +- .../discordplugin/commands/DebugCommand.java | 9 +- .../listeners/CommandListener.java | 9 +- .../listeners/CommonListeners.java | 23 ++-- .../discordplugin/role/RoleCommand.java | 110 ++++++++---------- 6 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java index a2281f9..bdff52d 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DCSender.java @@ -12,11 +12,14 @@ public class Command2DCSender implements Command2Sender { @Override public void sendMessage(String message) { - this.message.reply(DPUtils.sanitizeString(message)); + if (message.length() == 0) return; + message = DPUtils.sanitizeString(message); + message = Character.toLowerCase(message.charAt(0)) + message.substring(1); + this.message.reply(message); } @Override public void sendMessage(String[] message) { - this.message.reply(DPUtils.sanitizeString(String.join("\n", message))); + sendMessage(String.join("\n", message)); } } diff --git a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java index 54f63e0..4e37e35 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/ConnectCommand.java @@ -8,10 +8,10 @@ import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayerBase; import com.google.common.collect.HashBiMap; +import lombok.val; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; -import sx.blah.discord.handle.obj.IMessage; @CommandClass(helpText = { "Connect command", // @@ -26,7 +26,8 @@ public class ConnectCommand extends ICommand2DC { public static HashBiMap WaitingToConnect = HashBiMap.create(); @Command2.Subcommand - public boolean def(IMessage message, String Minecraftname) { + public boolean def(Command2DCSender sender, String Minecraftname) { + val message = sender.getMessage(); if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) { DiscordPlugin.sendMessageToChannel(message.getChannel(), "Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + Minecraftname); diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java index c623a63..26fc30e 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java @@ -4,18 +4,17 @@ import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.listeners.CommonListeners; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import sx.blah.discord.handle.obj.IMessage; @CommandClass(helpText = { "Switches debug mode." }) public class DebugCommand extends ICommand2DC { @Command2.Subcommand - public boolean def(IMessage message, String args) { - if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) //TODO: Make configurable - message.reply("Debug " + (CommonListeners.debug() ? "enabled" : "disabled")); + public boolean def(Command2DCSender sender, String args) { + if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) //TODO: Make configurable + sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled")); else - message.reply("You need to be a moderator to use this command."); + sender.sendMessage("you need to be a moderator to use this command."); return true; } } diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java index 1980bdf..4f99d35 100644 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java @@ -53,9 +53,12 @@ public class CommandListener { if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text if (cmdwithargs.length() > mention.length() + 1) { int i = cmdwithargs.indexOf(" ", mention.length()); - //noinspection StatementWithEmptyBody - for (; i < cmdwithargs.length() && cmdwithargs.charAt(i) == ' '; i++) - ; //Removes any space before the command + if (i == -1) + i = mention.length(); + else + //noinspection StatementWithEmptyBody + for (; i < cmdwithargs.length() && cmdwithargs.charAt(i) == ' '; i++) + ; //Removes any space before the command cmdwithargs.delete(0, i); cmdwithargs.insert(0, DiscordPlugin.getPrefix()); //Always use the prefix for processing } else diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java index 9b60fc3..fa11f78 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java @@ -5,6 +5,7 @@ import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.fun.FunModule; import buttondevteam.discordplugin.mcchat.MinecraftChatModule; import buttondevteam.discordplugin.role.GameRoleModule; +import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; import lombok.val; import sx.blah.discord.api.events.IListener; @@ -35,16 +36,20 @@ public class CommonListeners { return; if (FunModule.executeMemes(event.getMessage())) return; - boolean handled = false; - if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat + try { + boolean handled = false; + if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat || event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels - handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here - if (handled) return; - val mcchat = Component.getComponents().get(MinecraftChatModule.class); - if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again - handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels - if (!handled) - handled = CommandListener.runCommand(event.getMessage(), false); + handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here + if (handled) return; + val mcchat = Component.getComponents().get(MinecraftChatModule.class); + if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again + handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels + if (!handled) + handled = CommandListener.runCommand(event.getMessage(), false); + } catch (Exception e) { + TBMCCoreAPI.SendException("An error occured while handling a message!", e); + } } }, new IListener() { @Override diff --git a/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java b/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java index 822eb1a..19d78cf 100755 --- a/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java +++ b/src/main/java/buttondevteam/discordplugin/role/RoleCommand.java @@ -2,18 +2,18 @@ package buttondevteam.discordplugin.role; import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DiscordPlugin; +import buttondevteam.discordplugin.commands.Command2DCSender; import buttondevteam.discordplugin.commands.ICommand2DC; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IRole; import java.util.List; import java.util.stream.Collectors; @CommandClass -public class RoleCommand extends ICommand2DC { //TODO +public class RoleCommand extends ICommand2DC { private GameRoleModule grm; @@ -21,78 +21,64 @@ public class RoleCommand extends ICommand2DC { //TODO this.grm = grm; } + @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 boolean def(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; + public void list(Command2DCSender sender) { + sender.sendMessage("list of roles:\n" + grm.GameRoles.stream().sorted().collect(Collectors.joining("\n"))); } - 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", // - }; - } - } From 0f1f7b4ead3d340340b6e1fabb0b86620cb1a693 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 1 Mar 2019 18:01:32 +0100 Subject: [PATCH 09/14] Better handling of missing token Also moved the token's location --- .../discordplugin/DiscordPlugin.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 92bfcbb..7063c39 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -23,6 +23,7 @@ import lombok.Getter; import lombok.val; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.scheduler.BukkitTask; @@ -79,7 +80,24 @@ public class DiscordPlugin extends ButtonPlugin implements IListener plugin = this; manager = new Command2DC(); ClientBuilder cb = new ClientBuilder(); - cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8)); + File tokenFile = new File("TBMC", "Token.txt"); + if (tokenFile.exists()) //Legacy support + //noinspection UnstableApiUsage + cb.withToken(Files.readFirstLine(tokenFile, StandardCharsets.UTF_8)); + else { + File privateFile = new File(getDataFolder(), "private.yml"); + val conf = YamlConfiguration.loadConfiguration(privateFile); + String token = conf.getString("token"); + if (token == null) { + conf.set("token", "Token goes here"); + conf.save(privateFile); + + getLogger().severe("Token not found! Set it in private.yml"); + Bukkit.getPluginManager().disablePlugin(this); + return; + } else + cb.withToken(token); + } dc = cb.login(); dc.getDispatcher().registerListener(this); } catch (Exception e) { @@ -177,6 +195,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener @Override public void pluginPreDisable() { + if (ChromaBot.getInstance() == null) return; //Failed to load EmbedObject embed; if (ResetMCCommand.resetting) embed = new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build(); @@ -207,6 +226,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener public void pluginDisable() { MCChatPrivate.logoutAll(); getConfig().set("serverup", false); + if (ChromaBot.getInstance() == null) return; //Failed to load saveConfig(); try { From 14c42614d89cd273450dacc47e29ceed400a9671 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 2 Mar 2019 19:04:38 +0100 Subject: [PATCH 10/14] #bot mention ch null handling, limiting tries Won't try to get channels forever, since they may be set incorrectly --- src/main/java/buttondevteam/discordplugin/DPUtils.java | 6 ++++-- .../java/buttondevteam/discordplugin/DiscordPlugin.java | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index e415298..fba8a7b 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -126,8 +126,10 @@ public final class DPUtils { * @return The string for mentioning the channel */ public static String botmention() { - if (DiscordPlugin.plugin == null) return "#bot"; - return DiscordPlugin.plugin.CommandChannel().get().mention(); + IChannel channel; + if (DiscordPlugin.plugin == null + || (channel = DiscordPlugin.plugin.CommandChannel().get()) == null) return "#bot"; + return channel.mention(); } } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 7063c39..fd5f2fa 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -43,6 +43,7 @@ import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class DiscordPlugin extends ButtonPlugin implements IListener { @@ -116,7 +117,14 @@ public class DiscordPlugin extends ButtonPlugin implements IListener public void handle(ReadyEvent event) { try { dc.changePresence(StatusType.DND, ActivityType.PLAYING, "booting"); + val tries = new AtomicInteger(); task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> { + tries.incrementAndGet(); + if (tries.get() > 10) { //5 seconds + task.cancel(); + getLogger().severe("Main or dev server not found! Set ID and do /discord reset"); + return; + } if (mainServer == null || devServer == null) { mainServer = event.getClient().getGuildByID(125813020357165056L); devServer = event.getClient().getGuildByID(219529124321034241L); From cadb53d886e602196ad13e18a8481d9805ddcf7f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 9 Mar 2019 02:07:56 +0100 Subject: [PATCH 11/14] Made the plugin work cleanly (#51) Clean install works pretty well Automatically setting first server as main server Removed devServer variable, getting the guild from the channels Disabling each component that doesn't have its channel(s)/role(s) set correctly (unless it's not required) Removed redundant variable from the FunModule Correctly handling missing channel settings in some places Checking any role position for game roles, not just "ChromaBot" The bot is playing Minecraft now Always giving permission for commands for now --- .../discordplugin/AnnouncerModule.java | 1 + .../buttondevteam/discordplugin/DPUtils.java | 41 +++++++++++++++++-- .../discordplugin/DiscordPlugin.java | 26 +++++++----- .../discordplugin/commands/Command2DC.java | 3 +- .../exceptions/ExceptionListenerModule.java | 17 +++++--- .../discordplugin/fun/FunModule.java | 27 +++++------- .../listeners/CommonListeners.java | 3 +- .../mcchat/ChannelconCommand.java | 2 +- .../discordplugin/mcchat/MCListener.java | 9 +++- .../mcchat/MinecraftChatModule.java | 1 + .../discordplugin/role/GameRoleModule.java | 25 ++++++----- 11 files changed, 104 insertions(+), 51 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java b/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java index a4b8fda..d0efe1e 100644 --- a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java +++ b/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java @@ -45,6 +45,7 @@ public class AnnouncerModule extends Component { @Override protected void enable() { + if (DPUtils.disableIfConfigError(this, channel(), modChannel())) return; stop = false; //If not the first time DPUtils.performNoWait(() -> { try { diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index fba8a7b..48d5963 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -1,10 +1,13 @@ package buttondevteam.discordplugin; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.architecture.IHaveConfig; import lombok.val; import org.bukkit.Bukkit; import sx.blah.discord.handle.obj.IChannel; +import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IIDLinkedObject; import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.util.EmbedBuilder; @@ -114,10 +117,14 @@ public final class DPUtils { } public static ConfigData roleData(IHaveConfig config, String key, String defName) { + return roleData(config, key, defName, DiscordPlugin.mainServer); + } + + public static ConfigData roleData(IHaveConfig config, String key, String defName, IGuild guild) { return config.getDataPrimDef(key, defName, name -> { - val roles = DiscordPlugin.mainServer.getRolesByName((String) name); - return roles.size() > 0 ? roles.get(0) : null; //TODO: May not handle null properly - }, IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer) + val roles = guild.getRolesByName((String) name); + return roles.size() > 0 ? roles.get(0) : null; + }, IIDLinkedObject::getLongID); } /** @@ -132,4 +139,32 @@ public final class DPUtils { return channel.mention(); } + /** + * Disables the component if one of the given configs return null. Useful for channel/role configs. + * + * @param component The component to disable if needed + * @param configs The configs to check for null + * @return Whether the component got disabled and a warning logged + */ + public static boolean disableIfConfigError(@Nullable Component component, ConfigData... configs) { + for (val config : configs) { + if (config.get() == null) { + String path = null; + try { + if (component != null) + Component.setComponentEnabled(component, false); + val f = ConfigData.class.getDeclaredField("path"); + f.setAccessible(true); //Hacking my own plugin + path = (String) f.get(config); + } catch (Exception e) { + TBMCCoreAPI.SendException("Failed to disable component after config error!", e); + } + getLogger().warning("The config value " + path + " isn't set correctly " + (component == null ? "in global settings!" : "for component " + component.getClass().getSimpleName() + "!")); + getLogger().warning("Set the correct ID in the config" + (component == null ? "" : " or disable this component") + " to remove this message."); + return true; + } + } + return false; + } + } diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index fd5f2fa..498ba31 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -108,7 +108,6 @@ public class DiscordPlugin extends ButtonPlugin implements IListener } public static IGuild mainServer; - public static IGuild devServer; private static volatile BukkitTask task; private static volatile boolean sent = false; @@ -122,17 +121,22 @@ public class DiscordPlugin extends ButtonPlugin implements IListener tries.incrementAndGet(); if (tries.get() > 10) { //5 seconds task.cancel(); - getLogger().severe("Main or dev server not found! Set ID and do /discord reset"); + getLogger().severe("Main server not found! Invite the bot and do /discord reset"); + //getIConfig().getConfig().set("mainServer", 219529124321034241L); //Needed because it won't save as long as it's null - made it save + saveConfig(); //Put default there return; } - if (mainServer == null || devServer == null) { - mainServer = event.getClient().getGuildByID(125813020357165056L); - devServer = event.getClient().getGuildByID(219529124321034241L); - } - if (mainServer == null || devServer == null) - return; // Retry + mainServer = MainServer().get(); //Shouldn't change afterwards + if (mainServer == null) { + val guilds = dc.getGuilds(); + if (guilds.size() == 0) + return; //If there are no guilds in cache, retry + mainServer = guilds.get(0); + getLogger().warning("Main server set to first one: " + mainServer.getName()); + MainServer().set(mainServer); //Save in config + } if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable() - dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft"); + dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Minecraft"); } else { dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing"); } @@ -140,6 +144,8 @@ public class DiscordPlugin extends ButtonPlugin implements IListener if (task != null) task.cancel(); if (!sent) { + DPUtils.disableIfConfigError(null, CommandChannel(), ModRole()); //Won't disable, just prints the warning here + Component.registerComponent(this, new GeneralEventBroadcasterModule()); Component.registerComponent(this, new MinecraftChatModule()); Component.registerComponent(this, new ExceptionListenerModule()); @@ -242,7 +248,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener ChromaBot.delete(); dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing dc.logout(); - mainServer = devServer = null; //Fetch servers and channels again + //Configs are emptied so channels and servers are fetched again sent = false; } catch (Exception e) { TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e); diff --git a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java index c2decdb..a0b8fda 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java +++ b/src/main/java/buttondevteam/discordplugin/commands/Command2DC.java @@ -11,6 +11,7 @@ public class Command2DC extends Command2 { @Override public boolean hasPermission(Command2DCSender sender, ICommand2DC command) { - return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()); + //return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()); //TODO: ModRole may be null; more customisable way? + return true; } } diff --git a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java index b868586..5d21bb1 100755 --- a/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java +++ b/src/main/java/buttondevteam/discordplugin/exceptions/ExceptionListenerModule.java @@ -12,6 +12,7 @@ import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import sx.blah.discord.handle.obj.IChannel; +import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IRole; import java.util.ArrayList; @@ -43,15 +44,14 @@ public class ExceptionListenerModule extends Component implements e.setHandled(); } - private static IRole coderRole; - private static void SendException(Throwable e, String sourcemessage) { if (instance == null) return; try { - if (coderRole == null) - coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0); + IChannel channel = getChannel(); + assert channel != null; + IRole coderRole = instance.pingRole(channel.getGuild()).get(); StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder() - : new StringBuilder(coderRole.mention()).append("\n"); + : new StringBuilder(coderRole == null ? "" : coderRole.mention()).append("\n"); sb.append(sourcemessage).append("\n"); sb.append("```").append("\n"); String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n")) @@ -61,7 +61,7 @@ public class ExceptionListenerModule extends Component implements stackTrace = stackTrace.substring(0, 1800); sb.append(stackTrace).append("\n"); sb.append("```"); - DiscordPlugin.sendMessageToChannel(getChannel(), sb.toString()); //Instance isn't null here + DiscordPlugin.sendMessageToChannel(channel, sb.toString()); //Instance isn't null here } catch (Exception ex) { ex.printStackTrace(); } @@ -78,8 +78,13 @@ public class ExceptionListenerModule extends Component implements return DPUtils.channelData(getConfig(), "channel", 239519012529111040L); } + private ConfigData pingRole(IGuild guild) { + return DPUtils.roleData(getConfig(), "pingRole", "Coder", guild); + } + @Override protected void enable() { + if (DPUtils.disableIfConfigError(this, channel())) return; instance = this; Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin()); diff --git a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java index d7fcc86..f5adf0d 100644 --- a/src/main/java/buttondevteam/discordplugin/fun/FunModule.java +++ b/src/main/java/buttondevteam/discordplugin/fun/FunModule.java @@ -13,10 +13,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent; -import sx.blah.discord.handle.obj.IChannel; -import sx.blah.discord.handle.obj.IMessage; -import sx.blah.discord.handle.obj.IRole; -import sx.blah.discord.handle.obj.StatusType; +import sx.blah.discord.handle.obj.*; import sx.blah.discord.util.EmbedBuilder; import java.util.ArrayList; @@ -27,8 +24,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; public class FunModule extends Component implements Listener { - private static FunModule mod; - private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali "Between now and the heat-death of the universe.", // Ghostise "Soon™", "Ask again this time next month", // Ghostise @@ -68,7 +63,6 @@ public class FunModule extends Component implements Listener { @Override protected void enable() { - mod = this; registerListener(this); } @@ -99,7 +93,7 @@ public class FunModule extends Component implements Listener { return true; //Handled } lastlistp = (short) Bukkit.getOnlinePlayers().size(); //Didn't handle - if (mod.serverReady().get()) { + if (fm.serverReady().get()) { if (!TBMCCoreAPI.IsTestServer() && Arrays.stream(serverReadyQuestions).anyMatch(msglowercased::contains)) { int next; @@ -118,11 +112,8 @@ public class FunModule extends Component implements Listener { ListC = 0; } - private ConfigData fullHouseDevRole() { - return getConfig().getDataPrimDef("fullHouseDevRole", "Developer", name -> { - val list = DiscordPlugin.devServer.getRolesByName((String) name); - return list.size() > 0 ? list.get(0) : null; - }, IRole::getName); + private ConfigData fullHouseDevRole(IGuild guild) { + return DPUtils.roleData(getConfig(), "fullHouseDevRole", "Developer", guild); } @@ -135,17 +126,19 @@ public class FunModule extends Component implements Listener { public static void handleFullHouse(PresenceUpdateEvent event) { val fm = ComponentManager.getIfEnabled(FunModule.class); if (fm == null) return; - val devrole = fm.fullHouseDevRole().get(); + val channel = fm.fullHouseChannel().get(); + if (channel == null) return; + val devrole = fm.fullHouseDevRole(channel.getGuild()).get(); if (devrole == null) return; if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE) && !event.getNewPresence().getStatus().equals(StatusType.OFFLINE) - && event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream() + && event.getUser().getRolesForGuild(channel.getGuild()).stream() .anyMatch(r -> r.getLongID() == devrole.getLongID()) - && DiscordPlugin.devServer.getUsersByRole(devrole).stream() + && channel.getGuild().getUsersByRole(devrole).stream() .noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE)) && lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime()) && Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) { - DiscordPlugin.sendMessageToChannel(mod.fullHouseChannel().get(), "Full house!", + DiscordPlugin.sendMessageToChannel(channel, "Full house!", new EmbedBuilder() .withImage( "https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png") diff --git a/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java index fa11f78..5350b32 100755 --- a/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java +++ b/src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java @@ -38,7 +38,8 @@ public class CommonListeners { return; try { boolean handled = false; - if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat + val commandChannel = DiscordPlugin.plugin.CommandChannel().get(); + if ((commandChannel != null && event.getChannel().getLongID() == commandChannel.getLongID()) //If mentioned, that's higher than chat || event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here if (handled) return; diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java index ceb184b..2bd2bb6 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/ChannelconCommand.java @@ -144,7 +144,7 @@ public class ChannelconCommand extends ICommand2DC { "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: " // + "Invite link: " // TODO: Set correct client ID }; } } diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java index fbf9d27..6cc9f5b 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java @@ -108,6 +108,7 @@ class MCListener implements Listener { try { DPUtils.performNoWait(() -> { final IRole role = muteRole().get(); + if (role == null) return; final CommandSource source = e.getAffected().getSource(); if (!source.isPlayer()) return; @@ -120,7 +121,11 @@ class MCListener implements Listener { user.addRole(role); else user.removeRole(role); - DiscordPlugin.sendMessageToChannel(module.modlogChannel().get(), (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() + "!", @@ -143,7 +148,7 @@ class MCListener implements Listener { String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName() : event.getSender().getName(); //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO - MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s")); + MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s")); //TODO: Don't require emoji } @EventHandler diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 2d6e50b..789fd2d 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -41,6 +41,7 @@ public class MinecraftChatModule extends Component { @Override protected void enable() { + if (DPUtils.disableIfConfigError(this, chatChannel())) return; listener = new MCChatListener(this); DiscordPlugin.dc.getDispatcher().registerListener(listener); TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin()); diff --git a/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java b/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java index 45fe9ec..8806647 100644 --- a/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java +++ b/src/main/java/buttondevteam/discordplugin/role/GameRoleModule.java @@ -40,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."); + } } } } @@ -73,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 } } From b39a57124600237b4309cc448f09318081b43f04 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 9 Mar 2019 23:09:27 +0100 Subject: [PATCH 12/14] Made excluded plugins configurable Using configable mod role in debug command Also moved the AnnouncerModule --- .../discordplugin/DiscordPlugin.java | 1 + .../{ => announcer}/AnnouncerModule.java | 5 +- .../discordplugin/commands/DebugCommand.java | 2 +- .../discordplugin/listeners/MCListener.java | 73 ------------------- .../discordplugin/mcchat/MCChatPrivate.java | 6 +- .../discordplugin/mcchat/MCChatUtils.java | 71 ++++++++++++++++++ .../discordplugin/mcchat/MCListener.java | 4 +- .../mcchat/MinecraftChatModule.java | 19 +++++ 8 files changed, 100 insertions(+), 81 deletions(-) rename src/main/java/buttondevteam/discordplugin/{ => announcer}/AnnouncerModule.java (96%) diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index 498ba31..6d71070 100755 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -1,5 +1,6 @@ package buttondevteam.discordplugin; +import buttondevteam.discordplugin.announcer.AnnouncerModule; import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule; import buttondevteam.discordplugin.commands.*; import buttondevteam.discordplugin.exceptions.ExceptionListenerModule; diff --git a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java b/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.java similarity index 96% rename from src/main/java/buttondevteam/discordplugin/AnnouncerModule.java rename to src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.java index d0efe1e..c434dce 100644 --- a/src/main/java/buttondevteam/discordplugin/AnnouncerModule.java +++ b/src/main/java/buttondevteam/discordplugin/announcer/AnnouncerModule.java @@ -1,5 +1,8 @@ -package buttondevteam.discordplugin; +package buttondevteam.discordplugin.announcer; +import buttondevteam.discordplugin.DPUtils; +import buttondevteam.discordplugin.DiscordPlayer; +import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; diff --git a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java index 26fc30e..2cf87fb 100644 --- a/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/DebugCommand.java @@ -11,7 +11,7 @@ import buttondevteam.lib.chat.CommandClass; public class DebugCommand extends ICommand2DC { @Command2.Subcommand public boolean def(Command2DCSender sender, String args) { - if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L))) //TODO: Make configurable + if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get())) sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled")); else sender.sendMessage("you need to be a moderator to use this command."); 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/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 56582ba..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; @@ -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 6cc9f5b..981446d 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java @@ -38,7 +38,7 @@ class MCListener implements Listener { 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, ""))); + .ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); } @EventHandler(priority = EventPriority.LOWEST) @@ -70,7 +70,7 @@ class MCListener implements Listener { 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, "")))); + .ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, ChromaBot.getInstance()::updatePlayerList, 5); final String message = e.GetPlayer().PlayerName().get() + " left the game"; diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java index 789fd2d..509ea66 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MinecraftChatModule.java @@ -19,6 +19,9 @@ import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; +/** + * Provides Minecraft chat connection to Discord. Commands may be used either in a public chat (limited) or in a DM. + */ public class MinecraftChatModule extends Component { private @Getter MCChatListener listener; @@ -26,19 +29,35 @@ public class MinecraftChatModule extends Component { 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; From 2b4034b05f6322eef7559599c6b306839496c188 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 14 Mar 2019 16:40:58 +0100 Subject: [PATCH 13/14] NPE and 2 cmd fix --- .../buttondevteam/discordplugin/DPUtils.java | 1 + .../discordplugin/commands/UserinfoCommand.java | 16 ++++++++-------- .../discordplugin/mcchat/MCChatCommand.java | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/buttondevteam/discordplugin/DPUtils.java b/src/main/java/buttondevteam/discordplugin/DPUtils.java index 48d5963..c21cceb 100755 --- a/src/main/java/buttondevteam/discordplugin/DPUtils.java +++ b/src/main/java/buttondevteam/discordplugin/DPUtils.java @@ -122,6 +122,7 @@ public final class DPUtils { public static ConfigData roleData(IHaveConfig config, String key, String defName, IGuild guild) { return config.getDataPrimDef(key, defName, name -> { + if (!(name instanceof String)) return null; val roles = guild.getRolesByName((String) name); return roles.size() > 0 ? roles.get(0) : null; }, IIDLinkedObject::getLongID); diff --git a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java index 7954002..0433c81 100755 --- a/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java +++ b/src/main/java/buttondevteam/discordplugin/commands/UserinfoCommand.java @@ -22,22 +22,22 @@ import java.util.stream.Collectors; }) public class UserinfoCommand extends ICommand2DC { @Command2.Subcommand - public boolean def(Command2DCSender sender, @Command2.OptionalArg String args) { + public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) { val message = sender.getMessage(); IUser target = null; - if (args == null || args.length() == 0) + if (user == null || user.length() == 0) target = message.getAuthor(); else { final Optional firstmention = message.getMentions().stream() .filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst(); if (firstmention.isPresent()) target = firstmention.get(); - else if (args.contains("#")) { - String[] targettag = args.split("#"); + else if (user.contains("#")) { + String[] targettag = user.split("#"); final List targets = getUsers(message, targettag[0]); if (targets.size() == 0) { DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by name): " + args); + "The user cannot be found (by name): " + user); return true; } for (IUser ptarget : targets) { @@ -48,15 +48,15 @@ public class UserinfoCommand extends ICommand2DC { } if (target == null) { DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found (by discriminator): " + args + "(Found " + targets.size() + "The user cannot be found (by discriminator): " + user + "(Found " + targets.size() + " users with the name.)"); return true; } } else { - final List targets = getUsers(message, args); + final List targets = getUsers(message, user); if (targets.size() == 0) { DiscordPlugin.sendMessageToChannel(message.getChannel(), - "The user cannot be found on Discord: " + args); + "The user cannot be found on Discord: " + user); return true; } if (targets.size() > 1) { diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java index fbe4e38..23af46f 100755 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCChatCommand.java @@ -18,7 +18,7 @@ import lombok.val; public class MCChatCommand extends ICommand2DC { @Command2.Subcommand - public boolean def(Command2DCSender sender, String args) { + public boolean def(Command2DCSender sender) { val message = sender.getMessage(); if (!message.getChannel().isPrivate()) { message.reply("this command can only be issued in a direct message with the bot."); From 22bdc3fa620fa25b4b398a1ae4bf57a0f119cea0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 16 Mar 2019 14:49:27 +0100 Subject: [PATCH 14/14] YEEHAW fix, reload command --- .../discordplugin/mcchat/MCListener.java | 3 ++- .../mccommands/ReloadMCCommand.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/main/java/buttondevteam/discordplugin/mccommands/ReloadMCCommand.java diff --git a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java index 981446d..3ed7bcf 100644 --- a/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java +++ b/src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java @@ -148,7 +148,8 @@ class MCListener implements Listener { String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName() : event.getSender().getName(); //Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO - MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s")); //TODO: Don't require emoji + 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/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." + }; + } +}