commit 5d423a06b7ab8c6731bacb6cc17e590692adb70a Author: Julius de Jeu Date: Thu Sep 13 20:14:31 2018 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73f1d53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,124 @@ + +# Created by https://www.gitignore.io/api/kotlin,gradle,jetbrains+all + +### JetBrains+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +### JetBrains+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +### Kotlin ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + + +# End of https://www.gitignore.io/api/kotlin,gradle,jetbrains+all \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8e6b6a2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Julius de Jeu + +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/README.md b/README.md new file mode 100644 index 0000000..7a9cc82 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# YeetBot +A stupid discord bot that is angry at some phrases and stuff... \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..026b099 --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'java' + id 'org.jetbrains.kotlin.jvm' version '1.2.61' + id 'com.github.johnrengelman.shadow' version '2.0.4' + +} + +group 'nl.voidcorp.yeetbot' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + jcenter() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + testCompile group: 'junit', name: 'junit', version: '4.12' + compile 'net.dv8tion:JDA:3.7.1_421' + compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.1' + compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.1' + compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.1' + compile 'com.github.salomonbrys.kotson:kotson:2.5.0' + +} + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" +} +compileTestKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +shadowJar { + baseName = 'YeetBot' + classifier = null + version = null +} + +jar { + manifest { + attributes 'Main-Class': 'nl.voidcorp.yeetbot.YeetKt' + } +} \ No newline at end of file diff --git a/conf-old.json b/conf-old.json new file mode 100644 index 0000000..c3da5d9 --- /dev/null +++ b/conf-old.json @@ -0,0 +1,11 @@ +{ + "guildWords": { + "313400918353772544": { + "map": { + "yeet": 1536697805477, + "jeet": 1536699512125, + "nice": 1536699538069 + } + } + } +} \ No newline at end of file diff --git a/conf.json b/conf.json new file mode 100644 index 0000000..78c74be --- /dev/null +++ b/conf.json @@ -0,0 +1,33 @@ +{ + "guildWords": { + "174602395630829568": { + "list": [ + { + "match": "fr0+d", + "time": 1536701874919, + "type": "REGEX" + }, + { + "match": "regex", + "time": 1536702012766, + "type": "RAW" + }, + { + "match": "(me)+", + "time": 1536702032376, + "type": "REGEX" + }, + { + "match": "ye+t", + "time": 1536702476328, + "type": "REGEX" + }, + { + "match": "ye*t", + "time": 1536702619087, + "type": "REGEX" + } + ] + } + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1948b90 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d2c45a4 --- /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-4.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## 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="" + +# 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, switch paths to Windows format before running java +if $cygwin ; 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=$((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" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@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 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= + +@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 init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +: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/settings.gradle b/settings.gradle new file mode 100644 index 0000000..3c5dbd6 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'YeetBot' + diff --git a/src/main/kotlin/nl/voidcorp/yeetbot/Config.kt b/src/main/kotlin/nl/voidcorp/yeetbot/Config.kt new file mode 100644 index 0000000..c40ee17 --- /dev/null +++ b/src/main/kotlin/nl/voidcorp/yeetbot/Config.kt @@ -0,0 +1,12 @@ +package nl.voidcorp.yeetbot + +data class Config(val guildWords: MutableMap = mutableMapOf()) + +data class GuildInfo(val list: MutableList = mutableListOf()) + +data class Match(val match: String, var time: Long = System.currentTimeMillis(), val type: MatchType = MatchType.RAW) + +enum class MatchType { + REGEX, + RAW +} \ No newline at end of file diff --git a/src/main/kotlin/nl/voidcorp/yeetbot/Util.kt b/src/main/kotlin/nl/voidcorp/yeetbot/Util.kt new file mode 100644 index 0000000..d3ba1cd --- /dev/null +++ b/src/main/kotlin/nl/voidcorp/yeetbot/Util.kt @@ -0,0 +1,5 @@ +package nl.voidcorp.yeetbot + +import com.google.gson.GsonBuilder + +val gson = GsonBuilder().setPrettyPrinting().create() \ No newline at end of file diff --git a/src/main/kotlin/nl/voidcorp/yeetbot/Yeet.kt b/src/main/kotlin/nl/voidcorp/yeetbot/Yeet.kt new file mode 100644 index 0000000..2dcc809 --- /dev/null +++ b/src/main/kotlin/nl/voidcorp/yeetbot/Yeet.kt @@ -0,0 +1,160 @@ +package nl.voidcorp.yeetbot + +import com.github.salomonbrys.kotson.fromJson +import net.dv8tion.jda.core.* +import net.dv8tion.jda.core.entities.Game +import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent +import net.dv8tion.jda.core.hooks.ListenerAdapter +import net.dv8tion.jda.core.utils.PermissionUtil +import org.apache.logging.log4j.LogManager +import java.io.File +import java.io.FileReader +import java.io.FileWriter +import java.time.Duration +import java.time.Instant +import java.util.* +import java.util.regex.Pattern +import java.util.regex.PatternSyntaxException +import kotlin.concurrent.fixedRateTimer +import kotlin.concurrent.schedule +import kotlin.concurrent.timer + + +lateinit var config: Config +val logger = LogManager.getLogger("YeetBot") + +fun main(args: Array) { + + config = if (File("conf.json").exists()) { + gson.fromJson(FileReader("conf.json")) + } else { + Config() + } + + val token = if (args.isEmpty()) { + throw IllegalArgumentException("missing the token string my dude!") + } else { + args[0] + } + + val jda = JDABuilder(AccountType.BOT).setToken(token).build() + jda.addEventListener(MessageListener()) + + jda.presence.setPresence(OnlineStatus.ONLINE, Game.playing("a banjo")) + fixedRateTimer("ConfigThread", period = 1000 * 60 * 5, initialDelay = 1000 * 10) { + logger.info("Writing config!") + try { + with(FileWriter("conf.json")) { + gson.toJson(config, this) + close() + } + } catch (e: Exception) { + logger.fatal("Could not write config!", e) + } + } + + fixedRateTimer("StopTimer", period = 1000) { + if (File("new").exists()) { + File("new").deleteOnExit() + jda.presence.setPresence(OnlineStatus.DO_NOT_DISTURB, Game.watching("a timer")) + Timer().schedule(1000 * 30) { + Runtime.getRuntime().exec("sudo ") + } + + } + } +} + + +class MessageListener : ListenerAdapter() { + override fun onGuildMessageReceived(event: GuildMessageReceivedEvent) { + val msg = event.message.contentRaw + val guild = event.guild + if (PermissionUtil.checkPermission(event.member, Permission.ADMINISTRATOR) && msg.startsWith("%")) { + when { + msg.substring(1).startsWith("addword ") -> { + val m = msg.replace("%addword ", "") + config.guildWords.getOrPut(guild.idLong) { GuildInfo() }.list += Match(m) + logger.info(config.guildWords[guild.idLong]) + event.channel.sendMessage(MessageBuilder().append(event.member).append(" I added the word `").append(m).append("` to the bad words list!").build()).queue() + } + msg.substring(1) == "listwords" -> { + var block = "" + for (st in config.guildWords.getOrPut(guild.idLong) { GuildInfo() }.list) { + block += "${st.match}${if (st.type == MatchType.REGEX) " (REGEX)" else ""}\n" + } + + event.channel.sendMessage( + MessageBuilder().append(event.member).append(" the following words are forbidden:").appendCodeBlock(block, "").build() + ).queue() + } + msg.substring(1).startsWith("addrmatch ") -> { + val m = msg.replace("%addrmatch ", "") + + if (checkRegex(m)) { + + config.guildWords.getOrPut(guild.idLong) { GuildInfo() }.list += Match(m, type = MatchType.REGEX) + + event.channel.sendMessage(MessageBuilder().append(event.member).append(" I added the regex `").append(m).append("` to the bad words list!").build()).queue() + + } else { + event.channel.sendMessage(MessageBuilder().append(event.member).append(", the regex `").append(m).append("` is invalid!").build()).queue() + + } + + + } + } + + } else if (!event.author.isBot) { + val map = config.guildWords.getOrPut(guild.idLong) { GuildInfo() }.list + for (match in map) { + + if ((match.type == MatchType.RAW && msg.contains(match.match))) { + if (match.time <= System.currentTimeMillis()) { + val past = Instant.ofEpochMilli(match.time) + val now = Instant.ofEpochMilli(System.currentTimeMillis()) + val time = Duration.between(past, now) + + match.time = now.toEpochMilli() + 1000 * 60 * 30 + event.channel.sendMessage(MessageBuilder().append(event.member) + .append(" said the forbidden word `").append(match.match) + .append("`! \nI have reset the counter for this word and will wait 30 minutes so you can spam it as much as you want. \nYou lived ") + .append("${time.toDays()} days ${time.toHours() % 24} hours ${time.toMinutes() % 60} minutes and ${(time.toMillis() / 1000) % 60} seconds") + .append(" without mentioning it.").build()).queue() + } + } else if (match.type == MatchType.REGEX && msg.contains(match.match.toRegex())) { + if (match.time <= System.currentTimeMillis()) { + val past = Instant.ofEpochMilli(match.time) + val now = Instant.ofEpochMilli(System.currentTimeMillis()) + val time = Duration.between(past, now) + + logger.info(msg.contains(match.match.toRegex())) + logger.info(match.match.toRegex().toPattern().matcher(msg).find()) + val txt = match.match.toRegex().toPattern().matcher(msg) + + match.time = now.toEpochMilli() + 1000 * 60 * 30 + event.channel.sendMessage(MessageBuilder().append(event.member) + .append(" said the forbidden word `").append(msg.substring(txt.regionStart(), txt.regionEnd())) + .append("`! \nI have reset the counter for this word and will wait 30 minutes so you can spam it as much as you want. \nYou lived ") + .append("${time.toDays()} days ${time.toHours() % 24} hours ${time.toMinutes() % 60} minutes and ${(time.toMillis() / 1000) % 60} seconds") + .append(" without mentioning it.").build()).queue() + } + } + } + } + + + } +} + +fun checkRegex(pattern: String): Boolean { + var exc: PatternSyntaxException? = null + try { + Pattern.compile(pattern) + } catch (e: PatternSyntaxException) { + exc = e + } + + return exc == null +} \ No newline at end of file diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..2829192 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file