All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xyz.cssxsh.mirai.arknights.command.ArknightsMineCommand.kt Maven / Gradle / Ivy

There is a newer version: 2.3.1
Show newest version
package xyz.cssxsh.mirai.arknights.command

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.*
import net.mamoe.mirai.console.command.CommandSender.Companion.toCommandSender
import net.mamoe.mirai.console.command.*
import net.mamoe.mirai.event.*
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.MessageSource.Key.quote
import xyz.cssxsh.arknights.mine.*
import xyz.cssxsh.mirai.arknights.*
import xyz.cssxsh.mirai.arknights.data.*

public object ArknightsMineCommand : SimpleCommand(
    owner = ArknightsHelperPlugin,
    "ark-mine", "方舟挖矿", "方舟答题",
    description = "明日方舟助手挖矿指令"
) {

    private suspend inline fun  P.nextAnswerOrNull(
        timeoutMillis: Long,
        priority: EventPriority = EventPriority.MONITOR,
        noinline filter: suspend (P) -> Boolean = { true }
    ): P? {
        return withTimeoutOrNull(timeoutMillis) {
            bot.eventChannel.nextEvent(priority) { next ->
                subject.id == next.subject.id && filter(next)
            }
        }
    }

    private fun countQuestionType(type: QuestionType, mode: Int) {
        ArknightsMineData.count.compute(type) { _, s ->
            (s ?: mutableListOf(0, 0, 0)).apply { this[mode] += 1 }
        }
    }

    private val CommandSenderOnMessage<*>.mutex: Mutex by SubjectDelegate { Mutex() }

    @Handler
    public suspend fun CommandSenderOnMessage<*>.handler(type: QuestionType = QuestionType.values().random()) {
        val question = type.random(loader = ArknightsQuestionLoader)
        val time: Long
        val reply: MessageEvent?
        mutex.withLock {
            sendMessage(buildMessageChain {
                append(fromEvent.message.quote())
                appendLine("[${type}]<${question.coin}>:${question.problem} (${question.timeout / 1000}s内作答)")
                for ((index, text) in question.options) {
                    appendLine("${index}.${text}")
                }
            })

            val start = System.currentTimeMillis()
            reply = fromEvent.nextAnswerOrNull(question.timeout) { next ->
                next.message.content.uppercase().any { it in question.options.keys }
            }
            time = System.currentTimeMillis() - start
        }
        if (reply == null) {
            sendMessage("回答超时")
            countQuestionType(type, 2)
            return
        }
        val answer = reply.message.content.uppercase().filter { it in question.options.keys }.toSet()
        var multiple = 1
        var deduct = false
        val origin = fromEvent.sender
        reply.toCommandSender().reply {
            buildMessageChain {
                appendLine(question.problem)
                if (reply.sender != origin) {
                    multiple *= 10
                    deduct = true
                    appendLine("抢答(合成玉翻10倍)")
                }
                if (time * 3 < question.timeout) {
                    multiple *= 5
                    appendLine("快速回答(合成玉翻5倍)")
                }
                if (answer == question.answer) {
                    countQuestionType(type, 0)
                    user.coin += (question.coin * multiple)
                    appendLine("回答正确,合成玉${"%+d".format(question.coin)}*${multiple}")
                } else {
                    countQuestionType(type, 1)
                    appendLine("回答错误${answer}, ${question.tips ?: "参考答案${question.answer}"}")
                    if (deduct) {
                        user.coin -= (question.coin * multiple)
                        appendLine("抢答,合成玉${"%+d".format(question.coin * -1)}*${multiple}")
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy