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 }