YeetBot/src/main/kotlin/nl/voidcorp/yeetbot/Yeet.kt

160 lines
6.7 KiB
Kotlin

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<String>) {
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
}