Browse Source

remove specialCount from CmdData
remove CmdExitState

00ll00 5 years ago
parent
commit
6a6bc6f4c3

+ 9 - 0
src/main/kotlin/bot_luo_core/bot/BotLuo.kt

@@ -4,6 +4,8 @@ import bot_luo_core.cli.CmdHandler
 import bot_luo_core.data.DataObj
 import bot_luo_core.util.JsonWorker
 import bot_luo_core.util.Logger
+import bot_luo_core.util.Time
+import kotlinx.coroutines.TimeoutCancellationException
 import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.runBlocking
 import net.mamoe.mirai.Bot
@@ -15,6 +17,7 @@ import net.mamoe.mirai.event.events.*
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.utils.BotConfiguration
 import org.apache.logging.log4j.Level
+import kotlin.jvm.Throws
 
 /**
  * # 罗伯特
@@ -22,6 +25,11 @@ import org.apache.logging.log4j.Level
 object BotLuo {
     private const val FILE_PATH = "data/bots.json"
 
+    /**
+     * ## 罗伯特开机时间
+     */
+    val startAt = Time.time()
+
     /**
      * ## 所有机器人实例列表
      */
@@ -227,6 +235,7 @@ object BotLuo {
      *
      * @param filter 过滤消息直到获取到符合要求的消息(返回`true`)
      */
+    @Throws(TimeoutCancellationException::class)
     suspend fun catchNextMessage(userId: Long, groupId: Long, timeoutMillis: Long = -1L, filter: (msg: MessageChain)->Boolean = {true}): MessageChain {
         return syncFromEvent<Event, MessageChain>(timeoutMillis, EventPriority.MONITOR) { event ->
             return@syncFromEvent when (event) {

+ 107 - 7
src/main/kotlin/bot_luo_core/cli/Cmd.kt

@@ -3,18 +3,118 @@ package bot_luo_core.cli
 @Suppress("PropertyName", "FunctionName")
 abstract class Cmd(val context: CmdContext) {
 
-    val SUCCESS: CmdReceipt get() = CmdReceipt(context.time, CmdExitState.SUCCESS)
-    val FATAL: CmdReceipt get() = CmdReceipt(context.time, CmdExitState.FATAL)
-    val FATAL_BUT_SET_TIME: CmdReceipt get() = CmdReceipt(context.time, CmdExitState.FATAL_BUT_SET_TIME)
-    val FATAL_BUT_ADD_COUNT: CmdReceipt get() = CmdReceipt(context.time, CmdExitState.FATAL_BUT_ADD_COUNT)
+    val SUCCESS: CmdReceipt get() = SUCCESS()
+    val SUCCESS_NOT_ADD_COUNT: CmdReceipt get() = SUCCESS_NOT_ADD_COUNT()
+    val SUCCESS_NOT_SET_TIME: CmdReceipt get() = SUCCESS_NOT_SET_TIME()
+    val FATAL: CmdReceipt get() = FATAL()
+    val FATAL_BUT_ADD_COUNT: CmdReceipt get() = FATAL_BUT_ADD_COUNT()
+    val FATAL_BUT_SET_TIME: CmdReceipt get() = FATAL_BUT_SET_TIME()
 
     /**
+     * 执行成功,增加次数统计,设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
      * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
      */
-    fun SUCCESS(uploadFile: Int) = CmdReceipt(context.time, CmdExitState.SUCCESS, uploadOutputFile = uploadFile)
+    fun SUCCESS(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = true,
+        addCount = true,
+        setTime = true,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
 
     /**
-     * 命令执行完毕退出前执行
+     * 执行成功,不增加次数统计,设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
+     */
+    fun SUCCESS_NOT_ADD_COUNT(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = true,
+        addCount = false,
+        setTime = true,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
+
+    /**
+     * 执行成功,增加次数统计,不设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
+     */
+    fun SUCCESS_NOT_SET_TIME(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = true,
+        addCount = true,
+        setTime = false,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
+
+    /**
+     * 执行失败,不增加次数统计,不设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
+     */
+    fun FATAL(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = false,
+        addCount = true,
+        setTime = true,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
+
+    /**
+     * 执行失败,增加次数统计,不设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
+     */
+    fun FATAL_BUT_ADD_COUNT(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = false,
+        addCount = true,
+        setTime = true,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
+
+    /**
+     * 执行失败,不增加次数统计,设置时间
+     *
+     * @param addSpecialCount 增加特殊计次
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
      */
-    open fun onExit(receipt: CmdReceipt) {}
+    fun FATAL_BUT_SET_TIME(
+        addSpecialCount: Boolean = false,
+        uploadFile: Int = 0
+    ) = CmdReceipt(
+        time = context.time,
+        success = false,
+        addCount = true,
+        setTime = true,
+        addSpecialCount = addSpecialCount,
+        uploadOutputFile = uploadFile
+    )
 }

+ 23 - 1
src/main/kotlin/bot_luo_core/cli/CmdContext.kt

@@ -143,9 +143,17 @@ class CmdContext(
         return null
     }
 
+    /**
+     * 捕获下一条消息,超时抛出异常
+     */
     @Throws(TimeoutCancellationException::class)
     suspend inline fun nextMessage(timeoutMillis: Long = -1L): MessageChain = BotLuo.catchNextMessage(user.id, group.id, timeoutMillis)
 
+    /**
+     * 捕获下一条消息,带超时动作
+     *
+     * 超时返回空消息链
+     */
     suspend inline fun nextMessage(timeoutMillis: Long = -1L, timeoutAction: () -> Unit): MessageChain {
         try {
             return BotLuo.catchNextMessage(user.id, group.id, timeoutMillis)
@@ -154,7 +162,21 @@ class CmdContext(
         }
         return EmptyMessageChain
     }
-    suspend inline fun nextYorN(timeoutMillis: Long, noinline timeoutAction: suspend () -> Boolean): Boolean {
+
+    /**
+     * 带过滤器的[nextMessage]
+     *
+     * 超时返回`null`
+     */
+    suspend inline fun nextMessageFiltered(timeoutMillis: Long = -1L, noinline filter: (Message)-> Boolean): MessageChain? {
+        return try {
+            BotLuo.catchNextMessage(user.id, group.id, timeoutMillis, filter)
+        } catch (e: TimeoutCancellationException) {
+            null
+        }
+    }
+
+    suspend inline fun nextYorN(timeoutMillis: Long, timeoutAction: () -> Boolean): Boolean {
         return try {
             BotLuo.catchNextMessage(user.id, group.id, timeoutMillis) {
                 it.content.trim().toLowercase() in REPL_YES + REPL_NO

+ 0 - 1
src/main/kotlin/bot_luo_core/cli/CmdExecutable.kt

@@ -78,7 +78,6 @@ class CmdExecutable(private val cmd: KClass<out Cmd>, private val meth: KFunctio
         } else {
             meth.callBy(args)
         }
-        ins.onExit(receipt)
         return receipt
     }
 

+ 0 - 8
src/main/kotlin/bot_luo_core/cli/CmdExitState.kt

@@ -1,8 +0,0 @@
-package bot_luo_core.cli
-
-enum class CmdExitState(val addCount: Boolean, val setTime: Boolean) {
-    SUCCESS(true, true),
-    FATAL(false, false),
-    FATAL_BUT_SET_TIME(false, true),
-    FATAL_BUT_ADD_COUNT(true, false)
-}

+ 24 - 22
src/main/kotlin/bot_luo_core/cli/CmdHandler.kt

@@ -8,9 +8,11 @@ import bot_luo_core.data.Config.MAX_OUTPUT_LEN
 import bot_luo_core.data.Groups
 import bot_luo_core.data.Users
 import bot_luo_core.data.withAccessing
+import bot_luo_core.data.withLockedAccessing
 import bot_luo_core.util.Logger
 import bot_luo_core.util.Text.firstNotWhitespace
 import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.runBlocking
 import net.mamoe.mirai.event.events.GroupAwareMessageEvent
 import net.mamoe.mirai.event.events.MessageEvent
 import net.mamoe.mirai.message.data.At
@@ -123,29 +125,29 @@ object CmdHandler {
 
                     val res = cmd.executeWith(context, args)
 
-                    Logger.log(cmd, context, "执行完成:${res.state}")
-
-                    if (res.state.addCount) {
-                        val ud = context.user.readCmdData(cmd)
-                        ud.totalCount++
-                        ud.dayCount++
-                        ud.specialCount++
-                        context.user.writeCmdData(cmd, ud)
-                        val gd = context.group.readCmdData(cmd)
-                        gd.totalCount++
-                        gd.dayCount++
-                        gd.specialCount++
-                        context.group.writeCmdData(cmd, gd)
-                    }
+                    Logger.log(cmd, context, "执行完成:${res.success}")
+
+                    runBlocking { withLockedAccessing(context.user, context.group) {
+                        if (res.addCount) {
+                            val ud = context.user.readCmdData(cmd)
+                            ud.totalCount++
+                            ud.dayCount++
+                            context.user.writeCmdData(cmd, ud)
+                            val gd = context.group.readCmdData(cmd)
+                            gd.totalCount++
+                            gd.dayCount++
+                            context.group.writeCmdData(cmd, gd)
+                        }
 
-                    if (res.state.setTime) {
-                        val ud = context.user.readCmdData(cmd)
-                        ud.lastTime = context.time
-                        context.user.writeCmdData(cmd, ud)
-                        val gd = context.group.readCmdData(cmd)
-                        gd.lastTime = context.time
-                        context.group.writeCmdData(cmd, gd)
-                    }
+                        if (res.setTime) {
+                            val ud = context.user.readCmdData(cmd)
+                            ud.lastTime = context.time
+                            context.user.writeCmdData(cmd, ud)
+                            val gd = context.group.readCmdData(cmd)
+                            gd.lastTime = context.time
+                            context.group.writeCmdData(cmd, gd)
+                        }
+                    } }
 
                     context.uploadOutputFile = maxOf(context.uploadOutputFile, res.uploadOutputFile)
                 } catch (e: Exception) {

+ 4 - 8
src/main/kotlin/bot_luo_core/cli/CmdReceipt.kt

@@ -5,7 +5,10 @@ import kotlin.collections.ArrayList
 
 data class CmdReceipt(
     val time: Long,
-    val state: CmdExitState,
+    val success: Boolean,
+    val addCount: Boolean,
+    val setTime: Boolean,
+    val addSpecialCount: Boolean,
     val messages: ArrayList<String> = ArrayList(),
     val f: String? = null,
     val b: String? = null,
@@ -17,11 +20,4 @@ data class CmdReceipt(
     fun undoable(): Boolean {
         return f!=null && b!=null
     }
-
-    /**
-     * 需要保存
-     */
-    fun needSave(): Boolean {
-        return state.setTime || state.addCount
-    }
 }

+ 3 - 0
src/main/kotlin/bot_luo_core/cli/commands/DebugCmd.kt

@@ -1,5 +1,6 @@
 package bot_luo_core.cli.commands
 
+import bot_luo_core.bot.BotLuo
 import bot_luo_core.cli.*
 import bot_luo_core.cli.annotation.Command
 import bot_luo_core.cli.annotation.Method
@@ -7,6 +8,7 @@ import bot_luo_core.data.DataObj
 import bot_luo_core.data.Groups
 import bot_luo_core.data.Users
 import bot_luo_core.util.TableBuilder
+import bot_luo_core.util.Time.relativeTo
 
 @Command(
     name = "debug",
@@ -20,6 +22,7 @@ class DebugCmd(context: CmdContext) : Cmd(context) {
     fun show (): CmdReceipt {
         val table = TableBuilder(4)
         table.th("调试信息 ——").br()
+        table.tr("start_at:").tb( BotLuo.startAt relativeTo context.time)
         table.tr("active_groups:").tb(Groups.activeGroupsCount)
         table.tr("active_users:").tb(Users.activeUsersCount)
         table.tr("save_jobs:").tb(DataObj.savingJobs.size)

+ 0 - 1
src/main/kotlin/bot_luo_core/data/CmdData.kt

@@ -4,6 +4,5 @@ data class CmdData(
     var lastTime: Long,
     var totalCount: Int,
     var dayCount: Int,
-    var specialCount: Int,
     var working: Boolean
 )

+ 1 - 1
src/main/kotlin/bot_luo_core/data/Group.kt

@@ -18,7 +18,7 @@ class Group internal constructor(
 ) : CmdDataObj("data/groups/$id.json"), BotContact {
     override val contactType = BotContactType.Group
     override val defaultData: CmdData
-        get() = CmdData(0,0,0,0,false)//群组命令默认关闭
+        get() = CmdData(0,0,0,false)//群组命令默认关闭
 
     val virtual: Boolean = id==0L
 

+ 1 - 1
src/main/kotlin/bot_luo_core/data/User.kt

@@ -19,7 +19,7 @@ class User internal constructor (
     override var bot: Bot? = null
 ) : CmdDataObj("data/users/$id.json"), BotContact {
     override val contactType = BotContactType.Single
-    override val defaultData: CmdData get() = CmdData(0,0,0,0,true)//用户命令默认开启
+    override val defaultData: CmdData get() = CmdData(0,0,0,true)//用户命令默认开启
 
     val virtual: Boolean = id==0L
 

+ 21 - 0
src/main/kotlin/bot_luo_core/util/Time.kt

@@ -155,10 +155,31 @@ object Time {
             sb.append("${sec}秒")
         return sb.toString()
     }
+
     /**
      * 解析相对时刻(ms)为文本
      * @param [time] 正数为之前,负数为之后
      * @return [String] 时间文本
      */
     fun formatRelativeTime(time: Long) = formatSpan(abs(time)) + if (time>0) "前" else "后"
+
+    /**
+     * 时间差
+     */
+    infix fun Long.spanFrom(another: Long): String = formatSpan(another - this)
+
+    /**
+     * 简略时间差
+     */
+    infix fun Long.spanFromE(another: Long): String = formatSpanE(another - this)
+
+    /**
+     * 相对时间
+     */
+    infix fun Long.relativeTo(another: Long): String = formatRelativeTime(another - this)
+
+    /**
+     * 简略相对时间
+     */
+    infix fun Long.relativeToE(another: Long): String = formatRelativeTimeE(another - this)
 }