diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index e46c16f6..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "maven" # See documentation for possible values - directory: "/" # Location of package manifests - schedule: - interval: "daily" - target_branch: "develop" diff --git a/images/FriendlyBot.png b/.github/images/FriendlyBot.png similarity index 100% rename from images/FriendlyBot.png rename to .github/images/FriendlyBot.png diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 1fc2dda7..00000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,34 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Build - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Archive full target folder - uses: actions/upload-artifact@v2 - with: - name: friendlybot - path: target/ - - name: Archive Compiled and Shaded Archive - uses: actions/upload-artifact@v2 - with: - name: friendlybot - path: target/friendlybot-1.0.0-shaded.jar diff --git a/.gitignore b/.gitignore index 200f86b4..36a40da0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,15 @@ +# Gradle +.gradle/ +build/ + +# Unit testing +friendlybot.mv.db + # Runtime stuff /*.json src/test/resources/img* +friendlybot-locale.properties +friendlybot.conf # Private tests src/test/java/io/paradaux/friendlybot/managers/MailGunManagerTest.java diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d2f6ba3c..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Rían Errity - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Placeholders.md b/Placeholders.md deleted file mode 100644 index e69de29b..00000000 diff --git a/README.md b/README.md index e99c21c3..c2b68ef5 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ # FriendlyBot ![Build](https://github.com/ParadauxIO/FriendlyBot/workflows/Build/badge.svg?branch=main) +[![CodeFactor](https://www.codefactor.io/repository/github/paradauxio/friendlybot/badge)](https://www.codefactor.io/repository/github/paradauxio/friendlybot) ![Version](https://img.shields.io/badge/version-1.0.0-009999) ![License](https://img.shields.io/github/license/ParadauxIO/FriendlyBot)

- - Logo - + + Logo +

FriendlyBot

-

+

The general-purpose discord bot made for the Computer Science Friendly Corner.
YouTrack @@ -20,7 +21,6 @@ Issues · Actions -

There are plans to generify the codebase to allow for a public discord bot, as well as having a web-based user interface @@ -34,7 +34,7 @@ production server. FriendlyBot makes use of a MongoDB database which is integral to the functionality of the bot, the connection url must be specified in the configuration file. As well as that, a stable internet connection is required at all times; to talk to -discord and the various web APIs the bot makes use of. +discord, and the various web APIs the bot makes use of. The following instructions are to be executed on the command line (terminal) requiring write permissions. This requires both Maven and Git to be added to your terminal's path, other than that these instructions are fairly platform agnostic. @@ -67,4 +67,5 @@ Distributed under the MIT License. See [LICENSE.md](https://github.com/ParadauxI ## Contributors -1. [Rían Errity](mailto:rian@paradaux.io) — Project Lead — https://paradaux.io \ No newline at end of file +1. [Rían Errity](mailto:rian@paradaux.io) — Project Lead — https://paradaux.io +2. This could be you o.0 \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..1b7fcdc2 --- /dev/null +++ b/build.gradle @@ -0,0 +1,76 @@ +plugins { + id 'java' + id 'io.ebean' version '12.10.0' + id 'com.github.johnrengelman.shadow' version '7.0.0' +} + +group 'io.paradaux' +version '2.0.0' + +repositories { + gradlePluginPortal() + mavenCentral() + maven { + url = "https://m2.dv8tion.net/releases" + } + + maven { + url = "https://jitpack.io" + } + + maven { + url = "https://repo.paradaux.io/releases" + } + + maven { + url = "https://m2.chew.pro/releases" + } +} + +dependencies { + + implementation 'org.postgresql:postgresql:42.2.23' + implementation 'net.dv8tion:JDA:4.3.0_300' + implementation 'pw.chew:jda-chewtils:1.20' + implementation 'org.slf4j:slf4j-api:1.7.32' + implementation 'org.slf4j:slf4j-log4j12:1.7.32' + implementation 'com.google.code.gson:gson:2.8.8' + implementation 'org.mongodb:mongo-java-driver:3.12.10' + implementation 'io.paradaux.http:HttpApi:1.1.2' + implementation 'io.ebean:ebean:12.11.3' + implementation 'com.h2database:h2:1.4.200' + implementation 'org.spongepowered:configurate-hocon:4.1.2' + + annotationProcessor 'io.ebean:querybean-generator:12.11.3' + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2' + testImplementation 'io.ebean:ebean-test:12.11.3' + + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2' +} + +test { + useJUnitPlatform() +} + +compileJava { + options.release = 11 + options.encoding('UTF-8') +} + +jar { + manifest { + attributes( + 'Main-Class': 'io.paradaux.friendlybot.FBApplication' + ) + } + + from { + configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +// Allow use of Emojis inline +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..05679dc3 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..4f906e0c --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..107acd32 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 224547fb..00000000 --- a/pom.xml +++ /dev/null @@ -1,209 +0,0 @@ - - - - - 4.0.0 - - io.paradaux - friendlybot - 1.0.0 - - - UTF-8 - 1.8 - - - - - - org.apache.maven.plugins - - maven-compiler-plugin - - 3.8.1 - - - 11 - 11 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - - shade - - - - true - - - - io.paradaux.friendlybot.FriendlyBot - - - - ${project.build.directory}/dependency-reduced-pom.xml - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.0 - - - - true - io.paradaux.friendlybot.FriendlyBot - - - - - - - - - src/main/resources - true - - - - - - src/test/resources - - - - - - - - false - - jcenter - jcenter-bintray - https://jcenter.bintray.com - - - - jitpack.io - https://jitpack.io - - - - paradaux - https://repo.paradaux.io/releases - - - - - - net.dv8tion - JDA - 4.2.0_247 - - - club.minnced - opus-java - - - jar - compile - - - - com.jagrosh - jda-utilities - 3.0.5 - pom - compile - - - - org.slf4j - slf4j-api - 1.7.30 - jar - compile - - - - org.slf4j - slf4j-log4j12 - 1.7.30 - jar - compile - - - - com.google.code.gson - gson - 2.8.6 - - - - org.junit.jupiter - junit-jupiter-api - 5.7.1 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.7.1 - test - - - - org.mongodb - mongo-java-driver - 3.12.8 - - - - io.paradaux.http - HttpApi - 1.1.1 - - - org.slf4j - slf4j-log4j12 - - - - - \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..4a4c0735 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'FriendlyBot' + diff --git a/src/main/java/io/paradaux/friendlybot/FBApplication.java b/src/main/java/io/paradaux/friendlybot/FBApplication.java new file mode 100644 index 00000000..54a28b14 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/FBApplication.java @@ -0,0 +1,42 @@ +package io.paradaux.friendlybot; + +import io.paradaux.friendlybot.bot.FBot; +import io.paradaux.friendlybot.core.data.cache.GuildCache; +import io.paradaux.friendlybot.core.data.config.FConfiguration; +import io.paradaux.friendlybot.core.data.config.FConfigurationLoader; +import io.paradaux.friendlybot.core.data.database.EBeanConnection; +import io.paradaux.friendlybot.core.locale.LocaleLogger; +import io.paradaux.friendlybot.core.locale.LocaleManager; +import org.slf4j.LoggerFactory; +import org.spongepowered.configurate.ConfigurateException; + +import javax.security.auth.login.LoginException; + +public class FBApplication { + + public static final String VERSION = "2.0"; + + private static LocaleManager localeManager; + private static LocaleLogger logger; + private static FConfiguration config; + private static FBot bot; + private static GuildCache guildCache; + private static EBeanConnection eBeanConnection; + + public static FConfiguration getConfig() { + return config; + } + + public static void main(String[] args) throws ConfigurateException, LoginException { + localeManager = new LocaleManager(); + logger = new LocaleLogger(LoggerFactory.getLogger(FBApplication.class), true); + + config = FConfigurationLoader.loadConfig(); + eBeanConnection = new EBeanConnection(config); + bot = new FBot(config); + guildCache = new GuildCache(bot.getClient()); + } + + + +} diff --git a/src/main/java/io/paradaux/friendlybot/FriendlyBot.java b/src/main/java/io/paradaux/friendlybot/FriendlyBot.java index 322be6c9..c075cebd 100644 --- a/src/main/java/io/paradaux/friendlybot/FriendlyBot.java +++ b/src/main/java/io/paradaux/friendlybot/FriendlyBot.java @@ -25,10 +25,9 @@ package io.paradaux.friendlybot; +import io.paradaux.friendlybot.core.utils.API; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; import io.paradaux.friendlybot.managers.*; -import io.paradaux.friendlybot.utils.API; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import net.dv8tion.jda.api.utils.concurrent.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +56,7 @@ public static API getApi() { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger("io.paradaux.friendlybot"); - logger.info("CSBot v1.0.0 - Maintained by Rían Errity "); + logger.info("FriendlyBot v2.0 - Maintained by Rían Errity "); logger.info("Initialising Controllers. This may take some time..."); IOManager ioManager = new IOManager(logger); @@ -66,16 +65,18 @@ public static void main(String[] args) { ConfigurationEntry config = configManager.getConfig(); MongoManager mongoManager = new MongoManager(config, logger); - PermissionManager permissionManager = new PermissionManager(logger); + GuildSettingsManager guildSettingsManager = new GuildSettingsManager(logger, mongoManager); + PermissionManager permissionManager = new PermissionManager(logger, guildSettingsManager); RoleManager roleManager = new RoleManager(logger, mongoManager); - DiscordBotManager discordBotManager = new DiscordBotManager(config, logger, permissionManager, mongoManager, roleManager); - SettingsManager settingsManager = new SettingsManager(logger, mongoManager); + UserSettingsManager settingsManager = new UserSettingsManager(logger, mongoManager); + + PunishmentManager punishmentManager = new PunishmentManager(); + DiscordBotManager discordBotManager = new DiscordBotManager(config, logger, permissionManager, mongoManager, roleManager, guildSettingsManager); TagManager tagManager = new TagManager(config, logger, mongoManager); AuditManager auditManager = new AuditManager(config, logger); MailGunManager mailGunManager = new MailGunManager(config, logger); VerificationManager verificationManager = new VerificationManager(config, logger, mongoManager, mailGunManager); - TaskManager taskManager = new TaskManager(); - + api = API.builder() .setLogger(logger) .setIoManager(ioManager) @@ -91,7 +92,5 @@ public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new Thread(() -> { logger.info("Shutting down..."); })); - - // TODO unban scheduler } } diff --git a/src/main/java/io/paradaux/friendlybot/bot/FBot.java b/src/main/java/io/paradaux/friendlybot/bot/FBot.java new file mode 100644 index 00000000..5a390c25 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/FBot.java @@ -0,0 +1,67 @@ +package io.paradaux.friendlybot.bot; + +import com.jagrosh.jdautilities.commons.waiter.EventWaiter; +import io.paradaux.friendlybot.bot.command.CommandListener; +import io.paradaux.friendlybot.bot.commands.image.*; +import io.paradaux.friendlybot.bot.commands.test.CreateUser; +import io.paradaux.friendlybot.core.data.config.FConfiguration; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.MemberCachePolicy; + +import javax.security.auth.login.LoginException; + +public class FBot { + + private final FConfiguration config; + private final EventWaiter eventWaiter; + private final CommandListener commandListener; + private final JDA client; + + public FBot(FConfiguration config) throws LoginException { + this.config = config; + this.eventWaiter = new EventWaiter(); + this.commandListener = new CommandListener(); + registerCommands(); + this.client = login(config.getBotToken()); + } + + public void registerCommands() { + commandListener.registerCommands( + new CatCommand(), + new CoinFlipCommand(), + new DogCommand(), + new EightBallCommand(), + new InspireCommand(), + new MemeCommand(), + new MonkeyCommand(), + new XKCDCommand(), + new CreateUser() + ); + } + + /** + * Creates an Instance of JDA from the provided token. + * @param token The Discord Token taken from the configuration file. + * @return JDA An Instance of JDA + * @throws LoginException When logging in proved unsuccessful. + * */ + public JDA login(String token) throws LoginException { + JDABuilder builder = JDABuilder.createDefault(token, GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_MESSAGE_REACTIONS) + .setMemberCachePolicy(MemberCachePolicy.ALL) + .enableIntents(GatewayIntent.GUILD_MEMBERS) + .setBulkDeleteSplittingEnabled(false) + .addEventListeners(eventWaiter, commandListener); + + if (token == null) { + throw new LoginException("The Configuration File does not contain a token."); + } + + return builder.build(); + } + + public JDA getClient() { + return client; + } +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/Command.java b/src/main/java/io/paradaux/friendlybot/bot/command/Command.java new file mode 100644 index 00000000..252dddf4 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/Command.java @@ -0,0 +1,14 @@ +package io.paradaux.friendlybot.bot.command; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Command { + + String name() default ""; + String description() default ""; + String permission() default ""; + String[] aliases() default {}; + +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/CommandBody.java b/src/main/java/io/paradaux/friendlybot/bot/command/CommandBody.java new file mode 100644 index 00000000..2bc430c0 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/CommandBody.java @@ -0,0 +1,91 @@ +package io.paradaux.friendlybot.bot.command; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageChannel; +import net.dv8tion.jda.api.entities.User; + +public class CommandBody { + + private final JDA jda; + + private final String command; + private final String permission; + private final String description; + + private final String[] args; + private final String[] aliases; + + private final Message message; + private final MessageChannel channel; + private final Member member; + private final User user; + + public CommandBody(Message message, String command, String permission, String description, String[] args, String[] aliases) { + this.jda = message.getJDA(); + + this.command = command; + this.permission = permission; + this.description = description; + + this.args = args; + this.aliases = aliases; + + this.message = message; + this.channel = message.getChannel(); + this.member = message.getMember(); + if (this.member == null) { + throw new IllegalStateException("Member cannot be null"); + } + this.user = member.getUser(); + } + + public String getArgStr() { + return String.join(" ", getArgs()); + } + + public boolean isArgsEmpty() { + return getArgs().length == 0; + } + + public JDA getJda() { + return jda; + } + + public String getCommand() { + return command; + } + + public String[] getArgs() { + return args; + } + + public Message getMessage() { + return message; + } + + public MessageChannel getChannel() { + return channel; + } + + public Member getMember() { + return member; + } + + public User getUser() { + return user; + } + + public String getPermission() { + return permission; + } + + public String getDescription() { + return description; + } + + public String[] getAliases() { + return aliases; + } +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/CommandListener.java b/src/main/java/io/paradaux/friendlybot/bot/command/CommandListener.java new file mode 100644 index 00000000..f2eb5200 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/CommandListener.java @@ -0,0 +1,131 @@ +package io.paradaux.friendlybot.bot.command; + +import io.paradaux.friendlybot.bot.command.exception.CommandException; +import io.paradaux.friendlybot.core.data.cache.GuildCache; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; + +public class CommandListener extends ListenerAdapter { + + private final ArrayList commands; + + public CommandListener() { + commands = new ArrayList<>(); + } + + @Override + public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { + // Get the guild + FGuild guild = GuildCache.getInstance().getGuild(event.getGuild().getId()); + + // Message stuff + Message message = event.getMessage(); + String messageContent = message.getContentRaw(); + + // If it isn't a valid command + if (!messageContent.startsWith(guild.getCommandPrefix())) { + return; + } + + // Command body + String command = messageContent.substring(guild.getCommandPrefix().length()); + String[] args = {}; + + // If there's arguments, parse them. + if (messageContent.contains(" ")) { + String[] components = command.split(" "); + args = Arrays.copyOfRange(components, 1, components.length); + command = components[0]; + } + + if (command.equalsIgnoreCase("help")) { + helpMenu(message); + return; + } + + for (DiscordCommand c : commands) { + if (c.getNames().contains(command)) { + c.execute(guild, new CommandBody(message, command, c.getPermission(), c.getDescription(), args, c.getAliases())); + break; + } + } + + } + + + /** + * Returns a list of commands as a message as a reply. + * */ + public void helpMenu(Message message) { + EmbedBuilder builder = new EmbedBuilder(); + + StringBuilder descBuilder = new StringBuilder().append("\n\n"); + for (DiscordCommand c : commands) { + descBuilder.append("\\➡ **").append(c.getCommand()).append("**").append(" » ").append(c.getDescription()); + } + + descBuilder.append("\n\n"); + + builder.setAuthor("**FriendlyBot**: Commands"); + builder.setDescription(descBuilder); + builder.setTimestamp(Instant.now()); + builder.setFooter("N.B: Some commands may be role-locked."); + + message.getChannel().sendMessageEmbeds(builder.build()).queue(); + } + + + /** + * Registers the requested command. + * */ + public void registerCommand(DiscordCommand command) { + if (command.isRegistered()) { + throw new CommandException("Command is already marked as registered."); + } + + Class clazz = command.getClass(); + if (!clazz.isAnnotationPresent(Command.class)) { + throw new CommandException("Provided Argument is not a valid command. Not annotated as command."); + } + + Command cmd = clazz.getAnnotation(Command.class); + + command.register(cmd.name(), cmd.description(), cmd.permission(), cmd.aliases()); + + for (DiscordCommand c : commands) { + if (c.getCommand().equals(command.getCommand())) { + throw new CommandException("A command by this name has already been registered."); + } + } + + commands.add(command); + } + + /** + * Register a list of commands. + * */ + public void registerCommands(DiscordCommand... commands) { + for (DiscordCommand command : commands) { + registerCommand(command); + } + } + + + /** + * Unregisters the requested command. + * @throws CommandException If the provided command has not been registered. + * */ + public void removeCommand(DiscordCommand command) { + if (!commands.remove(command)) { + throw new CommandException("This command is not registered."); + } + } +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/DiscordCommand.java b/src/main/java/io/paradaux/friendlybot/bot/command/DiscordCommand.java new file mode 100644 index 00000000..bb852084 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/DiscordCommand.java @@ -0,0 +1,154 @@ +package io.paradaux.friendlybot.bot.command; + +import io.paradaux.friendlybot.FBApplication; +import io.paradaux.friendlybot.core.data.config.FConfiguration; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.models.enums.EmbedColour; +import io.paradaux.friendlybot.core.utils.models.exceptions.NoSuchUserException; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +@Command(name = "undefined", description = "undefined", permission = "undefined") +public abstract class DiscordCommand { + + private final Logger logger = LoggerFactory.getLogger(DiscordCommand.class); + + private boolean isRegistered; + private String command; + private String description; + private String permission; + private String[] aliases; + + private List names; + + public abstract void execute(FGuild guild, CommandBody body); + + public void register(String command, String description, String permission, String[] aliases) { + isRegistered = true; + this.command = command; + this.description = description; + this.permission = permission; + this.aliases = aliases; + this.names = new ArrayList<>(); + names.addAll(List.of(aliases)); + names.add(command); + } + + public void syntaxError(Message message) { + message.addReaction("\uD83D\uDEAB").queue(); + EmbedBuilder builder = new EmbedBuilder(); + + builder.setColor(EmbedColour.ISSUE.getColour()); + builder.setAuthor(message.getAuthor().getAsTag(), null, message.getAuthor().getAvatarUrl()); + builder.setDescription("There was an error in your syntax."); + builder.setFooter("FriendlyBot v" + FBApplication.VERSION); + + message.getChannel().sendMessageEmbeds(builder.build()).queue(); + } + + /** + * Used for commands which take a user as a parameter. Tries three ways of parsing the user. The first being by an @mention, the second + * by a tag (Username#Discriminator) then finally via their discord id. Returns the user object if found, otherwise null. + * */ + @CheckReturnValue + @Nullable + public User parseTarget(Message message, String userInput) throws NoSuchUserException { + try { + if (message.getMentionedMembers().size() == 1) { + return message.getMentionedMembers().get(0).getUser(); + } + + User user; + try { + user = message.getGuild().getJDA().getUserByTag(userInput); + } catch (IllegalArgumentException ex) { + user = message.getJDA().retrieveUserById(userInput).submit().get(); + } + + return user; + } catch (InterruptedException | ExecutionException | NumberFormatException exception) { + throw new NoSuchUserException(exception.getMessage()); + } + } + + /** + * Gets a message by guild and user id. + * */ + @CheckReturnValue + @Nullable + public Member retrieveMember(Guild guild, String userId) { + try { + return guild.retrieveMemberById(userId) + .submit() + .get(); + } catch (InterruptedException | ExecutionException e) { + logger.error("Interrupted Exception", e); + } + + return null; + } + + /** + * Gets a message by guild and User. + * */ + @CheckReturnValue + @Nullable + public Member retrieveMember(Guild guild, User user) { + try { + return guild.retrieveMember(user) + .submit() + .get(); + } catch (InterruptedException | ExecutionException e) { + logger.error("Interrupted Exception", e); + } + + return null; + } + + public FConfiguration getConfig() { + return FBApplication.getConfig(); + } + + public void unregister() { + isRegistered = false; + } + + public boolean isRegistered() { + return isRegistered; + } + + public String getCommand() { + return command; + } + + public String getDescription() { + return description; + } + + public Logger getLogger() { + return logger; + } + + public String getPermission() { + return permission; + } + + public String[] getAliases() { + return aliases; + } + + public List getNames() { + return names; + } +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/PermissionHandler.java b/src/main/java/io/paradaux/friendlybot/bot/command/PermissionHandler.java new file mode 100644 index 00000000..7b310f72 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/PermissionHandler.java @@ -0,0 +1,4 @@ +package io.paradaux.friendlybot.bot.command; + +public class PermissionHandler { +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/command/exception/CommandException.java b/src/main/java/io/paradaux/friendlybot/bot/command/exception/CommandException.java new file mode 100644 index 00000000..742f3423 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/command/exception/CommandException.java @@ -0,0 +1,23 @@ +package io.paradaux.friendlybot.bot.command.exception; + +public class CommandException extends RuntimeException { + + public CommandException() { + } + + public CommandException(String message) { + super(message); + } + + public CommandException(String message, Throwable cause) { + super(message, cause); + } + + public CommandException(Throwable cause) { + super(cause); + } + + public CommandException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/io/paradaux/friendlybot/bot/commands/image/CatCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/CatCommand.java new file mode 100644 index 00000000..5c30cc9f --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/CatCommand.java @@ -0,0 +1,40 @@ +package io.paradaux.friendlybot.bot.commands.image; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.http.HttpApi; +import net.dv8tion.jda.api.EmbedBuilder; +import org.json.JSONArray; + +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.concurrent.CompletableFuture; + +@Command(name="cat", description = "Get yourself a cute cat photo!", permission = "command.cat", aliases = {"feline", "kitten"}) +public class CatCommand extends DiscordCommand { + + private static final String CAT_API = "https://api.thecatapi.com/v1/images/search"; + + public void execute(FGuild guild, CommandBody body) { + HttpApi http = new HttpApi(getLogger()); + HttpRequest request = http.plainRequest(CAT_API); + + CompletableFuture> responseFtr = http.sendAsync(request, HttpResponse.BodyHandlers.ofString()); + + if (responseFtr == null) { + throw new IllegalStateException("Cat: Response was null"); + } + + responseFtr.thenAccept((response) -> { + EmbedBuilder builder = new EmbedBuilder() + .setImage(new JSONArray(response.body()).getJSONObject(0).getString("url")) + .setColor(NumberUtils.randomColor()) + .setFooter("For " + body.getUser().getName()); + + body.getMessage().getChannel().sendMessageEmbeds(builder.build()).queue(); + }).join(); + } +} diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/CoinFlipCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/CoinFlipCommand.java similarity index 56% rename from src/main/java/io/paradaux/friendlybot/commands/fun/CoinFlipCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/CoinFlipCommand.java index 53211933..eaa3ee2f 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/CoinFlipCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/CoinFlipCommand.java @@ -1,33 +1,25 @@ -package io.paradaux.friendlybot.commands.fun; - -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.RandomUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +package io.paradaux.friendlybot.bot.commands.image; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.friendlybot.core.utils.RandomUtils; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; -import org.slf4j.Logger; import java.util.concurrent.TimeUnit; -public class CoinFlipCommand extends BaseCommand { +@Command(name = "coinflip", description = "Provides a heads/tails result on a €2 coin", permission = "command.coinflip", + aliases = {"flip", "cf", "flipcoin"}) +public class CoinFlipCommand extends DiscordCommand { private static final String COIN_FLIP_GIF = "https://media1.tenor.com/images/49dc6597439a635b1614544d8e090c54/tenor.gif"; private static final String[] TAILS_HEADS_IMAGES = {"https://cdn.paradaux.io/img/jurx4.png", "https://cdn.paradaux.io/img/ofco7.png"}; - public CoinFlipCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "coinflip"; - this.help = "Flips a coin"; - this.aliases = new String[]{"flip", "cf", "flipcoin"}; - } - @Override - protected void execute(CommandEvent event) { - Message message = event.getMessage(); - + public void execute(FGuild guild, CommandBody body) { int result = new RandomUtils().pickRandomNumber(0, 1); MessageEmbed waitingEmbed = new EmbedBuilder() @@ -42,10 +34,10 @@ protected void execute(CommandEvent event) { .setImage(TAILS_HEADS_IMAGES[result]) .build(); - event.getChannel().sendMessage(waitingEmbed).queue((sentMessage) -> { + body.getChannel().sendMessageEmbeds(waitingEmbed).queue((sentMessage) -> { try { TimeUnit.MILLISECONDS.sleep(1200); - sentMessage.editMessage(resultEmbed).queue(); + sentMessage.editMessageEmbeds(resultEmbed).queue(); } catch (InterruptedException e) { getLogger().error("Interrupted whilst shaking the magic eight ball.."); } diff --git a/src/main/java/io/paradaux/friendlybot/bot/commands/image/DogCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/DogCommand.java new file mode 100644 index 00000000..8cee5ee0 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/DogCommand.java @@ -0,0 +1,38 @@ +package io.paradaux.friendlybot.bot.commands.image; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.http.HttpApi; +import net.dv8tion.jda.api.EmbedBuilder; +import org.json.JSONObject; + +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +@Command(name = "dog", description = "Get yourself a cute doggo pic!", permission = "command.dog", aliases = {"pupper", + "puppers", "pup", "doggo", "doggos"}) +public class DogCommand extends DiscordCommand { + + private static final String DOG_API = "https://dog.ceo/api/breeds/image/random"; + + @Override + public void execute(FGuild guild, CommandBody body) { + + HttpApi http = new HttpApi(getLogger()); + HttpRequest request = http.plainRequest(DOG_API); + + http.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept((response) -> { + EmbedBuilder builder = new EmbedBuilder() + .setImage(new JSONObject(response.body()).getString("message")) + .setColor(NumberUtils.randomColor()) + .setFooter("For " + body.getUser().getName()); + + body.getMessage().getChannel().sendMessageEmbeds(builder.build()).queue(); + }).join(); + + } + +} diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/EightBallCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/EightBallCommand.java similarity index 74% rename from src/main/java/io/paradaux/friendlybot/commands/fun/EightBallCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/EightBallCommand.java index 6dc49a07..b21b8147 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/EightBallCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/EightBallCommand.java @@ -23,43 +23,39 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; +package io.paradaux.friendlybot.bot.commands.image; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.stream.JsonReader; -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.RandomUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.friendlybot.core.utils.RandomUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; -import org.slf4j.Logger; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Random; import java.util.concurrent.TimeUnit; -public class EightBallCommand extends BaseCommand { +@Command(name = "eightball", description = "Asks the all knowing 8ball", permission = "command.eightball", aliases = {"8b", "8ball"}) +public class EightBallCommand extends DiscordCommand { private static final String WAITING_IMAGE = "https://i.imgur.com/nBRPBMf.gif"; - private final JsonObject eightBallResponses; + private static final JsonObject eightBallResponses; - public EightBallCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "eightball"; - this.help = "Asks the all knowing 8ball"; - this.aliases = new String[]{"8b", "8ball"}; - - InputStream rawResponseData = getClass().getResourceAsStream("/data/8ball.json"); + static { + InputStream rawResponseData = EightBallCommand.class.getResourceAsStream("/data/8ball.json"); JsonReader reader = new JsonReader(new InputStreamReader(rawResponseData)); - this.eightBallResponses = new Gson().fromJson(reader, JsonObject.class); + eightBallResponses = new Gson().fromJson(reader, JsonObject.class); if (eightBallResponses == null) { throw new RuntimeException("Eight ball responses not found."); @@ -67,11 +63,11 @@ public EightBallCommand(ConfigurationEntry config, Logger logger) { } @Override - protected void execute(CommandEvent event) { - Message message = event.getMessage(); + public void execute(FGuild guild, CommandBody body) { + Message message = body.getMessage(); - if (event.getArgs().isEmpty()) { - respondSyntaxError(message, ";8ball "); + if (body.getArgs().length == 0) { + syntaxError(message); } RandomUtils rUtils = new RandomUtils(new Random()); @@ -121,6 +117,10 @@ protected void execute(CommandEvent event) { color = 0xFF0000; break; } + + default: { + throw new IllegalStateException("Invalid 8ball responses file."); + } } MessageEmbed responseEmbed = new EmbedBuilder() @@ -128,10 +128,10 @@ protected void execute(CommandEvent event) { .setTitle(response) .build(); - event.getChannel().sendMessage(waitingEmbed).queue((sentMessage) -> { + body.getChannel().sendMessageEmbeds(waitingEmbed).queue((sentMessage) -> { try { TimeUnit.SECONDS.sleep(4); - sentMessage.editMessage(responseEmbed).queue(); + sentMessage.editMessageEmbeds(responseEmbed).queue(); } catch (InterruptedException e) { getLogger().error("Interrupted whilst shaking the magic eight ball.."); } diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/InspireCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/InspireCommand.java similarity index 69% rename from src/main/java/io/paradaux/friendlybot/commands/fun/InspireCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/InspireCommand.java index 16c43e94..7924a2b7 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/InspireCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/InspireCommand.java @@ -23,32 +23,27 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; +package io.paradaux.friendlybot.bot.commands.image; -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; import io.paradaux.http.HttpApi; import net.dv8tion.jda.api.EmbedBuilder; -import org.slf4j.Logger; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -public class InspireCommand extends BaseCommand { +@Command(name = "inspire", description = "Sends some heartwarming inspirational quotes!", permission = "command.inspire", + aliases = {"inspireme", "im"}) +public class InspireCommand extends DiscordCommand { private static final String INSPIRE_API = "https://inspirobot.me/api?generate=true"; - public InspireCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "inspire"; - this.aliases = new String[]{"inspireme", "im"}; - this.help = "Sends some heartwarming inspirational quotes!."; - } - @Override - protected void execute(CommandEvent event) { + public void execute(FGuild guild, CommandBody body) { HttpApi http = new HttpApi(getLogger()); HttpRequest request = http.plainRequest(INSPIRE_API); @@ -57,9 +52,9 @@ protected void execute(CommandEvent event) { EmbedBuilder builder = new EmbedBuilder() .setImage(response.body()) .setColor(NumberUtils.randomColor()) - .setFooter("For " + event.getAuthor().getName()); + .setFooter("For " + body.getUser().getName()); - event.getMessage().getChannel().sendMessage(builder.build()).queue(); + body.getChannel().sendMessageEmbeds(builder.build()).queue(); }).join(); } diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/MemeCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/MemeCommand.java similarity index 78% rename from src/main/java/io/paradaux/friendlybot/commands/fun/MemeCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/MemeCommand.java index c1fb5ff5..b47227e5 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/MemeCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/MemeCommand.java @@ -23,14 +23,15 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; - -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.HttpUtils; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.exceptions.VerificationException; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +package io.paradaux.friendlybot.bot.commands.image; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.HttpUtils; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.friendlybot.core.utils.models.exceptions.VerificationException; import io.paradaux.http.HttpApi; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; @@ -41,7 +42,6 @@ import okhttp3.RequestBody; import org.json.JSONArray; import org.json.JSONObject; -import org.slf4j.Logger; import java.io.IOException; import java.io.Reader; @@ -51,24 +51,17 @@ import java.util.Collections; import java.util.List; -public class MemeCommand extends BaseCommand { +@Command(name = "meme", description = "Meme generation!", permission = "command.meme", aliases = {"m"}) +public class MemeCommand extends DiscordCommand { private static final String GET_MEMES_API = "https://api.imgflip.com/get_memes"; public static final String CAPTION_MEMES_API = "https://api.imgflip.com/caption_image"; - public MemeCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "meme"; - this.aliases = new String[]{"m"}; - this.help = "Meme generation!"; - } - @Override - protected void execute(CommandEvent event) { - String[] args = getArgs(event.getArgs()); - Message message = event.getMessage(); + public void execute(FGuild guild, CommandBody body) { + Message message = body.getMessage(); - switch (args[0]) { + switch (body.getArgs()[0]) { case "images": { message.reply("I'm sending you a list of available images in your DMs...").queue(); @@ -96,9 +89,9 @@ protected void execute(CommandEvent event) { + "](" + meme.getString("url") + ")", false); } - event.getAuthor().openPrivateChannel().queue((channel) -> { + body.getUser().openPrivateChannel().queue((channel) -> { for (final var embed : embeds) { - channel.sendMessage(embed).queue(); + channel.sendMessageEmbeds(embed).queue(); } }); }).join(); @@ -106,15 +99,15 @@ protected void execute(CommandEvent event) { } case "caption": { - if (args.length < 5) { - respondSyntaxError(message, ";meme caption | "); + if (body.getArgs().length < 5) { + syntaxError(message); return; } - String id = args[1]; + String id = body.getArgs()[1]; List args2 = new ArrayList<>(); - Collections.addAll(args2, args); + Collections.addAll(args2, body.getArgs()); args2.remove(0); args2.remove(0); @@ -139,11 +132,11 @@ protected void execute(CommandEvent event) { bodyBuilder.addFormDataPart("text" + i, lines[i]); } - RequestBody body = bodyBuilder.build(); + RequestBody reqBody = bodyBuilder.build(); Request request = new Request.Builder() .url(CAPTION_MEMES_API) - .method("POST", body) + .method("POST", reqBody) .build(); HttpUtils.sendAsync(client, request).thenAccept((response -> { @@ -163,9 +156,9 @@ protected void execute(CommandEvent event) { EmbedBuilder builder = new EmbedBuilder() .setImage(responseJson.getJSONObject("data").getString("url")) .setColor(NumberUtils.randomColor()) - .setFooter("For " + event.getAuthor().getName()); + .setFooter("For " + body.getUser().getName()); - event.getChannel().sendMessage(builder.build()).queue(); + body.getChannel().sendMessage(builder.build()).queue(); } catch (IOException ok) { getLogger().error("Error occurred whilst interacting with mailgun."); @@ -177,7 +170,7 @@ protected void execute(CommandEvent event) { } default: { - respondSyntaxError(message, ";meme <| separated text blocks>"); + syntaxError(message); break; } diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/MonkeyCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/MonkeyCommand.java similarity index 61% rename from src/main/java/io/paradaux/friendlybot/commands/fun/MonkeyCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/MonkeyCommand.java index 5a796f2d..2ca524e4 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/MonkeyCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/MonkeyCommand.java @@ -1,31 +1,25 @@ -package io.paradaux.friendlybot.commands.fun; +package io.paradaux.friendlybot.bot.commands.image; -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; import io.paradaux.http.HttpApi; import net.dv8tion.jda.api.EmbedBuilder; import org.json.JSONObject; -import org.slf4j.Logger; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -public class MonkeyCommand extends BaseCommand { +@Command(name = "monkey", description = "Get a monkey image !", permission = "command.monkey") +public class MonkeyCommand extends DiscordCommand { private static final String MONKEY_API = "https://www.placemonkeys.com/500/350?random"; private static final String IMGUR_API = "https://api.imgur.com/3/upload/"; - public MonkeyCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "monkey"; - this.aliases = new String[0]; - this.help = "Get a monkey image !"; - } - @Override - protected void execute(CommandEvent event) { + public void execute(FGuild guild, CommandBody body) { HttpApi http = new HttpApi(getLogger()); @@ -42,9 +36,9 @@ protected void execute(CommandEvent event) { EmbedBuilder builder = new EmbedBuilder() .setColor(NumberUtils.randomColor()) .setImage(imgurMeta.getJSONObject("data").getString("link")) - .setFooter("For " + event.getAuthor().getName()); + .setFooter("For " + body.getUser().getName()); - event.getChannel().sendMessage(builder.build()).queue(); + body.getChannel().sendMessageEmbeds(builder.build()).queue(); }).join(); } diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/XKCDCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/image/XKCDCommand.java similarity index 79% rename from src/main/java/io/paradaux/friendlybot/commands/fun/XKCDCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/image/XKCDCommand.java index 02fa9cba..fc8a0e02 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/XKCDCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/image/XKCDCommand.java @@ -23,47 +23,42 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; +package io.paradaux.friendlybot.bot.commands.image; -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; import io.paradaux.http.HttpApi; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.json.JSONObject; -import org.slf4j.Logger; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -public class XKCDCommand extends BaseCommand { +@Command(name = "xkcd", description = "Links to the specified xkcd", permission = "command.xkcd") +public class XKCDCommand extends DiscordCommand { private static final String XKCD_SEARCH_API = "https://relevantxkcd.appspot.com/process?action=xkcd&query=%s"; private static final String XKCD_INFO_API = "https://xkcd.com/%s/info.0.json"; private static final String XKCD_PAGE_FORMAT = "https://xkcd.com/%s/"; private static final String XKCD_ICON = "https://webcomicshub.com/uploads/webcomics/xkcd-1280x1024.png"; - public XKCDCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "xkcd"; - this.help = "Links to the specified xkcd"; - } - @Override - protected void execute(CommandEvent event) { - Message message = event.getMessage(); - String args = event.getArgs(); + public void execute(FGuild guild, CommandBody body) { + Message message = body.getMessage(); + String[] args = body.getArgs(); - if (args == null || args.isEmpty()) { - respondSyntaxError(message, ";xkcd "); + if (args == null || args.length == 0) { + syntaxError(message); return; } HttpApi http = new HttpApi(getLogger()); - HttpRequest request = http.plainRequest(String.format(XKCD_SEARCH_API, args.replace(" ", "%20"))); + HttpRequest request = http.plainRequest(String.format(XKCD_SEARCH_API, String.join("%20", args))); http.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenAccept((response) -> { String returnedId = response.body().split(" ")[2].replaceAll("\n",""); diff --git a/src/main/java/io/paradaux/friendlybot/bot/commands/joke/CharmanderCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/CharmanderCommand.java new file mode 100644 index 00000000..21a54c2a --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/CharmanderCommand.java @@ -0,0 +1,39 @@ +package io.paradaux.friendlybot.bot.commands.joke; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.friendlybot.core.utils.RandomUtils; +import net.dv8tion.jda.api.EmbedBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Command(name = "charmander", description = "Cute charmander pics!", permission = "command.charmander", aliases = {"charm"}) +public class CharmanderCommand extends DiscordCommand { + + private static final String CHARMANDER_API = "https://cdn.paradaux.io/static/charmander/"; + private static final int CHARMANDER_COUNT = 38; + private static final List GIFS = new ArrayList<>(); + private final RandomUtils random = new RandomUtils(); + + static { + Collections.addAll(GIFS, 26); + } + + @Override + public void execute(FGuild guild, CommandBody body) { + int id = random.pickRandomNumber(1, CHARMANDER_COUNT); + + EmbedBuilder builder = new EmbedBuilder() + .setImage(CHARMANDER_API + id + (GIFS.contains(id) ? ".gif" : ".jpg")) + .setColor(NumberUtils.randomColor()) + .setFooter("For " + body.getUser().getName() + " Charmander ID: " + id); + + body.getMessage().getChannel().sendMessageEmbeds(builder.build()).queue(); + } + +} diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/LmgtfyCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/LmgtfyCommand.java similarity index 72% rename from src/main/java/io/paradaux/friendlybot/commands/fun/LmgtfyCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/joke/LmgtfyCommand.java index 052095d7..4610c58e 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/LmgtfyCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/LmgtfyCommand.java @@ -23,32 +23,27 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; +package io.paradaux.friendlybot.bot.commands.joke; -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; -import org.slf4j.Logger; -public class LmgtfyCommand extends BaseCommand { +@Command(name = "lmgtfy", description = "Let me lmgtfy for you...", permission = "command.lmgtfy") +public class LmgtfyCommand extends DiscordCommand { private static final String LMGTFY_LINK = "https://lmgtfy.com/?q="; - public LmgtfyCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "lmgtfy"; - this.help = "Let me lmgtfy for you..."; - } - @Override - protected void execute(CommandEvent event) { - Message message = event.getMessage(); - String query = event.getArgs(); + public void execute(FGuild guild, CommandBody body) { + Message message = body.getMessage(); + String query = String.join(" ", body.getArgs()); if (query.isEmpty()) { - respondSyntaxError(message, ";lmgtfy "); + syntaxError(message); return; } diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/MonkeCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/MonkeCommand.java similarity index 65% rename from src/main/java/io/paradaux/friendlybot/commands/fun/MonkeCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/joke/MonkeCommand.java index 51381cc6..269b8347 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/MonkeCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/MonkeCommand.java @@ -1,11 +1,13 @@ -package io.paradaux.friendlybot.commands.fun; - -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.HttpUtils; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.RandomUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +package io.paradaux.friendlybot.bot.commands.joke; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.bot.commands.image.MemeCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.HttpUtils; +import io.paradaux.friendlybot.core.utils.NumberUtils; +import io.paradaux.friendlybot.core.utils.RandomUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; import okhttp3.MultipartBody; @@ -13,14 +15,14 @@ import okhttp3.Request; import okhttp3.RequestBody; import org.json.JSONObject; -import org.slf4j.Logger; import java.io.IOException; import java.io.Reader; import java.util.Collections; import java.util.HashSet; -public class MonkeCommand extends BaseCommand { +@Command(name = "monke", description = "MONKE.", permission = "command.monke", aliases = {}) +public class MonkeCommand extends DiscordCommand { private static final HashSet MONKE_IDS = new HashSet<>(); @@ -28,15 +30,8 @@ public class MonkeCommand extends BaseCommand { Collections.addAll(MONKE_IDS, "289081819", "200213111"); } - public MonkeCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "monke"; - this.aliases = new String[]{"MONKE"}; - this.help = "MONKE."; - } - @Override - protected void execute(CommandEvent event) { + public void execute(FGuild guild, CommandBody body) { OkHttpClient client = new OkHttpClient().newBuilder() .build(); @@ -45,20 +40,20 @@ protected void execute(CommandEvent event) { .addFormDataPart("username", getConfig().getImgflipUsername()) .addFormDataPart("password", getConfig().getImgflipPassword()); - String[] lines = event.getArgs().split("\\|"); + String[] lines = String.join(" ", body.getArgs()).split("\\|"); if (lines.length != 2) { - respondSyntaxError(event.getMessage(), ";monke this is line one | this is line 2"); + syntaxError(body.getMessage()); } bodyBuilder.addFormDataPart("text0", lines[0]); bodyBuilder.addFormDataPart("text1", lines[1]); - RequestBody body = bodyBuilder.build(); + RequestBody reqBody = bodyBuilder.build(); Request request = new Request.Builder() .url(MemeCommand.CAPTION_MEMES_API) - .method("POST", body) + .method("POST", reqBody) .build(); HttpUtils.sendAsync(client, request).thenAccept((response -> { @@ -75,9 +70,9 @@ protected void execute(CommandEvent event) { JSONObject responseJson = new JSONObject(strBuilder.toString()); - MessageEmbed embed = new EmbedBuilder().setImage(responseJson.getJSONObject("data").getString("url")).setColor(NumberUtils.randomColor()).setFooter("For " + event.getAuthor().getName()).build(); + MessageEmbed embed = new EmbedBuilder().setImage(responseJson.getJSONObject("data").getString("url")).setColor(NumberUtils.randomColor()).setFooter("For " + body.getUser().getName()).build(); - event.getChannel().sendMessage(embed).queue(); + body.getChannel().sendMessage(embed).queue(); } catch (IOException ok) { getLogger().error("Error occurred whilst interacting with Imgflip"); diff --git a/src/main/java/io/paradaux/friendlybot/commands/fun/YodaifyCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/YodaifyCommand.java similarity index 75% rename from src/main/java/io/paradaux/friendlybot/commands/fun/YodaifyCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/joke/YodaifyCommand.java index bf47fcb9..0e0cf496 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/fun/YodaifyCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/joke/YodaifyCommand.java @@ -23,13 +23,15 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.fun; - -import com.jagrosh.jdautilities.command.CommandEvent; -import io.paradaux.friendlybot.utils.HttpUtils; -import io.paradaux.friendlybot.utils.NumberUtils; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.BaseCommand; +package io.paradaux.friendlybot.bot.commands.joke; + +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.bot.command.CommandBody; +import io.paradaux.friendlybot.bot.command.DiscordCommand; +import io.paradaux.friendlybot.bot.commands.image.MemeCommand; +import io.paradaux.friendlybot.core.data.database.models.FGuild; +import io.paradaux.friendlybot.core.utils.HttpUtils; +import io.paradaux.friendlybot.core.utils.NumberUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; @@ -38,32 +40,25 @@ import okhttp3.Request; import okhttp3.RequestBody; import org.json.JSONObject; -import org.slf4j.Logger; import java.io.IOException; import java.io.Reader; -public class YodaifyCommand extends BaseCommand { +@Command(name = "yodaify", description = "Convert english into Yoga's Language!", permission = "command.yodaify", aliases = {"yoda", "yodify"}) +public class YodaifyCommand extends DiscordCommand { private static final String YODA_IMAGE_ID = "14371066"; - public YodaifyCommand(ConfigurationEntry config, Logger logger) { - super(config, logger); - this.name = "yodaify"; - this.aliases = new String[]{"yoda", "yodify"}; - this.help = "Convert english into Yoga's Language!"; - } - @Override - protected void execute(CommandEvent event) { - Message message = event.getMessage(); + public void execute(FGuild guild, CommandBody body) { + Message message = body.getMessage(); - if (event.getArgs().isEmpty()) { - respondSyntaxError(message, ";yoda "); + if (body.getArgs().length == 0) { + syntaxError(message); return; } - String[] tokenisedSentence = event.getArgs().split("\\. *"); + String[] tokenisedSentence = String.join(" ", body.getArgs()).split("\\. *"); StringBuilder builder = new StringBuilder(); @@ -86,11 +81,11 @@ protected void execute(CommandEvent event) { bodyBuilder.addFormDataPart("text0", builder.toString()); - RequestBody body = bodyBuilder.build(); + RequestBody reqBody = bodyBuilder.build(); Request request = new Request.Builder() .url(MemeCommand.CAPTION_MEMES_API) - .method("POST", body) + .method("POST", reqBody) .build(); HttpUtils.sendAsync(client, request).thenAccept((response -> { @@ -110,10 +105,10 @@ protected void execute(CommandEvent event) { MessageEmbed embed = new EmbedBuilder() .setImage(responseJson.getJSONObject("data").getString("url")) .setColor(NumberUtils.randomColor()) - .setFooter("For " + event.getAuthor().getName()) + .setFooter("For " + body.getUser().getName()) .build(); - event.getChannel().sendMessage(embed).queue(); + body.getChannel().sendMessage(embed).queue(); } catch (IOException ok) { getLogger().error("Error occurred whilst interacting with Imgflip"); diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/AnnouncementCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/AnnouncementCommand.java similarity index 92% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/AnnouncementCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/AnnouncementCommand.java index 297a32cd..ac98f159 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/AnnouncementCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/AnnouncementCommand.java @@ -1,10 +1,11 @@ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; import com.jagrosh.jdautilities.commons.waiter.EventWaiter; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @@ -12,6 +13,7 @@ import java.util.regex.Pattern; +@Command(name = "", description = "", permission = "", aliases = {}) public class AnnouncementCommand extends PrivilegedCommand { private static final Pattern URL_PATTERN = Pattern.compile("^(http://|https://)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?"); @@ -26,6 +28,11 @@ public AnnouncementCommand(ConfigurationEntry config, Logger logger, PermissionM @Override protected void execute(CommandEvent event) { + + if (!isStaff(event.getGuild(), event.getAuthor().getId())) { + return; + } + event.reply("Beginning to build an announcement."); EmbedBuilder builder = new EmbedBuilder(); diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/BanCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/BanCommand.java similarity index 64% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/BanCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/BanCommand.java index a33d129f..7cba62bc 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/BanCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/BanCommand.java @@ -23,20 +23,18 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; import io.paradaux.friendlybot.FriendlyBot; -import io.paradaux.friendlybot.managers.AuditManager; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.MongoManager; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.embeds.moderation.BannedEmbed; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.database.BanEntry; -import io.paradaux.friendlybot.utils.models.types.ModerationAction; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; +import io.paradaux.friendlybot.managers.PunishmentManager; +import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.User; import org.slf4j.Logger; /** @@ -48,12 +46,16 @@ * @see FriendlyBot * */ +@Command(name = "", description = "", permission = "", aliases = {}) public class BanCommand extends PrivilegedCommand { + private final PunishmentManager punishments; + public BanCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { super(config, logger, permissionManager); this.name = "ban"; this.help = "Bans the specified user"; + this.punishments = PunishmentManager.getInstance(); } @Override @@ -64,7 +66,7 @@ protected void execute(CommandEvent event) { String[] args = getArgs(event.getArgs()); String authorID = event.getAuthor().getId(); - if (!isStaff(authorID)) { + if (!isStaff(event.getGuild(), authorID)) { respondNoPermission(message, "[Moderator, Administrator]"); return; } @@ -74,41 +76,18 @@ protected void execute(CommandEvent event) { return; } - User target = parseTarget(message, args[0]); + Member target = retrieveMember(event.getGuild(), args[0]); if (target == null) { message.getChannel().sendMessage("You did not specify a (valid) target.").queue(); return; } - if (isStaff(target.getId())) { + if (isStaff(event.getGuild(), target.getId())) { message.getChannel().sendMessage("You cannot ban a staff member.").queue(); return; } - String incidentID = mongo.getNextIncidentID(); - String reason = parseSentance(1, args); - - BanEntry entry = new BanEntry() - .setIncidentID(incidentID) - .setReason(reason) - .setStaffID(authorID) - .setStaffTag(event.getAuthor().getAsTag()) - .setUserID(target.getId()) - .setUserTag(target.getAsTag()); - - mongo.addBanEntry(entry); - AuditManager.getInstance().log(ModerationAction.BAN, target, - event.getAuthor(), reason, incidentID); - - message.getChannel().sendMessage("Incident ID: " + incidentID - + "\nReason: " + reason).queue(); - - BannedEmbed embed = new BannedEmbed(reason, incidentID); - target.openPrivateChannel().queue((channel) -> channel.sendMessage(embed.getEmbed()) - .queue()); - - message.getGuild().ban(target, 0).queue(); - + punishments.banUser(event.getGuild(), target, event.getMember(), event.getTextChannel(), parseSentance(1, args)); } } diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/PruneCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/PruneCommand.java similarity index 87% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/PruneCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/PruneCommand.java index 28455070..bf0d897e 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/PruneCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/PruneCommand.java @@ -23,15 +23,17 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.entities.Message; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class PruneCommand extends PrivilegedCommand { public PruneCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { @@ -48,7 +50,7 @@ protected void execute(CommandEvent event) { String[] args = getArgs(event.getArgs()); String authorID = event.getAuthor().getId(); - if (!isStaff(authorID)) { + if (!isStaff(event.getGuild(), authorID)) { respondNoPermission(message, "[Moderator, Administrator]"); return; } diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/SayCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SayCommand.java similarity index 83% rename from src/main/java/io/paradaux/friendlybot/commands/staff/technician/SayCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SayCommand.java index c99fec79..2575a6e0 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/SayCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SayCommand.java @@ -23,14 +23,16 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.technician; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class SayCommand extends PrivilegedCommand { public SayCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/SendEmbedCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SendEmbedCommand.java similarity index 83% rename from src/main/java/io/paradaux/friendlybot/commands/staff/technician/SendEmbedCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SendEmbedCommand.java index 4996a3ad..49119f3a 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/SendEmbedCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/SendEmbedCommand.java @@ -23,25 +23,27 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.technician; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.embeds.AuditLogEmbed; +import io.paradaux.friendlybot.core.utils.embeds.PoliticsRulesEmbed; +import io.paradaux.friendlybot.core.utils.embeds.RulesEmbed; +import io.paradaux.friendlybot.core.utils.embeds.moderation.*; +import io.paradaux.friendlybot.core.utils.embeds.modmail.ModMailSentEmbed; +import io.paradaux.friendlybot.core.utils.embeds.notices.*; +import io.paradaux.friendlybot.core.utils.embeds.roleselection.PoliticsOptionEmbed; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.interfaces.Embed; +import io.paradaux.friendlybot.core.utils.models.types.ModerationAction; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.embeds.AuditLogEmbed; -import io.paradaux.friendlybot.utils.embeds.PoliticsRulesEmbed; -import io.paradaux.friendlybot.utils.embeds.RulesEmbed; -import io.paradaux.friendlybot.utils.embeds.moderation.*; -import io.paradaux.friendlybot.utils.embeds.modmail.ModMailSentEmbed; -import io.paradaux.friendlybot.utils.embeds.notices.*; -import io.paradaux.friendlybot.utils.embeds.roleselection.PoliticsOptionEmbed; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.interfaces.Embed; -import io.paradaux.friendlybot.utils.models.types.ModerationAction; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.TextChannel; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class SendEmbedCommand extends PrivilegedCommand { public SendEmbedCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/VerificationCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/VerificationCommand.java similarity index 92% rename from src/main/java/io/paradaux/friendlybot/commands/staff/technician/VerificationCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/VerificationCommand.java index b95400b8..dcfe6454 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/VerificationCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/admin/VerificationCommand.java @@ -23,19 +23,21 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.technician; +package io.paradaux.friendlybot.bot.commands.staff.admin; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.exceptions.VerificationException; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.MongoManager; import io.paradaux.friendlybot.managers.PermissionManager; import io.paradaux.friendlybot.managers.VerificationManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.exceptions.VerificationException; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.User; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class VerificationCommand extends PrivilegedCommand { public VerificationCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/CiteCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/CiteCommand.java similarity index 82% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/CiteCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/CiteCommand.java index c3c0d25c..0c41ac28 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/CiteCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/CiteCommand.java @@ -23,18 +23,20 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.mod; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.embeds.moderation.CiteRuleEmbed; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.interfaces.Embed; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.embeds.moderation.CiteRuleEmbed; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.interfaces.Embed; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.TextChannel; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class CiteCommand extends PrivilegedCommand { public CiteCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { @@ -50,7 +52,7 @@ protected void execute(CommandEvent event) { String[] args = getArgs(event.getArgs()); String authorID = event.getAuthor().getId(); - if (!isStaff(authorID)) { + if (!isStaff(event.getGuild(), authorID)) { respondNoPermission(message, "[Moderator, Administrator]"); return; } diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/DmCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/DmCommand.java similarity index 59% rename from src/main/java/io/paradaux/friendlybot/commands/staff/technician/DmCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/DmCommand.java index acf9f826..8f7ea431 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/technician/DmCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/DmCommand.java @@ -23,14 +23,17 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.technician; +package io.paradaux.friendlybot.bot.commands.staff.mod; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; +import net.dv8tion.jda.api.entities.User; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class DmCommand extends PrivilegedCommand { public DmCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { @@ -42,7 +45,31 @@ public DmCommand(ConfigurationEntry config, Logger logger, PermissionManager per @Override protected void execute(CommandEvent event) { - // TODO Command stub + if (!isStaff(event.getGuild(), event.getAuthor().getId())) { + respondNoPermission(event.getMessage(), "Moderator"); + return; + } + + String[] args = getArgs(event.getArgs()); + + if (args.length < 3) { + respondSyntaxError(event.getMessage(), ";dm "); + return; + } + + User target = parseTarget(event.getMessage(), args[0]); + + if (target == null) { + respondSyntaxError(event.getMessage(), ";dm "); + return; + } + + target.openPrivateChannel().queue((channel) -> { + String message = parseSentance(1, args); + channel.sendMessage(message).queue(); + event.getChannel().sendMessage("Sent `" + message + "` to target: " + target.getAsTag()).queue(); + }); + } } diff --git a/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/KickCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/KickCommand.java new file mode 100644 index 00000000..5615d4b9 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/KickCommand.java @@ -0,0 +1,91 @@ +/* + * MIT License + * + * Copyright (c) 2021 Rían Errity + * io.paradaux.friendlybot.commands.staff.moderation.KickCommand : 31/01/2021, 01:26 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.paradaux.friendlybot.bot.commands.staff.mod; + +import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.FriendlyBot; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; +import io.paradaux.friendlybot.managers.PermissionManager; +import io.paradaux.friendlybot.managers.PunishmentManager; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import org.slf4j.Logger; + +/** + * This is a command which kicks the specified user. + * + * @author Rían Errity + * @version Last modified for 0.1.0-SNAPSHOT + * @since 4/11/2020 DD/MM/YY + * @see FriendlyBot + * */ + +@Command(name = "", description = "", permission = "", aliases = {}) +public class KickCommand extends PrivilegedCommand { + + private final PunishmentManager punishments; + + public KickCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { + super(config, logger, permissionManager); + this.name = "kick"; + this.help = "Kicks the specified user"; + this.punishments = PunishmentManager.getInstance(); + } + + @Override + protected void execute(CommandEvent event) { + Message message = event.getMessage(); + + String[] args = getArgs(event.getArgs()); + String authorID = event.getAuthor().getId(); + + if (!isStaff(event.getGuild(), authorID)) { + respondNoPermission(message, "[Moderator, Administrator]"); + return; + } + + if (args.length < 2) { + respondSyntaxError(message, ";kick "); + return; + } + + Member target = retrieveMember(event.getGuild(), args[0]); + + if (target == null) { + message.getChannel().sendMessage("You did not specify a (valid) target.").queue(); + return; + } + + if (isStaff(event.getGuild(), target.getId())) { + message.getChannel().sendMessage("You cannot ban a staff member.").queue(); + return; + } + + punishments.kickUser(event.getGuild(), target, event.getMember(), event.getTextChannel(), parseSentance(1, args)); + } +} \ No newline at end of file diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/LookupCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/LookupCommand.java similarity index 89% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/LookupCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/LookupCommand.java index d6de2ee3..4706f4cc 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/LookupCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/LookupCommand.java @@ -23,24 +23,26 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.mod; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.embeds.AuditLogEmbed; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.database.AuditLogEntry; +import io.paradaux.friendlybot.core.utils.models.database.BanEntry; +import io.paradaux.friendlybot.core.utils.models.database.KickEntry; +import io.paradaux.friendlybot.core.utils.models.database.WarningEntry; +import io.paradaux.friendlybot.core.utils.models.types.ModerationAction; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.MongoManager; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.embeds.AuditLogEmbed; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.database.AuditLogEntry; -import io.paradaux.friendlybot.utils.models.database.BanEntry; -import io.paradaux.friendlybot.utils.models.database.KickEntry; -import io.paradaux.friendlybot.utils.models.database.WarningEntry; -import io.paradaux.friendlybot.utils.models.types.ModerationAction; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.User; import org.slf4j.Logger; +@Command(name = "", description = "", permission = "", aliases = {}) public class LookupCommand extends PrivilegedCommand { public LookupCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager) { @@ -56,7 +58,7 @@ protected void execute(CommandEvent event) { String[] args = getArgs(event.getArgs()); String authorID = event.getAuthor().getId(); - if (!isStaff(authorID)) { + if (!isStaff(event.getGuild(), authorID)) { respondNoPermission(message, "[Moderator, Administrator]"); return; } diff --git a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/RespondCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/RespondCommand.java similarity index 86% rename from src/main/java/io/paradaux/friendlybot/commands/staff/moderation/RespondCommand.java rename to src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/RespondCommand.java index e6b898c2..f25da514 100644 --- a/src/main/java/io/paradaux/friendlybot/commands/staff/moderation/RespondCommand.java +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/RespondCommand.java @@ -23,16 +23,17 @@ * SOFTWARE. */ -package io.paradaux.friendlybot.commands.staff.moderation; +package io.paradaux.friendlybot.bot.commands.staff.mod; import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.database.ModMailEntry; +import io.paradaux.friendlybot.core.utils.models.database.ModMailResponse; +import io.paradaux.friendlybot.core.utils.models.enums.TicketStatus; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; import io.paradaux.friendlybot.managers.MongoManager; import io.paradaux.friendlybot.managers.PermissionManager; -import io.paradaux.friendlybot.utils.models.configuration.ConfigurationEntry; -import io.paradaux.friendlybot.utils.models.database.ModMailEntry; -import io.paradaux.friendlybot.utils.models.database.ModMailResponse; -import io.paradaux.friendlybot.utils.models.enums.TicketStatus; -import io.paradaux.friendlybot.utils.models.types.PrivilegedCommand; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import org.slf4j.Logger; @@ -41,6 +42,7 @@ import java.util.Date; import java.util.List; +@Command(name = "", description = "", permission = "", aliases = {}) public class RespondCommand extends PrivilegedCommand { private final MongoManager mongo; @@ -58,7 +60,7 @@ protected void execute(CommandEvent event) { String[] args = getArgs(event.getArgs()); String authorID = event.getAuthor().getId(); - if (!isStaff(authorID)) { + if (!isStaff(event.getGuild(), authorID)) { respondNoPermission(message, "[Moderator, Administrator]"); return; } @@ -71,13 +73,13 @@ protected void execute(CommandEvent event) { ModMailEntry entry = mongo.getModMailEntry(args[0]); if (entry == null) { - message.addReaction("\uD83D\uDEAB").queue(); + message.addReaction("🚫").queue(); message.getChannel().sendMessage("That ticket was not found").queue(); return; } if (entry.getStatus() == TicketStatus.CLOSED) { - message.addReaction("\uD83D\uDEAB").queue(); + message.addReaction("🚫").queue(); message.getChannel().sendMessage("You cannot respond to closed tickets.").queue(); return; } diff --git a/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/TempBanCommand.java b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/TempBanCommand.java new file mode 100644 index 00000000..19ff7240 --- /dev/null +++ b/src/main/java/io/paradaux/friendlybot/bot/commands/staff/mod/TempBanCommand.java @@ -0,0 +1,79 @@ +/* + * MIT License + * + * Copyright (c) 2021 Rían Errity + * io.paradaux.friendlybot.commands.staff.moderation.TempBanCommand : 06/02/2021, 18:10 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.paradaux.friendlybot.bot.commands.staff.mod; + +import com.jagrosh.jdautilities.command.CommandEvent; +import io.paradaux.friendlybot.bot.command.Command; +import io.paradaux.friendlybot.core.utils.models.configuration.ConfigurationEntry; +import io.paradaux.friendlybot.core.utils.models.types.PrivilegedCommand; +import io.paradaux.friendlybot.managers.MongoManager; +import io.paradaux.friendlybot.managers.PermissionManager; +import io.paradaux.friendlybot.managers.PunishmentManager; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import org.slf4j.Logger; + +@Command(name = "", description = "", permission = "", aliases = {}) +public class TempBanCommand extends PrivilegedCommand { + + private final MongoManager mongo; + private final PunishmentManager punishments; + + public TempBanCommand(ConfigurationEntry config, Logger logger, PermissionManager permissionManager, MongoManager mongo) { + super(config, logger, permissionManager); + this.mongo = mongo; + this.name = "tempban"; + this.help = "Temporarily bans a user."; + this.punishments = PunishmentManager.getInstance(); + } + + @Override + protected void execute(CommandEvent event) { + + Member staff = event.getMember(); + Message message = event.getMessage(); + String[] args = getArgs(event.getArgs()); + + if (!isStaff(event.getGuild(), staff.getId())) { + respondNoPermission(message, "[Moderator, Administrator]"); + return; + } + + if (event.getArgs().isEmpty()) { + respondSyntaxError(message, ";tempban