diff --git a/pom.xml b/pom.xml index e96a8c9f..106bf6f0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,12 +12,12 @@ BaristaGerald 0.0.1-SNAPSHOT BaristaGerald - - ${project.artifactId}-${project.version} - - - src - ${finalName} + + ${project.artifactId}-${project.version} + + + src + ${finalName} org.apache.maven.plugins @@ -30,7 +30,7 @@ maven-compiler-plugin - 3.8.1 + 3.8.1 1.8 1.8 @@ -39,7 +39,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.2.4 package @@ -48,18 +48,18 @@ - - META-INF/spring.handlers - - - META-INF/spring.factories - - - META-INF/spring.schemas - + + META-INF/spring.handlers + + + META-INF/spring.factories + + + META-INF/spring.schemas + main.java.de.voidtech.gerald.Gerald @@ -76,7 +76,7 @@ jcenter jcenter-bintray https://jcenter.bintray.com - + @@ -84,11 +84,11 @@ JDA 4.2.0_247 - - club.minnced - opus-java - - + + club.minnced + opus-java + + org.junit.jupiter @@ -165,10 +165,36 @@ 5.2.7.RELEASE - org.apache.commons - commons-text - 1.9 + org.apache.commons + commons-text + 1.9 + + + com.microsoft.playwright + playwright + 1.12.1 + + + com.github.twitch4j + twitch4j + 1.5.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.12.3 + + + com.fasterxml.jackson.core + jackson-core + 2.12.3 + + + com.fasterxml.jackson.core + jackson-annotations + 2.12.3 - + + \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/Gerald.java b/src/main/java/de/voidtech/gerald/Gerald.java index b8a2834d..454a04d4 100644 --- a/src/main/java/de/voidtech/gerald/Gerald.java +++ b/src/main/java/de/voidtech/gerald/Gerald.java @@ -1,6 +1,6 @@ /* BaristaGerald A General Purpose Discord Bot - Copyright (C) 2020-2021 Barista Gerald Dev Team (http://github.com/Montori/Barista-Gerald) + Copyright (C) 2020-2021 Barista Gerald Dev Team (https://github.com/Gerald-Development/Barista-Gerald) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,7 +68,7 @@ public JDA getJDA(MessageListener msgListener, GuildGoneListener guildGoneListen .enableIntents(getNonPrivilegedIntents()) .setMemberCachePolicy(MemberCachePolicy.ALL) .setBulkDeleteSplittingEnabled(false) - .setStatus(OnlineStatus.IDLE) + .setStatus(OnlineStatus.ONLINE) .setCompression(Compression.NONE) .addEventListeners(eventWaiter, msgListener, readyListener, guildGoneListener, channelDeleteListener, memberListener, starboardListener) .setActivity(EntityBuilder.createActivity(globalConf.getStatus(), diff --git a/src/main/java/de/voidtech/gerald/GlobalConstants.java b/src/main/java/de/voidtech/gerald/GlobalConstants.java index b897a8c6..18f89a28 100644 --- a/src/main/java/de/voidtech/gerald/GlobalConstants.java +++ b/src/main/java/de/voidtech/gerald/GlobalConstants.java @@ -4,5 +4,5 @@ public class GlobalConstants { public static final String STREAM_URL = "https://twitch.tv/elementalmp4"; public static final String LINKTREE_URL = "https://linktr.ee/GeraldBot"; public static final String INVITE_URL = "https://discord.com/api/oauth2/authorize?client_id=555816892141404163&permissions=805694544&scope=bot"; - public static final String VERSION = "1.1.4 - Latte Macchiato"; + public static final String VERSION = "1.2.0 - Mucho Mocha"; } diff --git a/src/main/java/de/voidtech/gerald/commands/AbstractCommand.java b/src/main/java/de/voidtech/gerald/commands/AbstractCommand.java index 201f6f01..0961dab4 100644 --- a/src/main/java/de/voidtech/gerald/commands/AbstractCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/AbstractCommand.java @@ -21,12 +21,18 @@ public abstract class AbstractCommand{ ThreadManager threadManager; private void runCommandInThread(Message message, List args) { - Runnable commandThreadRunnable = new Runnable() { - public void run() { - executeInternal(message, args); - } - }; - threadManager.getThreadByName("T-Command").execute(commandThreadRunnable); + if (message.getChannel().getType() == ChannelType.PRIVATE && !this.isDMCapable()) { + message.getChannel().sendMessage("**You can only use this command in guilds!**").queue(); + } else if (this.requiresArguments() && args.size() < 1) { + message.getChannel().sendMessage("**This command needs arguments to work! See the help command for more details!**\n" + this.getUsage()).queue(); + } else { + Runnable commandThreadRunnable = new Runnable() { + public void run() { + executeInternal(message, args); + } + }; + threadManager.getThreadByName("T-Command").execute(commandThreadRunnable); + } } public void run(Message message, List args) { @@ -43,7 +49,7 @@ public void run(Message message, List args) { if((channelWhitelisted && !commandOnBlacklist) || message.getMember().hasPermission(Permission.ADMINISTRATOR)) { runCommandInThread(message, args); - } + } } } @@ -62,5 +68,7 @@ public void run(Message message, List args) { public abstract boolean requiresArguments(); public abstract String[] getCommandAliases(); + + public abstract boolean canBeDisabled(); } diff --git a/src/main/java/de/voidtech/gerald/commands/TestCommand.java b/src/main/java/de/voidtech/gerald/commands/TestCommand.java index 5d798a8f..a5147076 100644 --- a/src/main/java/de/voidtech/gerald/commands/TestCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/TestCommand.java @@ -52,4 +52,9 @@ public String[] getCommandAliases() { String[] aliases = {"test"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/CuddleCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/CuddleCommand.java index 7a8ea86e..42e286c4 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/CuddleCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/CuddleCommand.java @@ -50,4 +50,9 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/HugCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/HugCommand.java index 59e210e5..b4f04fbf 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/HugCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/HugCommand.java @@ -49,5 +49,10 @@ public String[] getCommandAliases() { String[] aliases = {"hold"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/KissCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/KissCommand.java index 573ebd9b..2aa588a7 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/KissCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/KissCommand.java @@ -49,5 +49,10 @@ public String[] getCommandAliases() { String[] aliases = {"peck", "canoodle"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/NomCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/NomCommand.java index e0ce11ba..6abc4db3 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/NomCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/NomCommand.java @@ -49,4 +49,9 @@ public String[] getCommandAliases() { String[] aliases = {"bite"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/PatCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/PatCommand.java index afaed3e5..c44a740b 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/PatCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/PatCommand.java @@ -49,4 +49,9 @@ public String[] getCommandAliases() { String[] aliases = {"headpat"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/PokeCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/PokeCommand.java index d0d2edcd..e2491884 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/PokeCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/PokeCommand.java @@ -49,4 +49,9 @@ public String[] getCommandAliases() { String[] aliases = {"boop"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/SlapCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/SlapCommand.java index 152f7e7c..6885f33e 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/SlapCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/SlapCommand.java @@ -49,5 +49,10 @@ public String[] getCommandAliases() { String[] aliases = {"smack", "hit", "punch", "kill"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/actions/TickleCommand.java b/src/main/java/de/voidtech/gerald/commands/actions/TickleCommand.java index 84a66e61..547864b2 100644 --- a/src/main/java/de/voidtech/gerald/commands/actions/TickleCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/actions/TickleCommand.java @@ -49,5 +49,9 @@ public String[] getCommandAliases() { String[] aliases = {"fondle"}; return aliases; } - + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/effects/AccentCommand.java b/src/main/java/de/voidtech/gerald/commands/effects/AccentCommand.java index f82bef6d..6e8da132 100644 --- a/src/main/java/de/voidtech/gerald/commands/effects/AccentCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/effects/AccentCommand.java @@ -81,5 +81,10 @@ public String[] getCommandAliases() { String[] commandAliases = {"a"}; return commandAliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/effects/ClapCommand.java b/src/main/java/de/voidtech/gerald/commands/effects/ClapCommand.java index 05c072e1..8938a9a7 100644 --- a/src/main/java/de/voidtech/gerald/commands/effects/ClapCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/effects/ClapCommand.java @@ -51,4 +51,9 @@ public String[] getCommandAliases() { String[] aliases = {"clapback"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/effects/EmojifyCommand.java b/src/main/java/de/voidtech/gerald/commands/effects/EmojifyCommand.java index c9a0b58f..b5e2a448 100644 --- a/src/main/java/de/voidtech/gerald/commands/effects/EmojifyCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/effects/EmojifyCommand.java @@ -97,4 +97,9 @@ public String[] getCommandAliases() { String[] aliases = {"big"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/effects/SignCommand.java b/src/main/java/de/voidtech/gerald/commands/effects/SignCommand.java index 59c8f04a..bc745226 100644 --- a/src/main/java/de/voidtech/gerald/commands/effects/SignCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/effects/SignCommand.java @@ -103,4 +103,8 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/effects/ZalgoCommand.java b/src/main/java/de/voidtech/gerald/commands/effects/ZalgoCommand.java index b4b2ed28..324efdc2 100644 --- a/src/main/java/de/voidtech/gerald/commands/effects/ZalgoCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/effects/ZalgoCommand.java @@ -99,5 +99,10 @@ public String[] getCommandAliases() { String[] aliases = {"zalgoify", "fucktext"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/ApodCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/ApodCommand.java index 6a564721..7b505c87 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/ApodCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/ApodCommand.java @@ -98,4 +98,9 @@ public String[] getCommandAliases() { String[] aliases = {"nasa", "nasaapod", "astronomy"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/AskCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/AskCommand.java index 271dd9b8..0b194d76 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/AskCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/AskCommand.java @@ -77,4 +77,9 @@ public String[] getCommandAliases() { String[] aliases = {"whatif"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/BerryCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/BerryCommand.java index 31ead339..552a4d57 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/BerryCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/BerryCommand.java @@ -127,5 +127,10 @@ public String[] getCommandAliases() { String[] aliases = {"bguess", "berryguess"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/CatCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/CatCommand.java index 4ed4f3ec..552b5662 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/CatCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/CatCommand.java @@ -94,5 +94,10 @@ public String[] getCommandAliases() { String[] aliases = {"gato", "catto"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/ChatCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/ChatCommand.java index a5e0c830..16d35c62 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/ChatCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/ChatCommand.java @@ -161,5 +161,10 @@ public String[] getCommandAliases() { String[] aliases = {"ai", "geraldai", "geraldchat", "gavin"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/CitrusCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/CitrusCommand.java index 7e9f5e0d..7da96461 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/CitrusCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/CitrusCommand.java @@ -108,5 +108,10 @@ public String[] getCommandAliases() { String[] aliases = {"cguess", "citrusguess"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/CoinflipCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/CoinflipCommand.java index e53529db..fad16ebc 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/CoinflipCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/CoinflipCommand.java @@ -51,5 +51,10 @@ public String[] getCommandAliases() { String[] aliases = {"coin", "flip"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/ComplimentCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/ComplimentCommand.java index 7bec58aa..9743a0d7 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/ComplimentCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/ComplimentCommand.java @@ -70,5 +70,10 @@ public String[] getCommandAliases() { String[] aliases = {"respect"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/CountCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/CountCommand.java index 882b99eb..b41792a8 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/CountCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/CountCommand.java @@ -229,4 +229,9 @@ public String[] getCommandAliases() { String[] aliases = {"counting"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/fun/DeathmatchCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/DeathmatchCommand.java index b7386cb1..d8570625 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/DeathmatchCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/DeathmatchCommand.java @@ -142,5 +142,10 @@ public String[] getCommandAliases() { String[] aliases = {"fight", "battle", "challenge"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/DefineCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/DefineCommand.java index 3e67109f..2cd3007a 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/DefineCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/DefineCommand.java @@ -105,5 +105,10 @@ public String[] getCommandAliases() { String[] aliases = {"ud", "urbandictionary"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/DogCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/DogCommand.java index bcf7556a..935f70e5 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/DogCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/DogCommand.java @@ -94,5 +94,10 @@ public String[] getCommandAliases() { String[] aliases = {"doge", "doggo"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/EightballCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/EightballCommand.java index 281f0e7d..40149d3c 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/EightballCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/EightballCommand.java @@ -52,4 +52,9 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/FactCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/FactCommand.java index e7e8727c..262bb5d3 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/FactCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/FactCommand.java @@ -84,5 +84,10 @@ public String[] getCommandAliases() { String[] aliases = {"uselessfact"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/ImpersonateCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/ImpersonateCommand.java index eff6d18d..eec25e60 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/ImpersonateCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/ImpersonateCommand.java @@ -89,5 +89,10 @@ public String[] getCommandAliases() { String[] aliases = {"become", "pretend"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/InspiroCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/InspiroCommand.java index 8c8571aa..8e06a841 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/InspiroCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/InspiroCommand.java @@ -93,5 +93,10 @@ public String[] getCommandAliases() { String[] aliases = {"inspire", "inspirobot", "ib"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/LmgtfyCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/LmgtfyCommand.java index c330ca0d..2377f594 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/LmgtfyCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/LmgtfyCommand.java @@ -50,7 +50,12 @@ public boolean requiresArguments() { @Override public String[] getCommandAliases() { - String[] aliases = {"google"}; + String[] aliases = {"letmegetthat", "letmegoogle"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/MemeCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/MemeCommand.java index a10d5f56..077b5e2f 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/MemeCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/MemeCommand.java @@ -310,4 +310,9 @@ public String[] getCommandAliases() { String[] aliases = {"mememaker", "makememe"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/PPCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/PPCommand.java index a5a698fe..1d3f1690 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/PPCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/PPCommand.java @@ -94,5 +94,10 @@ public String[] getCommandAliases() { String[] aliases = {"ppsize"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/RedditCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/RedditCommand.java index a6b23915..daf28086 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/RedditCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/RedditCommand.java @@ -153,5 +153,10 @@ public String[] getCommandAliases() { String[] aliases = {"subreddit","sub"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/ShipCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/ShipCommand.java index 0425a388..feda2fd4 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/ShipCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/ShipCommand.java @@ -95,5 +95,10 @@ public String[] getCommandAliases() { String[] aliases = {"stan"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/SpinCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/SpinCommand.java index 9e356e5d..caa5b948 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/SpinCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/SpinCommand.java @@ -114,5 +114,10 @@ public String[] getCommandAliases() { String[] aliases = {"spinner", "speen"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/fun/VoteCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/VoteCommand.java index bdac0b6c..1a86f158 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/VoteCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/VoteCommand.java @@ -52,5 +52,10 @@ public String[] getCommandAliases() { String[] aliases = {"poll"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/fun/WouldYouRatherCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/WouldYouRatherCommand.java index 99b067a2..68d82808 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/WouldYouRatherCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/WouldYouRatherCommand.java @@ -70,5 +70,10 @@ public String[] getCommandAliases() { String[] aliases = {"wouldyourather"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/fun/XKCDCommand.java b/src/main/java/de/voidtech/gerald/commands/fun/XKCDCommand.java index 2f44c35c..330a59af 100644 --- a/src/main/java/de/voidtech/gerald/commands/fun/XKCDCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/fun/XKCDCommand.java @@ -38,7 +38,7 @@ public class XKCDCommand extends AbstractCommand { private static final String XKCD_URL = "https://xkcd.com/"; private static final String SUFFIX = "info.0.json"; - private static final String EMOTE_UNICODE = "U+1F440"; + private static final String EMOTE_UNICODE = "U+1f440"; private String makeRequest(String URL) { try { @@ -169,4 +169,9 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/info/CacheSearchCommand.java b/src/main/java/de/voidtech/gerald/commands/info/CacheSearchCommand.java index 18dad7db..80ffa5f8 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/CacheSearchCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/CacheSearchCommand.java @@ -120,5 +120,10 @@ public String[] getCommandAliases() { String[] aliases = {"cache", "csearch"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/CheatCommand.java b/src/main/java/de/voidtech/gerald/commands/info/CheatCommand.java index 91ebab0f..efcafeeb 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/CheatCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/CheatCommand.java @@ -127,5 +127,10 @@ public String[] getCommandAliases() { String[] aliases = {"cheatsheet", "cs"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/info/HelpCommand.java b/src/main/java/de/voidtech/gerald/commands/info/HelpCommand.java index 6341bcb2..6dacfaed 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/HelpCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/HelpCommand.java @@ -196,5 +196,10 @@ public String[] getCommandAliases() { String[] aliases = {"commands", "h"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return false; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/info/HttpCommand.java b/src/main/java/de/voidtech/gerald/commands/info/HttpCommand.java index 0fce9a24..3cd4dfdb 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/HttpCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/HttpCommand.java @@ -85,5 +85,10 @@ public String[] getCommandAliases() { String[] aliases = {"httpcat", "httpcode"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/InfoCommand.java b/src/main/java/de/voidtech/gerald/commands/info/InfoCommand.java index 33ca4bb7..983ec1c8 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/InfoCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/InfoCommand.java @@ -119,5 +119,10 @@ public String[] getCommandAliases() { String[] aliases = {"botinfo", "botstats", "bi", "bs", "stats"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/InviteCommand.java b/src/main/java/de/voidtech/gerald/commands/info/InviteCommand.java index 546c941b..4e694cb4 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/InviteCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/InviteCommand.java @@ -58,5 +58,10 @@ public String[] getCommandAliases() { String[] aliases = {"inv", "link"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/PermissionsCommand.java b/src/main/java/de/voidtech/gerald/commands/info/PermissionsCommand.java new file mode 100644 index 00000000..0ae6de77 --- /dev/null +++ b/src/main/java/de/voidtech/gerald/commands/info/PermissionsCommand.java @@ -0,0 +1,94 @@ +package main.java.de.voidtech.gerald.commands.info; + +import java.awt.Color; +import java.util.EnumSet; +import java.util.List; + +import main.java.de.voidtech.gerald.annotations.Command; +import main.java.de.voidtech.gerald.commands.AbstractCommand; +import main.java.de.voidtech.gerald.commands.CommandCategory; +import main.java.de.voidtech.gerald.util.ParsingUtils; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.GuildChannel; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageEmbed; + +@Command +public class PermissionsCommand extends AbstractCommand{ + + @Override + public void executeInternal(Message message, List args) { + EnumSet perms; + String member = ""; + if (args.size() > 0) { + if (args.get(0).equals("everyone")) { + perms = message.getGuild().getPublicRole().getPermissions(); + member = "Everyone"; + } else { + perms = ParsingUtils.getMember(message, args).getPermissions((GuildChannel) message.getChannel()); + member = ParsingUtils.getMember(message, args).getUser().getAsTag(); + } + } else { + perms = ParsingUtils.getMember(message, args).getPermissions((GuildChannel) message.getChannel()); + member = ParsingUtils.getMember(message, args).getUser().getAsTag(); + } + + message.getChannel().sendMessage(buildPermsEmbed(perms, member)).queue(); + } + + private MessageEmbed buildPermsEmbed(EnumSet perms, String member) { + String permsList = ""; + for (Permission perm : perms) { + permsList += perm.getName() + "\n"; + } + return new EmbedBuilder() + .setColor(Color.ORANGE) + .setTitle("Permissions for " + member) + .setDescription("```\n" + permsList + "\n```") + .build(); + + } + + @Override + public String getDescription() { + return "For server debugging and more, allows you to check someone's (or your own) permissions in a server."; + } + + @Override + public String getUsage() { + return "permissions [@member#1234/ID/everyone]"; + } + + @Override + public String getName() { + return "permissions"; + } + + @Override + public CommandCategory getCommandCategory() { + return CommandCategory.INFO; + } + + @Override + public boolean isDMCapable() { + return false; + } + + @Override + public boolean requiresArguments() { + return false; + } + + @Override + public String[] getCommandAliases() { + String[] aliases = {"perms", "permsin"}; + return aliases; + } + + @Override + public boolean canBeDisabled() { + return true; + } + +} diff --git a/src/main/java/de/voidtech/gerald/commands/info/PingCommand.java b/src/main/java/de/voidtech/gerald/commands/info/PingCommand.java index 06fe3e2b..5e42da4b 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/PingCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/PingCommand.java @@ -69,5 +69,10 @@ public String[] getCommandAliases() { String[] aliases = {"pong"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/ServerInfoCommand.java b/src/main/java/de/voidtech/gerald/commands/info/ServerInfoCommand.java index 693261a7..50b27cef 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/ServerInfoCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/ServerInfoCommand.java @@ -74,5 +74,10 @@ public String[] getCommandAliases() { String[] aliases = {"si", "server"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/info/TwitchCommand.java b/src/main/java/de/voidtech/gerald/commands/info/TwitchCommand.java new file mode 100644 index 00000000..1749d72b --- /dev/null +++ b/src/main/java/de/voidtech/gerald/commands/info/TwitchCommand.java @@ -0,0 +1,201 @@ +package main.java.de.voidtech.gerald.commands.info; + +import java.awt.Color; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.jagrosh.jdautilities.commons.waiter.EventWaiter; + +import main.java.de.voidtech.gerald.annotations.Command; +import main.java.de.voidtech.gerald.commands.AbstractCommand; +import main.java.de.voidtech.gerald.commands.CommandCategory; +import main.java.de.voidtech.gerald.entities.TwitchNotificationChannel; +import main.java.de.voidtech.gerald.service.ServerService; +import main.java.de.voidtech.gerald.service.TwitchNotificationService; +import main.java.de.voidtech.gerald.util.ParsingUtils; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; + +@Command +public class TwitchCommand extends AbstractCommand{ + + @Autowired + private EventWaiter waiter; + + @Autowired + private TwitchNotificationService twitchService; + + @Autowired + private ServerService serverService; + + private static final String TWITCH_BASE_URL = "https://twitch.tv/"; + private static final String TWITCH_URL_MATCHER = "https:\\/\\/(www\\.)?twitch.tv\\/.*"; + + private boolean validTwitchUrl(String streamerUrl) { + return streamerUrl.matches(TWITCH_URL_MATCHER) && Arrays.asList(streamerUrl.split("/")).size() == 4; + } + + private boolean validChannelId(String channelId, Message message) { + return ParsingUtils.isSnowflake(channelId) && message.getGuild().getTextChannelById(channelId) != null; + } + + private void removeStreamer(Message message, List args) { + if (args.size() == 1) + message.getChannel().sendMessage("**You need to specify a streamer to unsubscribe from!**").queue(); + else { + if (!twitchService.subscriptionExists(args.get(1), serverService.getServer(message.getGuild().getId()).getId())) + message.getChannel().sendMessage("**A subscription to that streamer does not exist!**").queue(); + else { + twitchService.removeChannelSubscription(args.get(1), serverService.getServer(message.getGuild().getId()).getId()); + message.getChannel().sendMessage("**Subscription has been removed**").queue(); + } + } + } + + private void listStreamers(Message message) { + List subscriptions = twitchService.getAllSubscriptionsForServer(serverService.getServer(message.getGuild().getId()).getId()); + String messageBody = ""; + if (subscriptions.size() == 0) + messageBody = "None to show!"; + else { + for (TwitchNotificationChannel subscription : subscriptions) { + messageBody += "**Streamer** - " + formatTwitchUrlMarkdown(subscription.getStreamerName()) + "\n**Channel** - <#" + subscription.getChannelId() + ">\n**Message** - " + subscription.getNotificationMessage() + "\n\n"; + } + } + message.getChannel().sendMessage(buildTwitchSubscriptionEmbed(messageBody)).queue(); + } + + private String formatTwitchUrlMarkdown(String name) { + return "[" + name + "](" + TWITCH_BASE_URL + name + ")"; + } + + private MessageEmbed buildTwitchSubscriptionEmbed(String messageBody) { + MessageEmbed subscriptionEmbed = new EmbedBuilder() + .setColor(Color.ORANGE) + .setTitle("Twitch Subscriptions for this server") + .setDescription(messageBody) + .build(); + return subscriptionEmbed; + } + + private void addStreamer(Message message) { + if (message.getMember().hasPermission(Permission.MANAGE_CHANNEL)) { + streamerSetupGetStreamer(message); + } + } + + private void streamerSetupGetStreamer(Message message) { + message.getChannel().sendMessage("**Please enter the twitch URL of the streamer you wish to subscribe to:**").queue(); + + waiter.waitForEvent(MessageReceivedEvent.class, + event -> ((MessageReceivedEvent) event).getAuthor().getId().equals(message.getAuthor().getId()), + event -> { + String streamerUrl = event.getMessage().getContentRaw().toLowerCase(); + if (validTwitchUrl(streamerUrl)) { + String streamerName = Arrays.asList(streamerUrl.split("/")).get(3); + if (twitchService.subscriptionExists(streamerName, serverService.getServer(message.getGuild().getId()).getId())) + message.getChannel().sendMessage("**A subscription to that streamer already exists!**").queue(); + else + streamerSetupGetChannel(message, streamerName); + } else + message.getChannel().sendMessage("**You did not enter a valid twitch.tv url! Please check your URL and start setup again**").queue(); + + }, 30, TimeUnit.SECONDS, + () -> message.getChannel().sendMessage(String.format("Request timed out.")).queue()); + } + + private void streamerSetupGetChannel(Message message, String streamerName) { + message.getChannel().sendMessage("**Please enter the channel you wish to get notifications sent to (use a channel mention or ID):**").queue(); + waiter.waitForEvent(MessageReceivedEvent.class, + event -> ((MessageReceivedEvent) event).getAuthor().getId().equals(message.getAuthor().getId()), + event -> { + String channelId = ParsingUtils.filterSnowflake(event.getMessage().getContentRaw().toLowerCase()); + if (validChannelId(channelId, message)) { + streamerSetupGetMessage(message, streamerName, channelId); + } else { + message.getChannel().sendMessage("**You did not enter a valid channel! Please check the mention was correct and the channel is in this server!**").queue(); + } + + }, 30, TimeUnit.SECONDS, + () -> message.getChannel().sendMessage(String.format("Request timed out.")).queue()); + } + + private void streamerSetupGetMessage(Message message, String streamerName, String channelId) { + message.getChannel().sendMessage("**Please enter your custom notification message:**").queue(); + waiter.waitForEvent(MessageReceivedEvent.class, + event -> ((MessageReceivedEvent) event).getAuthor().getId().equals(message.getAuthor().getId()), + event -> { + String notificationMessage = event.getMessage().getContentRaw(); + streamerSetupFinishSetup(message, streamerName, channelId, notificationMessage); + }, 30, TimeUnit.SECONDS, + () -> message.getChannel().sendMessage(String.format("Request timed out.")).queue()); + } + + private void streamerSetupFinishSetup(Message message, String streamerName, String channelId, String notificationMessage) { + message.getChannel().sendMessage("**Setup completed!**\n\nStreamer Url: " + TWITCH_BASE_URL + streamerName + "\nChannel: <#" + channelId + ">\nNotification Message: " + notificationMessage).queue(); + twitchService.addSubscription(streamerName, channelId, notificationMessage, serverService.getServer(message.getGuild().getId()).getId()); + } + + @Override + public void executeInternal(Message message, List args) { + switch (args.get(0)) { + case "add": + addStreamer(message); + break; + case "remove": + removeStreamer(message, args); + break; + case "list": + listStreamers(message); + } + } + + @Override + public String getDescription() { + return "This system allows you to see when twitch streamers go live. Use the add command to add a streamer's notifications. You may choose a notification channel and a unique message for each streamer!"; + } + + @Override + public String getUsage() { + return "twitch add [then follow the instructions on screen]\n" + + "twitch remove [streamer name]\n" + + "twitch list"; + } + + @Override + public String getName() { + return "twitch"; + } + + @Override + public CommandCategory getCommandCategory() { + return CommandCategory.INFO; + } + + @Override + public boolean isDMCapable() { + return false; + } + + @Override + public boolean requiresArguments() { + return true; + } + + @Override + public String[] getCommandAliases() { + String[] aliases = {"tn"}; + return aliases; + } + + @Override + public boolean canBeDisabled() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/info/WhoisCommand.java b/src/main/java/de/voidtech/gerald/commands/info/WhoisCommand.java index 63b8878e..dccd425d 100644 --- a/src/main/java/de/voidtech/gerald/commands/info/WhoisCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/info/WhoisCommand.java @@ -79,4 +79,9 @@ public String[] getCommandAliases() { String[] aliases = {"user", "userinfo", "ui"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/management/DisableCommand.java b/src/main/java/de/voidtech/gerald/commands/management/DisableCommand.java index 3a841a00..949a9fd0 100644 --- a/src/main/java/de/voidtech/gerald/commands/management/DisableCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/management/DisableCommand.java @@ -1,5 +1,6 @@ package main.java.de.voidtech.gerald.commands.management; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -9,6 +10,7 @@ import main.java.de.voidtech.gerald.commands.AbstractCommand; import main.java.de.voidtech.gerald.commands.CommandCategory; import main.java.de.voidtech.gerald.entities.Server; +import main.java.de.voidtech.gerald.routines.AbstractRoutine; import main.java.de.voidtech.gerald.service.ServerService; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Message; @@ -19,50 +21,108 @@ public class DisableCommand extends AbstractCommand { @Autowired private List commands; + @Autowired + private List routines; + @Autowired private ServerService serverService; @Override public void executeInternal(Message message, List args) { - if (args.size() > 0 && message.getMember().hasPermission(Permission.MANAGE_SERVER)) { - String commandName = args.get(0); - if (commandName.matches("enable|disable")) - message.getChannel().sendMessage("You cannot disable this command.").queue(); + + if (!commands.contains(this)) commands.add(this); + + if (message.getMember().hasPermission(Permission.MANAGE_SERVER)) { + String targetName = args.get(0).toLowerCase(); + if (targetName.equals("all")) disableAllCommands(message); + else if (targetName.startsWith("r-")) disableRoutine(targetName, message); + else disableCommand(targetName, message); + } + } + + private void disableCommand(String targetName, Message message) { + AbstractCommand foundCommand = null; + String resultMessage = ""; + for (AbstractCommand command : commands) { + if (command.getName().equals(targetName) || Arrays.asList(command.getCommandAliases()).contains(targetName)) { + foundCommand = command; + break; + } + } + if (foundCommand == null) + resultMessage = "**No command was found with name `" + targetName + "`**"; + else if (!foundCommand.canBeDisabled()) + resultMessage = "**The command `"+ targetName + "` cannot be disabled/enabled!**"; + else { + + Server server = serverService.getServer(message.getGuild().getId()); + if (server.getCommandBlacklist().contains(targetName)) { + resultMessage = "**This command is already disabled!**"; + } else { + server.addToCommandBlacklist(targetName); + serverService.saveServer(server); + resultMessage = "**Command `" + targetName + "` has been disabled!**"; + } + } + message.getChannel().sendMessage(resultMessage).queue(); + } + + private void disableRoutine(String targetName, Message message) { + AbstractRoutine foundRoutine = null; + String resultMessage = ""; + for (AbstractRoutine routine: routines) { + if (routine.getName().equals(targetName)) { + foundRoutine = routine; + break; + } + } + + if (foundRoutine == null) + resultMessage = "**No Routine was found with name `" + targetName + "`**"; + else if (!foundRoutine.canBeDisabled()) + resultMessage = "**Routine `"+ targetName + "` cannot be disabled/enabled!**"; + else { + + Server server = serverService.getServer(message.getGuild().getId()); + if (server.getRoutineBlacklist().contains(targetName)) + resultMessage = "**This routine is already disabled!**"; else { - AbstractCommand foundCommand = null; - - for (AbstractCommand command : commands) { - if (command.getName().equals(commandName) || Arrays.asList(command.getCommandAliases()).contains(commandName)) { - foundCommand = command; - commandName = command.getName(); - break; - } - } - - if (foundCommand == null) - message.getChannel().sendMessage("No command was found with name `" + commandName + "`").queue(); - else { - Server server = serverService.getServer(message.getGuild().getId()); - if (server.getCommandBlacklist().contains(commandName)) { - message.getChannel().sendMessage("This command is already disabled!").queue(); - } else { - server.addToCommandBlacklist(commandName); - serverService.saveServer(server); - message.getChannel().sendMessage("Command has been disabled: " + commandName).queue(); - } - } + server.addToRoutineBlacklist(targetName); + serverService.saveServer(server); + resultMessage = "**Routine `" + targetName + "`has been disabled!**"; } } + message.getChannel().sendMessage(resultMessage).queue(); + } + + private void disableAllCommands(Message message) { + Server server = serverService.getServer(message.getGuild().getId()); + List enabledCommands = new ArrayList(); + for (AbstractCommand command : commands) { + if (command.canBeDisabled() && !server.getCommandBlacklist().contains(command.getName())) + server.addToCommandBlacklist(command.getName()); + else if (!command.canBeDisabled()) enabledCommands.add(command); + } + serverService.saveServer(server); + message.getChannel().sendMessage("**All commands have been disabled except for these:**\n```" + createEnabledCommandString(enabledCommands) + "```").queue(); + } + + private String createEnabledCommandString(List enabledCommands) { + String message = ""; + for (AbstractCommand command : enabledCommands) + message += command.getName() + "\n"; + return message; } @Override public String getDescription() { - return "disabled a command"; + return "Allows you to disable a command or routine! Note: Some routines or commands cannot be disabled. Routine names always use the format r-[name]"; } @Override public String getUsage() { - return "disable ping"; + return "disable r-nitrolite\n" + + "disable ping"; } @Override @@ -87,8 +147,13 @@ public boolean requiresArguments() { @Override public String[] getCommandAliases() { - String[] aliases = {"block"}; + String[] aliases = {"lock"}; return aliases; } + @Override + public boolean canBeDisabled() { + return false; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/management/EnableCommand.java b/src/main/java/de/voidtech/gerald/commands/management/EnableCommand.java index 02751191..7105610e 100644 --- a/src/main/java/de/voidtech/gerald/commands/management/EnableCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/management/EnableCommand.java @@ -9,6 +9,7 @@ import main.java.de.voidtech.gerald.commands.AbstractCommand; import main.java.de.voidtech.gerald.commands.CommandCategory; import main.java.de.voidtech.gerald.entities.Server; +import main.java.de.voidtech.gerald.routines.AbstractRoutine; import main.java.de.voidtech.gerald.service.ServerService; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Message; @@ -18,51 +19,100 @@ public class EnableCommand extends AbstractCommand { @Autowired private List commands; + + @Autowired + private List routines; @Autowired private ServerService serverService; @Override public void executeInternal(Message message, List args) { - if (args.size() > 0 && message.getMember().hasPermission(Permission.MANAGE_SERVER)) { - String commandName = args.get(0); - if (commandName.matches("enable|disable")) - message.getChannel().sendMessage("This command is not disabled.").queue(); - else { - AbstractCommand foundCommand = null; - - for (AbstractCommand command : commands) { - if (command.getName().equals(commandName) || Arrays.asList(command.getCommandAliases()).contains(commandName)) { - foundCommand = command; - commandName = command.getName(); - break; - } - } + if (!commands.contains(this)) commands.add(this); + + if (message.getMember().hasPermission(Permission.MANAGE_SERVER)) { + String targetName = args.get(0).toLowerCase(); + if (targetName.equals("all")) enableAllCommands(message); + else if (targetName.startsWith("r-")) enableRoutine(targetName, message); + else enableCommand(targetName, message); + } + } + + private void enableCommand(String targetName, Message message) { + AbstractCommand foundCommand = null; + String resultMessage = ""; + for (AbstractCommand command : commands) { + if (command.getName().equals(targetName) || Arrays.asList(command.getCommandAliases()).contains(targetName)) { + foundCommand = command; + targetName = command.getName(); + break; + } + } + if (foundCommand == null) + resultMessage = "**No command was found with name `" + targetName + "`**"; + else if (!foundCommand.canBeDisabled()) message.getChannel().sendMessage("**The command `"+ targetName + "` cannot be enabled/disabled!**").queue(); + else { + Server server = serverService.getServer(message.getGuild().getId()); + if (!server.getCommandBlacklist().contains(targetName)) { + resultMessage = "**This command is not disabled!**"; + } else { + server.removeFromCommandBlacklist(targetName); + serverService.saveServer(server); + resultMessage = "**Command `" + targetName + "` has been enabled!**"; + } + } + message.getChannel().sendMessage(resultMessage).queue(); + } - if (foundCommand == null) - message.getChannel().sendMessage("No command was found with name `" + commandName + "`").queue(); - else { - Server server = serverService.getServer(message.getGuild().getId()); - if (!server.getCommandBlacklist().contains(commandName)) { - message.getChannel().sendMessage("This command is not disabled!").queue(); - } else { - server.removeFromCommandBlacklist(commandName); - serverService.saveServer(server); - message.getChannel().sendMessage("Command has been enabled: " + commandName).queue(); - } - } + private void enableRoutine(String targetName, Message message) { + AbstractRoutine foundRoutine = null; + String resultMessage = ""; + for (AbstractRoutine routine: routines) { + if (routine.getName().equals(targetName)) { + foundRoutine = routine; + break; + } + } + if (foundRoutine == null) + resultMessage = "**No Routine was found with name `" + targetName + "`**"; + else if (!foundRoutine.canBeDisabled()) + resultMessage = "**Routine `"+ targetName + "` cannot be enabled/disabled!**"; + else { + + Server server = serverService.getServer(message.getGuild().getId()); + if (!server.getRoutineBlacklist().contains(targetName)) + resultMessage = "**This routine is not enabled!**"; + else { + server.removeFromRoutineBlacklist(targetName); + serverService.saveServer(server); + resultMessage = "**Routine `" + targetName + "`has been enabled!**"; } } + message.getChannel().sendMessage(resultMessage).queue(); + } + + private void enableAllCommands(Message message) { + Server server = serverService.getServer(message.getGuild().getId()); + String resultMessage = ""; + if (server.getCommandBlacklist().isEmpty()) + resultMessage = "**There are no disabled commands!**"; + else { + server.clearCommandBlacklist(); + serverService.saveServer(server); + resultMessage = "**All commands have been enabled!**"; + } + message.getChannel().sendMessage(resultMessage).queue(); } @Override public String getDescription() { - return "enables a command"; + return "Allows you to enable a command or routine! Note: Some routines or commands cannot be disabled. Routine names always use the format r-[name]"; } @Override public String getUsage() { - return "enable ping"; + return "enable r-nitrolite\n" + + "enable ping"; } @Override @@ -87,8 +137,13 @@ public boolean requiresArguments() { @Override public String[] getCommandAliases() { - String[] aliases = {"unblock"}; + String[] aliases = {"unlock"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return false; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/management/PrefixCommand.java b/src/main/java/de/voidtech/gerald/commands/management/PrefixCommand.java index 35e2144e..04c45f6e 100644 --- a/src/main/java/de/voidtech/gerald/commands/management/PrefixCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/management/PrefixCommand.java @@ -80,5 +80,10 @@ public String[] getCommandAliases() { String[] aliases = {"setprefix"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return false; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/management/RoutineCommand.java b/src/main/java/de/voidtech/gerald/commands/management/RoutineCommand.java new file mode 100644 index 00000000..8f490c1e --- /dev/null +++ b/src/main/java/de/voidtech/gerald/commands/management/RoutineCommand.java @@ -0,0 +1,86 @@ +package main.java.de.voidtech.gerald.commands.management; + +import java.awt.Color; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +import main.java.de.voidtech.gerald.annotations.Command; +import main.java.de.voidtech.gerald.commands.AbstractCommand; +import main.java.de.voidtech.gerald.commands.CommandCategory; +import main.java.de.voidtech.gerald.entities.Server; +import main.java.de.voidtech.gerald.routines.AbstractRoutine; +import main.java.de.voidtech.gerald.service.ServerService; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Message; + +@Command +public class RoutineCommand extends AbstractCommand { + + @Autowired + private List routines; + + @Autowired + private ServerService serverService; + + @Override + public void executeInternal(Message message, List args) { + long routineCount = routines.size(); + Server server = serverService.getServer(message.getGuild().getId()); + + EmbedBuilder routineInformation = new EmbedBuilder() + .setColor(Color.ORANGE) + .setTitle("Barista Gerald - Routines") + .setThumbnail(message.getJDA().getSelfUser().getAvatarUrl()) + .setFooter("Routine Count: "+ routineCount + " | Note: Some routines cannot be disabled. The commands they power require them to function. Try disabling the command instead!"); + for (AbstractRoutine routine: routines) { + routineInformation.addField(routine.getName(), String.format("Description: %s\nCan be disabled: %s\nIs disabled Here: %s", + routine.getDescription(), + routine.canBeDisabled() ? ":white_check_mark:" : ":x:", + server.getRoutineBlacklist().contains(routine.getName()) ? ":white_check_mark:" : ":x:"), + false); + } + message.getChannel().sendMessage(routineInformation.build()).queue(); + } + + @Override + public String getDescription() { + return "List all routines"; + } + + @Override + public String getUsage() { + return "routine"; + } + + @Override + public String getName() { + return "routine"; + } + + @Override + public CommandCategory getCommandCategory() { + return CommandCategory.MANAGEMENT; + } + + @Override + public boolean isDMCapable() { + return false; + } + + @Override + public boolean requiresArguments() { + return false; + } + + @Override + public String[] getCommandAliases() { + String[] aliases = {"routines", "r"}; + return aliases; + } + + @Override + public boolean canBeDisabled() { + return false; + } +} diff --git a/src/main/java/de/voidtech/gerald/commands/management/SayCommand.java b/src/main/java/de/voidtech/gerald/commands/management/SayCommand.java index ee20f98b..eadd0df6 100644 --- a/src/main/java/de/voidtech/gerald/commands/management/SayCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/management/SayCommand.java @@ -57,5 +57,10 @@ public String[] getCommandAliases() { String[] aliases = {"speak", "blessuswiththevoiceofgerald"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/management/WhitelistCommand.java b/src/main/java/de/voidtech/gerald/commands/management/WhitelistCommand.java index 8a297485..3f1b7eb3 100644 --- a/src/main/java/de/voidtech/gerald/commands/management/WhitelistCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/management/WhitelistCommand.java @@ -137,5 +137,10 @@ public String[] getCommandAliases() { String[] aliases = {"allowlist", "allowedchannels", "allow"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return false; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/ActivityCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/ActivityCommand.java index 4aea10fe..ade32b87 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/ActivityCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/ActivityCommand.java @@ -143,5 +143,10 @@ public String[] getCommandAliases() { String[] aliases = {"setactivity", "status", "setstatus"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/AvatarCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/AvatarCommand.java index 70ddb9ec..c2f57a1b 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/AvatarCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/AvatarCommand.java @@ -64,4 +64,9 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/CompileCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/CompileCommand.java index 565061c7..8771ef44 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/CompileCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/CompileCommand.java @@ -210,4 +210,9 @@ public String[] getCommandAliases() { return aliases; } + @Override + public boolean canBeDisabled() { + return true; + } + } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/EnlargeCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/EnlargeCommand.java index 88cf2ee5..bb0cc51d 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/EnlargeCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/EnlargeCommand.java @@ -91,4 +91,9 @@ public String[] getCommandAliases() { String[] aliases = {"jumbo"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/utils/GoogleCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/GoogleCommand.java new file mode 100644 index 00000000..3614a97f --- /dev/null +++ b/src/main/java/de/voidtech/gerald/commands/utils/GoogleCommand.java @@ -0,0 +1,216 @@ +package main.java.de.voidtech.gerald.commands.utils; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.jagrosh.jdautilities.commons.waiter.EventWaiter; +import com.microsoft.playwright.Browser; +import com.microsoft.playwright.Browser.NewContextOptions; +import com.microsoft.playwright.BrowserContext; +import com.microsoft.playwright.Page; +import com.microsoft.playwright.Playwright; + +//import main.java.de.voidtech.gerald.annotations.Command; +import main.java.de.voidtech.gerald.commands.AbstractCommand; +import main.java.de.voidtech.gerald.commands.CommandCategory; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.ChannelType; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageChannel; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; + +//Command +public class GoogleCommand extends AbstractCommand { + + private static final String BROWSER_LOGO_IMAGE = "https://e7.pngegg.com/pngimages/293/824/png-clipart-ecosia-computer-icons-web-browser-android-illegal-logging-globe-logo-thumbnail.png"; + private static final String RED_CROSS_UNICODE = "U+274c"; + + private static final String BROWSER_BASE_URL = "https://www.ecosia.org/"; + private static final String BROWSER_SEARCH_URL = "search?q="; + private static final String BROWSER_NEWS_URL = "news?q="; + private static final String BROWSER_IMAGES_URL = "images?q="; + private static final String BROWSER_VIDEOS_URL = "videos?q="; + private static final String SAFE_SEARCH_SUFFIX = "&sfs=true"; + + private static final Logger LOGGER = Logger.getLogger(GoogleCommand.class.getName()); + + private BrowserContext browser = null; + + @Autowired + private EventWaiter waiter; + + private NewContextOptions getContextOptions() { + return new Browser.NewContextOptions() + .setViewportSize(1000, 1000); + } + + GoogleCommand() { + LOGGER.log(Level.INFO, "Firefox is being initialised"); + Browser browserInstance = Playwright.create().firefox().launch(); + this.browser = browserInstance.newContext(getContextOptions()); + LOGGER.log(Level.INFO, "Firefox is ready!"); + } + + private String removeFirstListItem(List originalList) { + if (originalList.size() == 1) { + return ""; + } else { + List modifiedList = new ArrayList(); + for (int i = 1; i < originalList.size(); i++) { + modifiedList.add(originalList.get(i)); + } + return String.join("+", modifiedList); + } + } + + private String constructSearchURL(List args, boolean nsfwAllowed) { + String urlBuffer = BROWSER_BASE_URL; + String queryString = String.join("+", args); + + if (args.get(0).startsWith("-")) { + String flag = args.get(0).substring(1); + queryString = String.join("+", removeFirstListItem(args)); + switch (flag) { + case "i": + urlBuffer += BROWSER_IMAGES_URL; + break; + case "n": + urlBuffer += BROWSER_NEWS_URL; + break; + case "v": + urlBuffer += BROWSER_VIDEOS_URL; + break; + default: + urlBuffer += BROWSER_SEARCH_URL; + break; + } + } else + urlBuffer += BROWSER_SEARCH_URL; + if (queryString == "") + return null; + else { + urlBuffer += queryString; + if (!nsfwAllowed) + urlBuffer += SAFE_SEARCH_SUFFIX; + return urlBuffer; + } + } + + private boolean getNsfwMode(MessageChannel messageChannel) + { + return messageChannel.getType().equals(ChannelType.PRIVATE) ? true : ((TextChannel)messageChannel).isNSFW(); + } + + private void sendDeleteButtonWithListener(Message sentMessage, Message originMessage) { + sentMessage.addReaction(RED_CROSS_UNICODE).queue(); + waiter.waitForEvent(MessageReactionAddEvent.class, + event -> deleteEventAuthorised(((MessageReactionAddEvent) event), originMessage), + event -> { + boolean deleteButtonPressed = event.getReactionEmote().toString().equals("RE:" + RED_CROSS_UNICODE); + if (deleteButtonPressed) { + sentMessage.delete().queue(); + } + }, 60, TimeUnit.SECONDS, () -> {}); + } + + private void sendFinalMessage(Message message, String url, byte[] screenshotBytesBuffer) { + message.getChannel().sendMessage(constructResultEmbed(url, getNsfwMode(message.getChannel()))) + .addFile(screenshotBytesBuffer, "screenshot.png") + .queue(sentMessage -> { + if (!message.getChannelType().equals(ChannelType.PRIVATE)) { + sendDeleteButtonWithListener(sentMessage, message); + } + }); + } + + private boolean deleteEventAuthorised(MessageReactionAddEvent event, Message message) { + return !event.getMember().getId().equals(event.getJDA().getSelfUser().getId()) && + ( + event.getUser().getId().equals(message.getAuthor().getId()) || + event.getMember().hasPermission(Permission.MESSAGE_MANAGE) + ); + } + + private MessageEmbed constructResultEmbed(String url, boolean safeSearchMode) { + MessageEmbed googleEmbed = new EmbedBuilder() + .setColor(Color.ORANGE) + .setTitle("**Your Search Result:**", url) + .setImage("attachment://screenshot.png") + .setFooter("Powered By Ecosia | Safe mode " + (safeSearchMode ? "disabled" : "enabled"), BROWSER_LOGO_IMAGE) + .build(); + return googleEmbed; + } + + @Override + public void executeInternal(Message message, List args) { + String url = constructSearchURL(args, getNsfwMode(message.getChannel())); + + if (url == null) + message.getChannel().sendMessage("**You did not provide something to search for!**").queue(); + else { + message.getChannel().sendTyping().queue(); + Page searchPage = this.browser.newPage(); + searchPage.navigate(url); + searchPage.setViewportSize(1000, 1000); + + byte[] screenshotBytesBuffer = searchPage.screenshot(); + searchPage.close(); + + sendFinalMessage(message, url, screenshotBytesBuffer); + } + } + + @Override + public String getDescription() { + return "Allows you to search the mighty interwebs for something of interest"; + } + + @Override + public String getUsage() { + return "google [a thing you want to see]\n" + + "google -i [an image you want to see]\n" + + "google -n [a thing you want to know about]\n" + + "google -v [a thing you want to watch]\n" + + "use the flag -i for images, -v for videos and -n for news"; + } + + @Override + public String getName() { + return "google"; + } + + @Override + public CommandCategory getCommandCategory() { + return CommandCategory.UTILS; + } + + @Override + public boolean isDMCapable() { + return true; + } + + @Override + public boolean requiresArguments() { + return true; + } + + @Override + public String[] getCommandAliases() { + String[] aliases = {"search", "ecosia"}; + return aliases; + } + + @Override + public boolean canBeDisabled() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/commands/utils/HexCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/HexCommand.java index 78e38850..582b6de0 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/HexCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/HexCommand.java @@ -1,13 +1,18 @@ package main.java.de.voidtech.gerald.commands.utils; import java.awt.Color; +import java.io.IOException; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import main.java.de.voidtech.gerald.annotations.Command; import main.java.de.voidtech.gerald.commands.AbstractCommand; import main.java.de.voidtech.gerald.commands.CommandCategory; +import main.java.de.voidtech.gerald.util.ParsingUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; @@ -15,13 +20,9 @@ @Command public class HexCommand extends AbstractCommand { - private static final Pattern HEX_PATTERN = Pattern.compile("^([a-fA-F0-9]{6})$"); private static final String IMAGE_SOURCE_URL = "https://via.placeholder.com/250/"; - - private boolean isValidHex(String input) { - Matcher hexMatcher = HEX_PATTERN.matcher(input); - return hexMatcher.find(); - } + private static final String COLOUR_HEXA_BASE_URL = "https://www.colorhexa.com/"; + private static final Logger LOGGER = Logger.getLogger(HexCommand.class.getName()); private Color getEmbedColour(String hex) { return new Color( @@ -32,19 +33,34 @@ private Color getEmbedColour(String hex) { private void sendHexImage(Message message, String hexCode) { String finalImageURL = IMAGE_SOURCE_URL + hexCode + "/" + hexCode + ".png"; + String colourHexaURL = COLOUR_HEXA_BASE_URL + hexCode; + String colourName = getColourName(colourHexaURL); + MessageEmbed hexColourEmbed = new EmbedBuilder() .setColor(getEmbedColour(hexCode)) .setImage(finalImageURL) - .setTitle(hexCode.toUpperCase(), finalImageURL) + .setTitle("#" + hexCode.toUpperCase(), colourHexaURL) + .setFooter(colourName) .build(); message.getChannel().sendMessage(hexColourEmbed).queue(); } + private String getColourName(String colourHexaURL) { + try { + Document colourHexaPage = Jsoup.connect(colourHexaURL).get(); + return colourHexaPage.select("#information > div.color-description > p > strong").first().text(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error during CommandExecution: " + e.getMessage()); + e.printStackTrace(); + } + return ""; + } + @Override public void executeInternal(Message message, List args) { String hexCode = args.get(0).replaceAll("#", ""); - if (isValidHex(hexCode)) { + if (ParsingUtils.isHexadecimal(hexCode)) { sendHexImage(message, hexCode); } else { message.getChannel().sendMessage("**You did not supply a valid hex code!**").queue(); @@ -87,5 +103,10 @@ public String[] getCommandAliases() { String[] aliases = {"hexcolor", "colour", "hexcolour", "color"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/NitroliteCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/NitroliteCommand.java index 4360ceef..c2e063ac 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/NitroliteCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/NitroliteCommand.java @@ -1,11 +1,15 @@ package main.java.de.voidtech.gerald.commands.utils; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; +import com.jagrosh.jdautilities.commons.waiter.EventWaiter; + import main.java.de.voidtech.gerald.annotations.Command; import main.java.de.voidtech.gerald.commands.AbstractCommand; import main.java.de.voidtech.gerald.commands.CommandCategory; @@ -17,6 +21,7 @@ import main.java.de.voidtech.gerald.service.WebhookManager; import main.java.de.voidtech.gerald.util.ParsingUtils; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @Command public class NitroliteCommand extends AbstractCommand { @@ -35,6 +40,9 @@ public class NitroliteCommand extends AbstractCommand { @Autowired private WebhookManager webhookManager; + + @Autowired + private EventWaiter waiter; private boolean aliasAlreadyExists(String name, long serverID) { try(Session session = sessionFactory.openSession()) @@ -83,29 +91,88 @@ private void removeAlias(String aliasName, long serverID, Message message) { message.getChannel().sendMessage("**Alias with name **`" + aliasName + "`** has been deleted!**").queue(); } - private void searchEmoteDatabase(Message message, List args) { - String search = args.get(1); - - List result = emoteService.getEmotes(search, message.getJDA()); - - String searchResult = "**Database searched for: **`" + search + "`\n"; - if (result.size() == 0) { - searchResult += "Nothing found :("; - } else { - for (NitroliteEmote emote: result) { - searchResult += nitroliteService.constructEmoteString(emote) + " - " + emote.getName() + " - " + emote.getID() + "\n"; - } - } - + private void sendFallbackMessage(Message message, String content) { webhookManager.postMessageWithFallback( - message, searchResult, + message, content, message.getJDA().getSelfUser().getAvatarUrl(), message.getJDA().getSelfUser().getName(), "BGNitrolite"); - } - private void addEmoteAlias(Message message, List args) { + private List getFirstFifteen(List list) { + List firstFifteen = new ArrayList(); + if (list.size() > 15) { + for (int i = 0; i < 15; i++) { + firstFifteen.add(list.get(i)); + } + return firstFifteen; + } else { + return list; + } + } + + private List listWithFirstFifteenRemoved(List list) { + List tailOfList = new ArrayList(); + for (int i = 15; i < list.size(); i++) { + tailOfList.add(list.get(i)); + } + return tailOfList; + } + + private void sendPages(Message message, List result) { + List firstFifteenResults = getFirstFifteen(result); + String searchResult = ""; + boolean canSendMoreEmotes = false; + + for (NitroliteEmote emote: firstFifteenResults) { + searchResult += nitroliteService.constructEmoteString(emote) + " - " + emote.getName() + " - " + emote.getID() + "\n"; + } + + if (result.size() > 15) { + searchResult += "\n**Send 'more' to see more results!**"; + canSendMoreEmotes = true; + } + + sendFallbackMessage(message, searchResult); + + if (canSendMoreEmotes) { + waiter.waitForEvent(MessageReceivedEvent.class, + event -> ((MessageReceivedEvent) event).getAuthor().getId().equals(message.getAuthor().getId()), + event -> { + boolean moreRequested = event.getMessage().getContentRaw().toLowerCase().equals("more"); + if (moreRequested) { + sendPages(message, listWithFirstFifteenRemoved(result)); + } + }, 60, TimeUnit.SECONDS, + () -> message.getChannel().sendMessage("**Search ended**").queue()); + } + } + + private void searchEmoteDatabase(Message message, List args) { + String search = args.get(1); + + if (search.length() < 3) + message.getChannel().sendMessage("**Your search is too small! Please use at least 3 letters!**").queue(); + else { + List result = emoteService.getEmotes(search, message.getJDA()); + + String searchResult = "**Database searched for: **`" + search + "`\n"; + if (result.size() == 0) { + searchResult += "Nothing found :("; + } else { + if (result.size() > 15) { + sendPages(message, result); + } else { + for (NitroliteEmote emote: result) { + searchResult += nitroliteService.constructEmoteString(emote) + " - " + emote.getName() + " - " + emote.getID() + "\n"; + } + sendFallbackMessage(message, searchResult); + } + } + } + } + + private void addEmoteAlias(Message message, List args) { if (args.size() < 3) { message.getChannel().sendMessage("**You need to supply more arguments!**\n\n" + this.getUsage()).queue(); } else { @@ -150,13 +217,8 @@ private void sendAllAliases(Message message) { NitroliteEmote emote = emoteService.getEmoteById(alias.getEmoteID(), message.getJDA()); aliasMessage += nitroliteService.constructEmoteString(emote) + " - **Alias:** `" + alias.getAliasName() + "` **ID:** `" + alias.getEmoteID() + "`\n"; } + sendFallbackMessage(message, aliasMessage); } - - webhookManager.postMessageWithFallback( - message, aliasMessage, - message.getJDA().getSelfUser().getAvatarUrl(), - message.getJDA().getSelfUser().getName(), - "BGNitrolite"); } @Override @@ -226,4 +288,9 @@ public String[] getCommandAliases() { String[] aliases = {"nitro", "nl", "emotes", "emote"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/StarboardCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/StarboardCommand.java index 3d7e9fdd..0177cbdd 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/StarboardCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/StarboardCommand.java @@ -1,5 +1,6 @@ package main.java.de.voidtech.gerald.commands.utils; +import java.awt.Color; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -12,8 +13,10 @@ import main.java.de.voidtech.gerald.service.ServerService; import main.java.de.voidtech.gerald.service.StarboardService; import main.java.de.voidtech.gerald.util.ParsingUtils; +import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageEmbed; @Command public class StarboardCommand extends AbstractCommand { @@ -33,6 +36,8 @@ else if (args.size() < 3) String channelID = ParsingUtils.filterSnowflake(args.get(1)); if (!ParsingUtils.isSnowflake(channelID)) message.getChannel().sendMessage("**The channel you provided is not valid!**").queue(); + else if (!message.getGuild().getChannels().contains(message.getJDA().getGuildChannelById(channelID))) + message.getChannel().sendMessage("**The channel you provided is not in this server!**").queue(); else if (!ParsingUtils.isInteger(args.get(2))) message.getChannel().sendMessage("**You need to specify a number for the star count!**").queue(); else if (Integer.parseInt(args.get(2)) < 1) @@ -52,11 +57,15 @@ private void disableStarboard(Message message, Server server) { private void changeChannel(Message message, List args, Server server) { if (starboardService.getStarboardConfig(server.getId()) != null) { String channelID = ParsingUtils.filterSnowflake(args.get(1)); - if (!ParsingUtils.isSnowflake(channelID)) message.getChannel().sendMessage("**The channel you provided is not valid!**").queue(); + if (!ParsingUtils.isSnowflake(channelID)) + message.getChannel().sendMessage("**The channel you provided is not valid!**").queue(); + else if (!message.getGuild().getChannels().contains(message.getJDA().getGuildChannelById(channelID))) + message.getChannel().sendMessage("**The channel you provided is not in this server!**").queue(); else { StarboardConfig config = starboardService.getStarboardConfig(server.getId()); config.setChannelID(channelID); starboardService.updateConfig(config); + message.getChannel().sendMessage("**Message channel has been changed to <#" + channelID + ">!**").queue(); } } else message.getChannel().sendMessage("**A Starboard has not been set up here! Did you mean to use one of these?**\n\n" + this.getUsage()).queue(); } @@ -68,10 +77,78 @@ private void changeRequiredStarCount(Message message, List args, Server StarboardConfig config = starboardService.getStarboardConfig(server.getId()); config.setRequiredStarCount(Integer.parseInt(args.get(1))); starboardService.updateConfig(config); + message.getChannel().sendMessage("**Required count has been changed to " + args.get(1) + "!**").queue(); } } else message.getChannel().sendMessage("**A Starboard has not been set up here! Did you mean to use one of these?**\n\n" + this.getUsage()).queue(); } + + private void showIgnoredChannels(Message message, Server server) { + if (starboardService.getStarboardConfig(server.getId()) != null) { + List ignoredChannels = starboardService.getIgnoredChannels(server.getId()); + String ignoredChannelMessage = ""; + if (ignoredChannels == null) { + ignoredChannelMessage = "None ignored!"; + } else { + for (String id : ignoredChannels) + ignoredChannelMessage = ignoredChannelMessage + "<#" + id + ">\n"; + } + message.getChannel().sendMessage(constructIgnoredChannelEmbed(ignoredChannelMessage)).queue(); + } else message.getChannel().sendMessage("**A Starboard has not been set up here! Did you mean to use one of these?**\n\n" + this.getUsage()).queue(); + } + + private void ignoreChannel(Message message, List args, Server server) { + if (message.getMember().getPermissions().contains(Permission.MANAGE_CHANNEL)) { + if (starboardService.getStarboardConfig(server.getId()) != null) { + String channelID = ParsingUtils.filterSnowflake(args.get(1)); + if (!ParsingUtils.isSnowflake(channelID)) + message.getChannel().sendMessage("**The channel you provided is not valid!**").queue(); + else if (!message.getGuild().getChannels().contains(message.getJDA().getGuildChannelById(channelID))) + message.getChannel().sendMessage("**The channel you provided is not in this server!**").queue(); + else { + if (starboardService.getIgnoredChannels(server.getId()) == null) { + starboardService.addChannelToIgnorelist(server.getId(), channelID); + message.getChannel().sendMessage("<#" + channelID + "> **has been added to the blacklist!**").queue(); + } else if (starboardService.getIgnoredChannels(server.getId()).contains(channelID)) + message.getChannel().sendMessage("**This channel is already blacklisted!**").queue(); + else { + starboardService.addChannelToIgnorelist(server.getId(), channelID); + message.getChannel().sendMessage("<#" + channelID + "> **has been added to the blacklist!**").queue(); + } + } + } else message.getChannel().sendMessage("**A Starboard has not been set up here! Did you mean to use one of these?**\n\n" + this.getUsage()).queue(); + } + } + private void unignoreChannel(Message message, List args, Server server) { + if (message.getMember().getPermissions().contains(Permission.MANAGE_CHANNEL)) { + if (starboardService.getStarboardConfig(server.getId()) != null) { + String channelID = ParsingUtils.filterSnowflake(args.get(1)); + if (!ParsingUtils.isSnowflake(channelID)) + message.getChannel().sendMessage("**The channel you provided is not valid!**").queue(); + else if (!message.getGuild().getChannels().contains(message.getJDA().getGuildChannelById(channelID))) + message.getChannel().sendMessage("**The channel you provided is not in this server!**").queue(); + else { + if (starboardService.getIgnoredChannels(server.getId()) == null) + message.getChannel().sendMessage("**There is no blacklist yet!**").queue(); + else if (starboardService.getIgnoredChannels(server.getId()).contains(channelID)) { + starboardService.removeFromIgnorelist(server.getId(), channelID); + message.getChannel().sendMessage("<#" + channelID + "> **has been removed from the blacklist!**").queue(); + } else + message.getChannel().sendMessage("**This channel is not yet blacklisted!**").queue(); + } + } else message.getChannel().sendMessage("**A Starboard has not been set up here! Did you mean to use one of these?**\n\n" + this.getUsage()).queue(); + } + } + + private MessageEmbed constructIgnoredChannelEmbed(String ignoredChannelMessage) { + MessageEmbed ignoredChannelEmbed = new EmbedBuilder() + .setTitle("Starboard Ignored Channels") + .setColor(Color.ORANGE) + .setDescription(ignoredChannelMessage) + .build(); + return ignoredChannelEmbed; + } + @Override public void executeInternal(Message message, List args) { if (message.getMember().getPermissions().contains(Permission.MANAGE_CHANNEL)) { @@ -90,6 +167,15 @@ public void executeInternal(Message message, List args) { case "disable": disableStarboard(message, server); break; + case "ignore": + ignoreChannel(message, args, server); + break; + case "unignore": + unignoreChannel(message, args, server); + break; + case "ignored": + showIgnoredChannels(message, server); + break; default: message.getChannel().sendMessage("**That's not a valid subcommand! Try this instead:**\n\n" + this.getUsage()).queue(); } @@ -100,7 +186,9 @@ public void executeInternal(Message message, List args) { public String getDescription() { return "Do you like quoting things? Funny, interesting and more? Perfect!\n" + "Our starboard system allows you to react to messages with the :star: emote and have them automatically sent to" - + " a starboard channel in your server! Your server admins can choose the channel and number of stars needed to get it pinned! We recommend you use 5 stars"; + + " a starboard channel in your server! Your server admins can choose the channel and number of stars needed to get it pinned!" + + " Additionally, they may choose to ignore some channels. Ignore a channel with the ignore command, allow it again with the" + + " unignore command, and show all the ignored channels with the ignored command!"; } @Override @@ -108,7 +196,10 @@ public String getUsage() { return "starboard setup [Channel mention / ID] [Required star count]\n" + "starboard count [New number of stars needed]\n" + "starboard channel [New channel mention / ID]\n" - + "starboard disable\n\n" + + "starboard disable\n" + + "starboard ignore [channel mention / ID]\n" + + "starboard unignore [channel mention / ID]\n" + + "starboard ignored\n\n" + "NOTE: You MUST run the setup command first!"; } @@ -137,5 +228,10 @@ public String[] getCommandAliases() { String[] aliases = {"autoquote", "quotechannel", "sb"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/SuggestCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/SuggestCommand.java index 32ed218d..cdfefbd5 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/SuggestCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/SuggestCommand.java @@ -220,5 +220,10 @@ public String[] getCommandAliases() { String[] aliases = {"idea", "suggestion"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/TunnelCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/TunnelCommand.java index bbedb508..18cfa45b 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/TunnelCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/TunnelCommand.java @@ -58,8 +58,8 @@ private void fillTunnel(Message message) { private void sendChannelVerificationRequest(TextChannel targetChannel, Message originChannelMessage, User tunnelInstantiator) { String targetChannelID = targetChannel.getId(); String originChannelID = originChannelMessage.getChannel().getId(); - //TODO: Redo this, it doesn't work - //pendingRequests.put(targetChannel.getId(), originChannelMessage.getChannel().getLatestMessageId()); + + addToMap(targetChannel, originChannelMessage); targetChannel.getGuild().retrieveMember(tunnelInstantiator).queue(member -> { if (member == null) { @@ -68,7 +68,7 @@ private void sendChannelVerificationRequest(TextChannel targetChannel, Message o if (member.hasPermission(Permission.MANAGE_CHANNEL)) { targetChannel.sendMessage("**Incoming tunnel request from " + originChannelMessage.getGuild().getName() + " > " + originChannelMessage.getChannel().getName() - + "**\nSay 'accept' within 15 seconds to allow this tunnel to be dug!").queue(); + + "**\nSay 'accept' within 30 seconds to allow this tunnel to be dug!").queue(); waiter.waitForEvent(MessageReceivedEvent.class, event -> tunnelAcceptedStatement(((MessageReceivedEvent) event), targetChannel), event -> { @@ -94,6 +94,10 @@ private void removeFromMap(String targetChannelID, String originChannelID) { this.pendingRequests.remove(targetChannelID); this.pendingRequests.remove(originChannelID); } + + private void addToMap(TextChannel targetChannel, Message originChannelMessage) { + this.pendingRequests.put(targetChannel.getId(), originChannelMessage.getChannel().getId()); + } private boolean tunnelAcceptedStatement(MessageReceivedEvent event, TextChannel targetChannel) { @@ -257,5 +261,10 @@ public String[] getCommandAliases() { String[] aliases = {"spaceport", "connection"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } diff --git a/src/main/java/de/voidtech/gerald/commands/utils/WelcomerCommand.java b/src/main/java/de/voidtech/gerald/commands/utils/WelcomerCommand.java index e24d0a62..a7a0f398 100644 --- a/src/main/java/de/voidtech/gerald/commands/utils/WelcomerCommand.java +++ b/src/main/java/de/voidtech/gerald/commands/utils/WelcomerCommand.java @@ -179,8 +179,6 @@ private void beginSetup(Message message, Server server) { () -> message.getChannel().sendMessage("**No input has been supplied, cancelling.**").queue()); } - //TODO REVIEW: This b is fatter than yo mama. I have no idea rn because it's 1AM but this should be refactored. - //Update: the chongus algorithm has been de-chongo'd (RIP 19/03/2021 - 24/05/2021) private void setupWelcomer(Server server, Message message) { if (customMessageEnabled(server.getId())) { message.getChannel().sendMessage("**The Welcomer is already set up!**").queue(); @@ -305,5 +303,10 @@ public String[] getCommandAliases() { String[] aliases = {"jm", "joinmessage"}; return aliases; } + + @Override + public boolean canBeDisabled() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/entities/Server.java b/src/main/java/de/voidtech/gerald/entities/Server.java index 5ba03b02..858bf6c9 100644 --- a/src/main/java/de/voidtech/gerald/entities/Server.java +++ b/src/main/java/de/voidtech/gerald/entities/Server.java @@ -36,6 +36,10 @@ public class Server @ElementCollection(fetch = FetchType.EAGER) @Cascade(CascadeType.REMOVE) private Set commandBlacklist; + + @ElementCollection(fetch = FetchType.EAGER) + @Cascade(CascadeType.REMOVE) + private Set routineBlacklist; @Column private String prefix; @@ -78,11 +82,27 @@ public Set getCommandBlacklist() { else return Collections.unmodifiableSet(this.commandBlacklist); } - public void addToCommandBlacklist(String channelID) { - this.commandBlacklist.add(channelID); + public void addToCommandBlacklist(String commandName) { + this.commandBlacklist.add(commandName); + } + public void removeFromCommandBlacklist(String commandName) { + this.commandBlacklist.remove(commandName); + } + + public void clearCommandBlacklist() { + this.commandBlacklist.clear(); + } + + public Set getRoutineBlacklist() { + if (this.routineBlacklist == null) return Collections.unmodifiableSet(new HashSet()); + else return Collections.unmodifiableSet(this.routineBlacklist); + } + + public void addToRoutineBlacklist(String routineName) { + this.routineBlacklist.add(routineName); } - public void removeFromCommandBlacklist(String channelID) { - this.commandBlacklist.remove(channelID); + public void removeFromRoutineBlacklist(String routineName) { + this.routineBlacklist.remove(routineName); } public String getPrefix() { diff --git a/src/main/java/de/voidtech/gerald/entities/StarboardConfig.java b/src/main/java/de/voidtech/gerald/entities/StarboardConfig.java index 648cb0f2..11a88024 100644 --- a/src/main/java/de/voidtech/gerald/entities/StarboardConfig.java +++ b/src/main/java/de/voidtech/gerald/entities/StarboardConfig.java @@ -1,5 +1,8 @@ package main.java.de.voidtech.gerald.entities; +import java.util.Arrays; +import java.util.List; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -15,8 +18,7 @@ public class StarboardConfig { @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - //TODO: REVIEW Should this be unique? - @Column + @Column(unique = true) private String starboardChannel; @Column @@ -25,16 +27,20 @@ public class StarboardConfig { @Column private long requiredStarCount; + @Column + private String ignoredChannels; + @Deprecated //ONLY FOR HIBERNATE, DO NOT USE StarboardConfig() { } - public StarboardConfig(long serverID, String channelID, long requiredStarCount) + public StarboardConfig(long serverID, String channelID, long requiredStarCount, String ignoredChannels) { this.serverID = serverID; this.starboardChannel = channelID; this.requiredStarCount = requiredStarCount; + this.ignoredChannels = ignoredChannels; } public long getServerID() { @@ -60,4 +66,15 @@ public long getRequiredStarCount() { public void setRequiredStarCount(long newCount) { this.requiredStarCount = newCount; } + + public List getIgnoredChannels() { + return ignoredChannels == null ? null : Arrays.asList(ignoredChannels.split(",")); + } + + public void setIgnoredChannels(List newList) { + String newListCompiled = ""; + for (String item : newList) + newListCompiled = newListCompiled + item + ","; + this.ignoredChannels = newListCompiled; + } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/entities/StarboardMessage.java b/src/main/java/de/voidtech/gerald/entities/StarboardMessage.java index 747b938d..62ae7d59 100644 --- a/src/main/java/de/voidtech/gerald/entities/StarboardMessage.java +++ b/src/main/java/de/voidtech/gerald/entities/StarboardMessage.java @@ -15,12 +15,10 @@ public class StarboardMessage { @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - //TODO: REVIEW should be unique - @Column + @Column(unique = true) private String originMessageID; - //TODO: REVIEW should this be unique? - @Column + @Column(unique = true) private String selfMessageID; @Column diff --git a/src/main/java/de/voidtech/gerald/entities/TwitchNotificationChannel.java b/src/main/java/de/voidtech/gerald/entities/TwitchNotificationChannel.java new file mode 100644 index 00000000..40a9e107 --- /dev/null +++ b/src/main/java/de/voidtech/gerald/entities/TwitchNotificationChannel.java @@ -0,0 +1,74 @@ +package main.java.de.voidtech.gerald.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "TwitchNotificationChannel") + +public class TwitchNotificationChannel { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column + private String channelID; + + @Column + private String streamerName; + + @Column + private String notificationMessage; + + @Column + private long serverID; + + @Deprecated + //ONLY FOR HIBERNATE, DO NOT USE + TwitchNotificationChannel() { + } + + public TwitchNotificationChannel(String channelID, String streamerName, String notificationMessage, long serverID) + { + this.channelID = channelID; + this.streamerName = streamerName; + this.notificationMessage = notificationMessage; + this.serverID = serverID; + } + + public String getChannelId() { + return channelID; + } + + public void setChannelId(String newChannelID) { + this.channelID = newChannelID; + } + + public String getStreamerName() { + return streamerName; + } + + public void setStreamerName(String streamerName) { + this.streamerName = streamerName; + } + + public String getNotificationMessage() { + return notificationMessage; + } + + public void setNotificationMessahe(String notificationMessage) { + this.notificationMessage = notificationMessage; + } + + public long getServerId() { + return serverID; + } + + public void setServerId(long serverID) { + this.serverID = serverID; + } +} \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/listeners/ReadyListener.java b/src/main/java/de/voidtech/gerald/listeners/ReadyListener.java index b5730f2b..690ca34a 100644 --- a/src/main/java/de/voidtech/gerald/listeners/ReadyListener.java +++ b/src/main/java/de/voidtech/gerald/listeners/ReadyListener.java @@ -8,6 +8,7 @@ import main.java.de.voidtech.gerald.service.GeraldConfig; import main.java.de.voidtech.gerald.service.MessageHandler; +import main.java.de.voidtech.gerald.service.TwitchNotificationService; import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.events.ReadyEvent; import net.dv8tion.jda.api.hooks.EventListener; @@ -20,12 +21,17 @@ public class ReadyListener implements EventListener { @Autowired private MessageHandler messageHandler; + @Autowired + private TwitchNotificationService twitchService; + @Override public void onEvent(GenericEvent event) { if (event instanceof ReadyEvent) { String clientName = ((ReadyEvent) event).getJDA().getSelfUser().getAsTag(); LOGGER.log(Level.INFO, "Coffee Machine is ready! Serving lattes as " + clientName); - messageHandler.loadAliases(); + + messageHandler.loadAliases(); + twitchService.subscribeToAllStreamers(); } } } diff --git a/src/main/java/de/voidtech/gerald/listeners/StarboardListener.java b/src/main/java/de/voidtech/gerald/listeners/StarboardListener.java index b07914cb..e8bfceff 100644 --- a/src/main/java/de/voidtech/gerald/listeners/StarboardListener.java +++ b/src/main/java/de/voidtech/gerald/listeners/StarboardListener.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import main.java.de.voidtech.gerald.entities.StarboardConfig; import main.java.de.voidtech.gerald.service.ServerService; import main.java.de.voidtech.gerald.service.StarboardService; import net.dv8tion.jda.api.events.GenericEvent; @@ -28,12 +29,20 @@ public void onEvent(GenericEvent event) { long serverID = serverService.getServer(reaction.getGuild().getId()).getId(); - if (starboardService.getStarboardConfig(serverID) != null) { - if (!starboardService.reactionIsInStarboardChannel(reaction.getChannel().getId(), serverID)) { - starboardService.checkStars(serverID, reaction); - } + StarboardConfig config = starboardService.getStarboardConfig(serverID); + if (config != null) { + pinStarIfAllowed(reaction, config, serverID); } } } } + + private void pinStarIfAllowed(GuildMessageReactionAddEvent reaction, StarboardConfig config, long serverID) { + if (!starboardService.reactionIsInStarboardChannel(reaction.getChannel().getId(), serverID)) { + if (config.getIgnoredChannels() != null) { + if (!config.getIgnoredChannels().contains(reaction.getChannel().getId())) + starboardService.checkStars(serverID, reaction); + } else starboardService.checkStars(serverID, reaction); + } + } } diff --git a/src/main/java/de/voidtech/gerald/routines/AbstractRoutine.java b/src/main/java/de/voidtech/gerald/routines/AbstractRoutine.java index a4162c1e..75355717 100644 --- a/src/main/java/de/voidtech/gerald/routines/AbstractRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/AbstractRoutine.java @@ -1,11 +1,15 @@ package main.java.de.voidtech.gerald.routines; +import main.java.de.voidtech.gerald.entities.Server; +import main.java.de.voidtech.gerald.service.ServerService; import org.springframework.beans.factory.annotation.Autowired; import main.java.de.voidtech.gerald.service.ThreadManager; import net.dv8tion.jda.api.entities.Message; public abstract class AbstractRoutine { + @Autowired + private ServerService serverService; @Autowired ThreadManager threadManager; @@ -20,8 +24,11 @@ public void run() { } public void run(Message message) { - runRoutineInThread(message); - } + Server server = serverService.getServer(message.getGuild().getId()); + if (!server.getRoutineBlacklist().contains(getName())) { + runRoutineInThread(message); + } + } public abstract void executeInternal(Message message); @@ -33,4 +40,6 @@ public void run(Message message) { public abstract boolean allowsBotResponses(); + public abstract boolean canBeDisabled(); + } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/routines/fun/BottiusResponseRoutine.java b/src/main/java/de/voidtech/gerald/routines/fun/BottiusResponseRoutine.java index 3945a2c6..e0d01e3a 100644 --- a/src/main/java/de/voidtech/gerald/routines/fun/BottiusResponseRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/fun/BottiusResponseRoutine.java @@ -44,7 +44,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "Greets bottius mightily"; + return "Greets bottius mightily in some very special servers"; } @Override @@ -52,9 +52,14 @@ public boolean allowsBotResponses() { return true; } + @Override + public boolean canBeDisabled() { + return true; + } + @Override public String getName() { - return "Bottius-Routine"; + return "r-bottius"; } @Override diff --git a/src/main/java/de/voidtech/gerald/routines/fun/ChatRoutine.java b/src/main/java/de/voidtech/gerald/routines/fun/ChatRoutine.java index 9b810c66..3fcc4202 100644 --- a/src/main/java/de/voidtech/gerald/routines/fun/ChatRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/fun/ChatRoutine.java @@ -45,7 +45,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "GeraldAI Routine"; + return "Allows channels with the chat command to work. Communicates with our AI chatbot"; } @Override @@ -53,9 +53,14 @@ public boolean allowsBotResponses() { return false; } + @Override + public boolean canBeDisabled() { + return false; + } + @Override public String getName() { - return "GeraldAI"; + return "r-chat"; } @Override diff --git a/src/main/java/de/voidtech/gerald/routines/fun/CountRoutine.java b/src/main/java/de/voidtech/gerald/routines/fun/CountRoutine.java index c9ff4814..66a824ef 100644 --- a/src/main/java/de/voidtech/gerald/routines/fun/CountRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/fun/CountRoutine.java @@ -193,7 +193,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "Handles counting channels"; + return "Allows channels with counting enabled to work"; } @Override @@ -201,9 +201,14 @@ public boolean allowsBotResponses() { return false; } + @Override + public boolean canBeDisabled() { + return false; + } + @Override public String getName() { - return "Counting"; + return "r-count"; } @Override diff --git a/src/main/java/de/voidtech/gerald/routines/utils/NitroliteCollectorRoutine.java b/src/main/java/de/voidtech/gerald/routines/utils/NitroliteCollectorRoutine.java index ebb64b24..a32e4fd3 100644 --- a/src/main/java/de/voidtech/gerald/routines/utils/NitroliteCollectorRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/utils/NitroliteCollectorRoutine.java @@ -104,7 +104,7 @@ public void executeInternal(Message message) { @Override public String getName() { - return "EmoteGrabber5000"; + return "r-EmoteGrabber5000"; } @Override @@ -122,4 +122,9 @@ public boolean allowsBotResponses() { return true; } + @Override + public boolean canBeDisabled() { + return false; + } + } diff --git a/src/main/java/de/voidtech/gerald/routines/utils/NitroliteRoutine.java b/src/main/java/de/voidtech/gerald/routines/utils/NitroliteRoutine.java index 843fad47..a9388784 100644 --- a/src/main/java/de/voidtech/gerald/routines/utils/NitroliteRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/utils/NitroliteRoutine.java @@ -90,7 +90,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "Service for sending emotes without nitro"; + return "Allows nitrolite messages to be detected and handled"; } @Override @@ -98,9 +98,14 @@ public boolean allowsBotResponses() { return false; } + @Override + public boolean canBeDisabled() { + return true; + } + @Override public String getName() { - return "Nitrolite"; + return "r-nitrolite"; } @Override diff --git a/src/main/java/de/voidtech/gerald/routines/utils/PingResponseRoutine.java b/src/main/java/de/voidtech/gerald/routines/utils/PingResponseRoutine.java index c3bdb93d..82cf91c4 100644 --- a/src/main/java/de/voidtech/gerald/routines/utils/PingResponseRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/utils/PingResponseRoutine.java @@ -60,7 +60,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "Allows Gerald to respond when he is pinged"; + return "Allows Gerald to respond when he is mentioned"; } @Override @@ -68,9 +68,14 @@ public boolean allowsBotResponses() { return false; } + @Override + public boolean canBeDisabled() { + return false; + } + @Override public String getName() { - return "PingResponder"; + return "r-ping"; } @Override diff --git a/src/main/java/de/voidtech/gerald/routines/utils/TunnelRoutine.java b/src/main/java/de/voidtech/gerald/routines/utils/TunnelRoutine.java index f5a3517b..3313452f 100644 --- a/src/main/java/de/voidtech/gerald/routines/utils/TunnelRoutine.java +++ b/src/main/java/de/voidtech/gerald/routines/utils/TunnelRoutine.java @@ -119,7 +119,7 @@ public void executeInternal(Message message) { @Override public String getDescription() { - return "The routine for handling tunnels"; + return "Allows tunnels to be handled"; } @Override @@ -127,9 +127,14 @@ public boolean allowsBotResponses() { return true; } + @Override + public boolean canBeDisabled() { + return false; + } + @Override public String getName() { - return "Tunnels"; + return "r-tunnel"; } @Override diff --git a/src/main/java/de/voidtech/gerald/service/EmoteService.java b/src/main/java/de/voidtech/gerald/service/EmoteService.java index 97eef6b9..5136fa16 100644 --- a/src/main/java/de/voidtech/gerald/service/EmoteService.java +++ b/src/main/java/de/voidtech/gerald/service/EmoteService.java @@ -22,8 +22,8 @@ public class EmoteService { private List getPersistentEmotes(String name) { try(Session session = sessionFactory.openSession()) { - List emotes = (List) session.createQuery("FROM NitroliteEmote WHERE LOWER(name) = :name", NitroliteEmote.class) - .setParameter("name", name.toLowerCase()) + List emotes = (List) session.createQuery("FROM NitroliteEmote WHERE LOWER(name) LIKE :name", NitroliteEmote.class) + .setParameter("name", "%" + name.toLowerCase() + "%") .list(); return emotes; } diff --git a/src/main/java/de/voidtech/gerald/service/GeraldConfig.java b/src/main/java/de/voidtech/gerald/service/GeraldConfig.java index 5561d9f1..37e77778 100644 --- a/src/main/java/de/voidtech/gerald/service/GeraldConfig.java +++ b/src/main/java/de/voidtech/gerald/service/GeraldConfig.java @@ -87,8 +87,11 @@ public String getGavinURL() { return url != null ? url : "http://localhost:8000/chat_bot/"; } - public String getSeleniumDriverPath() { - String dir = config.getProperty("seleniumDirectory"); - return dir != null ? dir : "bin/geckodriver.exe"; + public String getTwitchClientId() { + return config.getProperty("twitch.clientId"); + } + + public String getTwitchSecret() { + return config.getProperty("twitch.secret"); } } \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/service/JoinLeaveMessageService.java b/src/main/java/de/voidtech/gerald/service/JoinLeaveMessageService.java index 722e95e3..09a621fc 100644 --- a/src/main/java/de/voidtech/gerald/service/JoinLeaveMessageService.java +++ b/src/main/java/de/voidtech/gerald/service/JoinLeaveMessageService.java @@ -1,6 +1,7 @@ package main.java.de.voidtech.gerald.service; import java.awt.Color; +import java.time.Instant; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -11,6 +12,7 @@ import main.java.de.voidtech.gerald.entities.Server; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.GuildChannel; +import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; @@ -51,12 +53,12 @@ public void sendJoinMessage(GuildMemberJoinEvent event) { JoinLeaveMessage joinLeaveMessage = getJoinLeaveMessageEntity(server.getId()); GuildChannel channel = event.getJDA().getGuildChannelById(joinLeaveMessage.getChannelID()); String message = joinLeaveMessage.getJoinMessage(); - String member = event.getMember().getAsMention(); + Member member = event.getMember(); MessageEmbed joinMessageEmbed = new EmbedBuilder() .setColor(Color.green) - .setDescription(member + " **" + message + "**") - .setTimestamp(null) + .setDescription(member.getAsMention() + " **(" + member.getUser().getAsTag() + ")" + message + "**") + .setTimestamp(Instant.now()) .build(); ((MessageChannel) channel).sendMessage(joinMessageEmbed).queue(); @@ -69,12 +71,12 @@ public void sendLeaveMessage(GuildMemberRemoveEvent event) { JoinLeaveMessage joinLeaveMessage = getJoinLeaveMessageEntity(server.getId()); GuildChannel channel = event.getJDA().getGuildChannelById(joinLeaveMessage.getChannelID()); String message = joinLeaveMessage.getLeaveMessage(); - String member = event.getUser().getAsMention(); + Member member = event.getMember(); MessageEmbed leaveMessageEmbed = new EmbedBuilder() .setColor(Color.red) - .setDescription(member + " **" + message + "**") - .setTimestamp(null) + .setDescription(member.getAsMention() + " **(" + member.getUser().getAsTag() + ")" + message + "**") + .setTimestamp(Instant.now()) .build(); ((MessageChannel) channel).sendMessage(leaveMessageEmbed).queue(); diff --git a/src/main/java/de/voidtech/gerald/service/MessageHandler.java b/src/main/java/de/voidtech/gerald/service/MessageHandler.java index 8f486d65..4682ba64 100644 --- a/src/main/java/de/voidtech/gerald/service/MessageHandler.java +++ b/src/main/java/de/voidtech/gerald/service/MessageHandler.java @@ -44,7 +44,6 @@ public void loadAliases() { LOGGER.log(Level.INFO, "Command aliases have been loaded"); } - // ENTRY POINT FROM MESSAGE LISTENER public void handleMessage(Message message) { if (message.isWebhookMessage()) return; @@ -99,11 +98,6 @@ private void handleCommandOnDemand(Message message) { message.getChannel().sendMessage("**You can only use this command in guilds!**").queue(); return; } - - if (commandOpt.requiresArguments() && messageArray.size() <= 1) { - message.getChannel().sendMessage("**This command needs arguments to work! See the help command for more details!**\n" + commandOpt.getUsage()).queue(); - return; - } commandOpt.run(message, messageArray.subList(1, messageArray.size())); diff --git a/src/main/java/de/voidtech/gerald/service/StarboardService.java b/src/main/java/de/voidtech/gerald/service/StarboardService.java index e5a956f6..0f9d5960 100644 --- a/src/main/java/de/voidtech/gerald/service/StarboardService.java +++ b/src/main/java/de/voidtech/gerald/service/StarboardService.java @@ -1,6 +1,9 @@ package main.java.de.voidtech.gerald.service; import java.awt.Color; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -13,6 +16,7 @@ import main.java.de.voidtech.gerald.entities.StarboardMessage; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.Message.Attachment; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageReaction; import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent; @@ -63,7 +67,7 @@ public void completeStarboardSetup(Message message, String channelID, String sta { session.getTransaction().begin(); - StarboardConfig config = new StarboardConfig(server.getId(), channelID, requiredStarCount); + StarboardConfig config = new StarboardConfig(server.getId(), channelID, requiredStarCount, null); session.saveOrUpdate(config); session.getTransaction().commit(); @@ -103,10 +107,27 @@ private MessageEmbed constructEmbed(Message message) { .setColor(Color.ORANGE) .setAuthor(message.getAuthor().getAsTag(), GlobalConstants.LINKTREE_URL, message.getAuthor().getAvatarUrl()) .setDescription(message.getContentRaw()) - .setTitle("Jump to message!", message.getJumpUrl()); + .setTitle("Jump to message!", message.getJumpUrl()) + .setTimestamp(Instant.now()) + .setFooter("in #" + message.getChannel().getName()); + boolean found = false; if (message.getAttachments().size() > 0) { - starboardEmbed.setImage(message.getAttachments().get(0).getUrl()); + + for (Attachment attachment : message.getAttachments()) { + if (attachment.isImage() && !found) { + starboardEmbed.setImage(attachment.getUrl()); + found = true; + } + } + } + if (!found && !message.getEmbeds().isEmpty()) { + for (MessageEmbed embed : message.getEmbeds()) { + if (embed.getImage() != null && !found) { + starboardEmbed.setImage(embed.getImage().getUrl()); + found = true; + } + } } return starboardEmbed.build(); @@ -165,4 +186,35 @@ public void checkStars(long serverID, GuildMessageReactionAddEvent reaction) { sendOrUpdateMessage(serverID, reaction, config, message, starCountFromMessage); } } + + public List getIgnoredChannels(long serverID) { + StarboardConfig config = getStarboardConfig(serverID); + return config.getIgnoredChannels(); + } + + public void addChannelToIgnorelist(long serverID, String channelID) { + List ignoredChannels = getIgnoredChannels(serverID); + List newIgnoredChannelList; + if (ignoredChannels == null) { + newIgnoredChannelList = new ArrayList(); + newIgnoredChannelList.add(channelID); + } else { + newIgnoredChannelList = new ArrayList(ignoredChannels); + newIgnoredChannelList.add(channelID); + } + StarboardConfig config = getStarboardConfig(serverID); + config.setIgnoredChannels(newIgnoredChannelList); + updateConfig(config); + } + + public void removeFromIgnorelist(long serverID, String channelID) { + List ignoredChannels = getIgnoredChannels(serverID); + List newIgnoredChannelList = new ArrayList(ignoredChannels); + newIgnoredChannelList.remove(channelID); + if (newIgnoredChannelList.size() == 0) + newIgnoredChannelList = null; + StarboardConfig config = getStarboardConfig(serverID); + config.setIgnoredChannels(newIgnoredChannelList); + updateConfig(config); + } } diff --git a/src/main/java/de/voidtech/gerald/service/TwitchNotificationService.java b/src/main/java/de/voidtech/gerald/service/TwitchNotificationService.java new file mode 100644 index 00000000..303ecbd0 --- /dev/null +++ b/src/main/java/de/voidtech/gerald/service/TwitchNotificationService.java @@ -0,0 +1,182 @@ +package main.java.de.voidtech.gerald.service; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.github.twitch4j.TwitchClient; +import com.github.twitch4j.TwitchClientBuilder; +import com.github.twitch4j.events.ChannelGoLiveEvent; + +import main.java.de.voidtech.gerald.entities.TwitchNotificationChannel; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.TextChannel; + +@Service +public class TwitchNotificationService { + + private static final Logger LOGGER = Logger.getLogger(TwitchNotificationService.class.getName()); + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private GeraldConfig geraldConfig; + + @Autowired + private JDA jda; + + private TwitchClient twitchClient; + + public void subscribeToAllStreamers() { + String twitchClientId = geraldConfig.getTwitchClientId(); + String twitchClientSecret = geraldConfig.getTwitchSecret(); + + if (twitchClientId != null && twitchClientSecret != null) { + LOGGER.log(Level.INFO, "Adding Twitch API subscriptions"); + twitchClient = TwitchClientBuilder.builder() + .withEnableHelix(true) + .withClientId(twitchClientId) + .withClientSecret(twitchClientSecret) + .build(); + + List streamerNames = getAllStreamerNames(); + if (streamerNames != null) { + for (String name : streamerNames) { + twitchClient.getClientHelper().enableStreamEventListener(name); + } + } + + LOGGER.log(Level.INFO, "Added Twitch API subscriptions!"); + listenForTwitchEvents(); + } + } + + private void listenForTwitchEvents() { + twitchClient.getEventManager().onEvent(ChannelGoLiveEvent.class, event -> { + String streamerName = event.getChannel().getName(); + List channels = getNotificationChannelsByStreamerName(streamerName); + for (TwitchNotificationChannel channel : channels) { + sendNotificationMessage(channel, jda); + } + }); + } + + private void sendNotificationMessage(TwitchNotificationChannel channel, JDA jda) { + TextChannel notificationChannel = jda.getTextChannelById(channel.getChannelId()); + if (notificationChannel == null) + removeChannelSubscriptionByChannelId(channel.getStreamerName(), channel.getChannelId()); + else + notificationChannel.sendMessage(formMessage(channel)).queue(); + } + + private CharSequence formMessage(TwitchNotificationChannel channel) { + return channel.getNotificationMessage() + "\nhttps://twitch.tv/" + channel.getStreamerName(); + } + + @SuppressWarnings("unchecked") + private List getAllStreamerNames() { + try(Session session = sessionFactory.openSession()) + { + List names = (List) session.createQuery("SELECT DISTINCT streamerName FROM TwitchNotificationChannel") + .list(); + return names; + } + } + + @SuppressWarnings("unchecked") + private List getNotificationChannelsByStreamerName(String streamerName) { + try(Session session = sessionFactory.openSession()) + { + List channels = (List) session.createQuery("FROM TwitchNotificationChannel WHERE streamerName = :streamerName") + .setParameter("streamerName", streamerName) + .list(); + return channels; + } + } + + public void addSubscription(String streamerName, String channelId, String notificationMessage, long serverID) { + if (zeroChannelsSubscribed(streamerName)) { + twitchClient.getClientHelper().enableStreamEventListener(streamerName); + } + persistChannelSubscription(streamerName, channelId, notificationMessage, serverID); + } + + private void persistChannelSubscription(String streamerName, String channelId, String notificationMessage, long serverID) { + try(Session session = sessionFactory.openSession()) + { + session.getTransaction().begin(); + + TwitchNotificationChannel channel = new TwitchNotificationChannel(channelId, streamerName, notificationMessage, serverID); + session.saveOrUpdate(channel); + session.getTransaction().commit(); + } + } + + private boolean zeroChannelsSubscribed(String streamerName) { + try(Session session = sessionFactory.openSession()) + { + @SuppressWarnings("rawtypes") + Query query = session.createQuery("SELECT COUNT(*) FROM TwitchNotificationChannel WHERE streamerName = :streamerName") + .setParameter("streamerName", streamerName); + long count = ((long)query.uniqueResult()); + session.close(); + return count == 0; + } + } + + public boolean subscriptionExists(String streamerName, long id) { + try(Session session = sessionFactory.openSession()) + { + TwitchNotificationChannel channel = (TwitchNotificationChannel) session.createQuery("FROM TwitchNotificationChannel WHERE streamerName = :streamerName AND serverID = :serverID") + .setParameter("streamerName", streamerName) + .setParameter("serverID", id) + .uniqueResult(); + return channel != null; + } + } + + private void removeChannelSubscriptionByChannelId(String streamerName, String id) { + try(Session session = sessionFactory.openSession()) + { + session.getTransaction().begin(); + session.createQuery("DELETE FROM TwitchNotificationChannel WHERE channelID = :channelID AND streamerName = :streamerName") + .setParameter("channelID", id) + .setParameter("streamerName", streamerName) + .executeUpdate(); + session.getTransaction().commit(); + } + } + + public void removeChannelSubscription(String streamerName, long id) { + try(Session session = sessionFactory.openSession()) + { + session.getTransaction().begin(); + session.createQuery("DELETE FROM TwitchNotificationChannel WHERE serverID = :serverID AND streamerName = :streamerName") + .setParameter("serverID", id) + .setParameter("streamerName", streamerName) + .executeUpdate(); + session.getTransaction().commit(); + } + if (zeroChannelsSubscribed(streamerName)) { + twitchClient.getClientHelper().disableStreamEventListener(streamerName); + } + } + + @SuppressWarnings("unchecked") + public List getAllSubscriptionsForServer(long serverID) { + try(Session session = sessionFactory.openSession()) + { + List channels = (List) session.createQuery("FROM TwitchNotificationChannel WHERE serverID = :serverID") + .setParameter("serverID", serverID) + .list(); + return channels; + } + } +} \ No newline at end of file diff --git a/src/main/java/de/voidtech/gerald/util/ParsingUtils.java b/src/main/java/de/voidtech/gerald/util/ParsingUtils.java index c45ade34..6f07b165 100644 --- a/src/main/java/de/voidtech/gerald/util/ParsingUtils.java +++ b/src/main/java/de/voidtech/gerald/util/ParsingUtils.java @@ -1,11 +1,16 @@ package main.java.de.voidtech.gerald.util; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; public class ParsingUtils { + + private static final Pattern HEX_PATTERN = Pattern.compile("^([a-fA-F0-9]{6})$"); + public static boolean isInteger(String str) { if (str == null) { return false; @@ -55,4 +60,9 @@ public static Member getMember(Message message, List args) { public static boolean isSnowflake(String input) { return isInteger(input) && input.length() == 18; } + + public static boolean isHexadecimal(String input) { + Matcher hexMatcher = HEX_PATTERN.matcher(input); + return hexMatcher.find(); + } }