diff --git a/build.gradle.kts b/build.gradle.kts index 75bccba..f164efa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("gg.flyte:neptune:2.4") implementation("org.mongodb:mongodb-driver-sync:4.9.0") implementation("io.github.cdimascio:dotenv-kotlin:6.4.1") - implementation(files("libs/Math-Evaluator-1.2.0.jar")) + implementation(files("libs/Math-Evaluator-1.2.2.jar")) } application { diff --git a/libs/Math-Evaluator-1.2.0.jar b/libs/Math-Evaluator-1.2.0.jar deleted file mode 100644 index 5bad21c..0000000 Binary files a/libs/Math-Evaluator-1.2.0.jar and /dev/null differ diff --git a/libs/Math-Evaluator-1.2.2.jar b/libs/Math-Evaluator-1.2.2.jar new file mode 100644 index 0000000..85c56ae Binary files /dev/null and b/libs/Math-Evaluator-1.2.2.jar differ diff --git a/src/main/kotlin/com/learnspigot/bot/Bot.kt b/src/main/kotlin/com/learnspigot/bot/Bot.kt index 66570c8..11b0229 100644 --- a/src/main/kotlin/com/learnspigot/bot/Bot.kt +++ b/src/main/kotlin/com/learnspigot/bot/Bot.kt @@ -1,5 +1,6 @@ package com.learnspigot.bot +import com.learnspigot.bot.counting.CountingRegistry import com.learnspigot.bot.help.search.HelpPostRegistry import com.learnspigot.bot.intellijkey.IJUltimateKeyRegistry import com.learnspigot.bot.knowledgebase.KnowledgebasePostRegistry @@ -88,6 +89,8 @@ class Bot { return HelpPostRegistry() } + @Instantiate fun countingRegistry(): CountingRegistry = CountingRegistry(profileRegistry) + companion object { lateinit var jda: JDA } diff --git a/src/main/kotlin/com/learnspigot/bot/counting/CountingCommand.kt b/src/main/kotlin/com/learnspigot/bot/counting/CountingCommand.kt new file mode 100644 index 0000000..b6656c3 --- /dev/null +++ b/src/main/kotlin/com/learnspigot/bot/counting/CountingCommand.kt @@ -0,0 +1,57 @@ +package com.learnspigot.bot.counting + +import com.learnspigot.bot.profile.ProfileRegistry +import com.learnspigot.bot.util.embed +import gg.flyte.neptune.annotation.Command +import gg.flyte.neptune.annotation.Description +import gg.flyte.neptune.annotation.Inject +import gg.flyte.neptune.annotation.Optional +import net.dv8tion.jda.api.entities.User +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent + +class CountingCommand { + + @Inject private lateinit var profileRegistry: ProfileRegistry + @Inject private lateinit var countingRegistry: CountingRegistry + + @Command(name = "countingstats", description = "View counting statistics") + fun onCountingCommand( + event: SlashCommandInteractionEvent, + @Description("User's stats to view") @Optional user: User? + ) { + if (user == null) { // Server stats + event.replyEmbeds( + embed() + .setTitle("Server counting statistics") + .setDescription(""" + - Current Count: ${countingRegistry.currentCount} + - Total Counts: ${countingRegistry.serverTotalCounts} + - Highest Count: ${countingRegistry.topServerCount} + """.trimIndent()) + .addField( + "Top 5 counters", + countingRegistry.leaderboard.take(5).joinToString("") { + val profile = profileRegistry.findById(it)!! + if (profile.tag == null || profile.totalCounts == 0) return@joinToString "" + "\n- ${profile.tag}: ${profile.totalCounts}" + }, + false + ) + .build() + ).setEphemeral(true).queue() + } else { // Individual Stats + val profile = profileRegistry.findByUser(user) + event.replyEmbeds( + embed() + .setTitle(user.name + "'s counting statistics") + .setDescription(""" + - Total Counts: ${profile.totalCounts} + - Highest Count: ${profile.highestCount} + - Mistakes: ${profile.countingFuckUps} + """.trimIndent()) + .build() + ).setEphemeral(true).queue() + } + + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/learnspigot/bot/counting/CountingListener.kt b/src/main/kotlin/com/learnspigot/bot/counting/CountingListener.kt index 0a0c032..10ae046 100644 --- a/src/main/kotlin/com/learnspigot/bot/counting/CountingListener.kt +++ b/src/main/kotlin/com/learnspigot/bot/counting/CountingListener.kt @@ -2,70 +2,38 @@ package com.learnspigot.bot.counting import com.learnspigot.bot.Environment import com.learnspigot.bot.Server -import com.learnspigot.bot.profile.ProfileRegistry -import com.learnspigot.bot.util.Mongo -import com.mongodb.client.model.Filters import gg.flyte.neptune.annotation.Inject import me.superpenguin.mathevaluator.Evaluator import net.dv8tion.jda.api.entities.Message import net.dv8tion.jda.api.entities.User import net.dv8tion.jda.api.entities.channel.Channel +import net.dv8tion.jda.api.entities.emoji.Emoji import net.dv8tion.jda.api.events.message.MessageDeleteEvent import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.events.message.MessageUpdateEvent import net.dv8tion.jda.api.hooks.ListenerAdapter -import org.bson.Document class CountingListener: ListenerAdapter() { - @Inject private lateinit var profileRegistry: ProfileRegistry + @Inject private lateinit var countingRegistry: CountingRegistry - private val mongoCollection = Mongo.countingCollection - - var topServerCount: Int = 0 - var serverTotalCounts: Int = 0 - var currentCount = 0 + val currentCount: Int get() = countingRegistry.currentCount var lastCount: Message? = null - init { - val document = mongoCollection.find().first() - if (document == null) { - val newDoc = Document() - newDoc["highestCount"] = 0 - newDoc["currentCount"] = 0 - newDoc["serverTotalCounts"] = 0 - mongoCollection.insertOne(newDoc) - } else { - topServerCount = document.getInteger("highestCount", 0) - currentCount = document.getInteger("currentCount", 0) - serverTotalCounts = document.getInteger("serverTotalCounts", 0) - } - } - - fun incrementCount(user: User) { - currentCount++ - serverTotalCounts++ - profileRegistry.findByUser(user).incrementCount(currentCount) - if (currentCount > topServerCount) topServerCount = currentCount - val newDoc = mongoCollection.find().first()!! - newDoc["highestCount"] = topServerCount - newDoc["currentCount"] = currentCount - newDoc["serverTotalCounts"] = serverTotalCounts - mongoCollection.replaceOne(Filters.eq("_id", newDoc.getObjectId("_id")), newDoc) - } - fun fuckedUp(user: User) { - currentCount = 0 lastCount = null - profileRegistry.findByUser(user).fuckedUpCounting() + countingRegistry.fuckedUp(user) } private fun Channel.isCounting() = id == Environment.get("COUNTING_CHANNEL_ID") + private fun Message.millisSinceLastCount() = timeCreated.toInstant().toEpochMilli() - (lastCount?.timeCreated?.toInstant()?.toEpochMilli() ?: 0) + + private val thinking = Emoji.fromUnicode("🤔") override fun onMessageReceived(event: MessageReceivedEvent) { if (event.author.isBot || !event.isFromGuild || !event.channel.isCounting() || event.guild.id != Server.guildId) return - if (event.message.embeds.isNotEmpty()) return + if (event.message.attachments.isNotEmpty()) return val msg = event.message.contentRaw val userId = event.author.id @@ -74,17 +42,23 @@ class CountingListener: ListenerAdapter() { if (evaluated == currentCount + 1) { if (userId.equals(lastCount?.author?.id, true)) return run { event.message.addReaction(Server.downvoteEmoji) - event.message.reply("You can't count twice in a row, let someone else join in!").queue() + event.message.reply("You can't count twice in a row, let someone else join in! ( The count has been reset to 1 )").queue() fuckedUp(event.author) } lastCount = event.message event.message.addReaction(Server.upvoteEmoji).queue() - incrementCount(event.author) + countingRegistry.incrementCount(event.author) } else { + if (evaluated == currentCount && event.message.millisSinceLastCount() < 600) { + // ( 600ms delay ) - Arbitrary value based on superficial testing + event.message.addReaction(thinking).queue() + event.message.reply("I'll let this one slide").queue() + return + } val next = currentCount + 1 fuckedUp(event.author) event.message.addReaction(Server.downvoteEmoji).queue() - event.message.reply("The next number was $next").queue() + event.message.reply("The next number was $next, not $evaluated").queue() } } } diff --git a/src/main/kotlin/com/learnspigot/bot/counting/CountingRegistry.kt b/src/main/kotlin/com/learnspigot/bot/counting/CountingRegistry.kt new file mode 100644 index 0000000..a406588 --- /dev/null +++ b/src/main/kotlin/com/learnspigot/bot/counting/CountingRegistry.kt @@ -0,0 +1,59 @@ +package com.learnspigot.bot.counting + +import com.learnspigot.bot.profile.ProfileRegistry +import com.learnspigot.bot.util.Mongo +import com.mongodb.client.model.Filters +import net.dv8tion.jda.api.entities.User +import org.bson.Document +import java.util.* + +class CountingRegistry(private val profileRegistry: ProfileRegistry) { + private val mongoCollection = Mongo.countingCollection + + var topServerCount: Int = 0 + var serverTotalCounts: Int = 0 + var currentCount = 0 + + // Queue of User Ids + val leaderboard: PriorityQueue = PriorityQueue { a, b -> + profileRegistry.findById(b)!!.totalCounts.compareTo(profileRegistry.findById(a)!!.totalCounts) + } + + init { + val document = mongoCollection.find().first() + if (document == null) { + val newDoc = Document() + newDoc["highestCount"] = 0 + newDoc["currentCount"] = 0 + newDoc["serverTotalCounts"] = 0 + mongoCollection.insertOne(newDoc) + } else { + topServerCount = document.getInteger("highestCount", 0) + currentCount = document.getInteger("currentCount", 0) + serverTotalCounts = document.getInteger("serverTotalCounts", 0) + } + + profileRegistry.profileCache.values.forEach { leaderboard.add(it.id) } + } + + private fun PriorityQueue.recalculate(ele: T) = remove(ele).also { add(ele) } + + fun incrementCount(user: User) { + currentCount++ + serverTotalCounts++ + if (currentCount > topServerCount) topServerCount = currentCount + leaderboard.recalculate(user.id) + profileRegistry.findByUser(user).incrementCount(currentCount) + val newDoc = mongoCollection.find().first()!! + newDoc["highestCount"] = topServerCount + newDoc["currentCount"] = currentCount + newDoc["serverTotalCounts"] = serverTotalCounts + mongoCollection.replaceOne(Filters.eq("_id", newDoc.getObjectId("_id")), newDoc) + } + + fun fuckedUp(user: User) { + currentCount = 0 + profileRegistry.findByUser(user).fuckedUpCounting() + } + +} \ No newline at end of file