00ll00 5 лет назад
Родитель
Сommit
4600d34a21

+ 6 - 1
src/main/kotlin/bot_luo_core/cli/Cmd.kt

@@ -1,6 +1,6 @@
 package bot_luo_core.cli
 
-@Suppress("PropertyName")
+@Suppress("PropertyName", "FunctionName")
 abstract class Cmd(val context: CmdContext) {
 
     val SUCCESS: CmdReceipt get() = CmdReceipt(context.time, CmdExitState.SUCCESS)
@@ -8,6 +8,11 @@ abstract class Cmd(val context: CmdContext) {
     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)
 
+    /**
+     * @param uploadFile 0:不允许上传 1:超过限制时上传 2:始终上传
+     */
+    fun SUCCESS(uploadFile: Int) = CmdReceipt(context.time, CmdExitState.SUCCESS, uploadOutputFile = uploadFile)
+
     /**
      * 命令执行完毕退出前执行
      */

+ 40 - 0
src/main/kotlin/bot_luo_core/cli/CmdContext.kt

@@ -7,14 +7,20 @@ import bot_luo_core.data.Config.REPL_YES
 import bot_luo_core.data.Group
 import bot_luo_core.data.User
 import bot_luo_core.util.Logger
+import bot_luo_core.util.Logger.sendMessageWithLog
 import bot_luo_core.util.Text.toLowercase
 import bot_luo_core.util.Time
 import kotlinx.coroutines.TimeoutCancellationException
 import net.mamoe.mirai.contact.Contact
+import net.mamoe.mirai.contact.Contact.Companion.uploadImage
+import net.mamoe.mirai.contact.FileSupported
 import net.mamoe.mirai.contact.MemberPermission
 import net.mamoe.mirai.event.events.EventCancelledException
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.*
+import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource
+import net.mamoe.mirai.utils.RemoteFile.Companion.uploadFile
+import java.io.File
 import kotlin.jvm.Throws
 
 class CmdContext(
@@ -33,6 +39,13 @@ class CmdContext(
         time: Long = Time.time()
     ): this(reader, user, group, user, group, time)
 
+    /**
+     * - 0: 不允许上传
+     * - 1: 当输出过大时允许上传文件
+     * - 2: 始终上传
+     */
+    var uploadOutputFile: Int = 0
+
     /**
      * 直接回复消息所使用的对象,可能为`null`
      *
@@ -116,6 +129,18 @@ class CmdContext(
         return null
     }
 
+    suspend fun uploadOutput(): MessageReceipt<Contact>? {
+        withBackendBot{ contact ->
+            if (contact !is FileSupported) return null
+            val file = File.createTempFile("output-${this.hashCode()}",".txt")
+            file.deleteOnExit()
+            file.toExternalResource().use { resource ->
+                return  contact.sendMessageWithLog(contact.uploadFile("${this.reader.original.content.replace(' ','_')}.txt",resource))
+            }
+        }
+        return null
+    }
+
     @Throws(TimeoutCancellationException::class)
     suspend inline fun nextMessage(timeoutMillis: Long = -1L): MessageChain = MultiBotHandler.catchNextMessage(user.id, group.id, timeoutMillis)
 
@@ -164,4 +189,19 @@ class CmdContext(
         }
     }
 
+    /**
+     * 获取一个[receiver]的Mirai联系对象进行动作
+     *
+     * 获取失败返回`false`并放弃执行动作
+     *
+     * @return 是否获取成功
+     */
+    inline fun withBackendBot(pms: MemberPermission = MemberPermission.MEMBER, action: (contact: Contact)->Unit): Boolean {
+        return when(receiver) {
+            is Group -> group.withServeBot(pms, action)
+            is User -> user.withServeBot(action)
+            else -> false
+        }
+    }
+
 }

+ 28 - 1
src/main/kotlin/bot_luo_core/cli/CmdHandler.kt

@@ -4,6 +4,7 @@ import bot_luo_core.bot.VirtualMessageEvent
 import bot_luo_core.cli.Checker.Companion.order
 import bot_luo_core.cli.exceptions.*
 import bot_luo_core.data.Config.CMD_PREFIX
+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
@@ -68,7 +69,31 @@ object CmdHandler {
         } catch (e: Exception) {
             context.sendOutputWithLog("发生异常:${e::class.simpleName}\n${e.message}".toPlainText())
         }
-        context.sendOutputWithLog()
+        when (context.uploadOutputFile) {
+            0 -> {
+                if (context.getOutput().content.length > MAX_OUTPUT_LEN) {
+                    context.sendOutputWithLog("输出过大,考虑使用dumpfile命令获取输出")
+                } else {
+                    context.sendOutputWithLog()
+                }
+            }
+            1 -> {
+                if (context.getOutput().content.length > MAX_OUTPUT_LEN) {
+                    val receipt = context.uploadOutput()
+                    if (receipt == null) {
+                        context.sendOutputWithLog("输出上传文件失败")
+                    }
+                } else {
+                    context.sendOutputWithLog()
+                }
+            }
+            2 -> {
+                val receipt = context.uploadOutput()
+                if (receipt == null) {
+                    context.sendOutputWithLog("输出上传文件失败")
+                }
+            }
+        }
     }
 
     /**
@@ -121,6 +146,8 @@ object CmdHandler {
                         gd.lastTime = context.time
                         context.group.writeCmdData(cmd, gd)
                     }
+
+                    context.uploadOutputFile = maxOf(context.uploadOutputFile, res.uploadOutputFile)
                 } catch (e: Exception) {
                     when(e) {
                         is CliException -> throw e

+ 2 - 1
src/main/kotlin/bot_luo_core/cli/CmdReceipt.kt

@@ -8,7 +8,8 @@ data class CmdReceipt(
     val state: CmdExitState,
     val messages: ArrayList<String> = ArrayList(),
     val f: String? = null,
-    val b: String? = null
+    val b: String? = null,
+    val uploadOutputFile: Int = 0
 ) {
     /**
      * 允许撤销操作

+ 1 - 1
src/main/kotlin/bot_luo_core/cli/commands/AnnounceCmd.kt

@@ -23,7 +23,7 @@ import java.lang.IllegalStateException
 import java.net.HttpURLConnection
 import java.net.URL
 import kotlin.reflect.KType
-
+//TODO 需要验证
 @Command(
     name = "announce",
     display = "公告",

+ 35 - 0
src/main/kotlin/bot_luo_core/cli/commands/DumpFileCmd.kt

@@ -0,0 +1,35 @@
+package bot_luo_core.cli.commands
+
+import bot_luo_core.cli.*
+import bot_luo_core.cli.annotation.Argument
+import bot_luo_core.cli.annotation.Command
+import bot_luo_core.cli.annotation.Method
+import bot_luo_core.cli.exceptions.CliException
+import bot_luo_core.cli.handlers.GreedyMessageArgHandler
+import net.mamoe.mirai.message.data.MessageChain
+import kotlin.jvm.Throws
+
+@Command(
+    name = "dumpfile",
+    display = "上传输出",
+    alias = ["df"],
+    usage = "将命令输出作为文件发送,避免输出消息过长",
+    notice = [
+        "目前只支持上传群文件"
+    ]
+)
+class DumpFileCmd(context: CmdContext) : Cmd(context) {
+
+    @Throws(CliException::class)
+    @Method(name = "", alias = [], pmsLevel = CmdPermissionLevel.OP)
+    fun dump (
+        @Argument(display = "命令", handler = GreedyMessageArgHandler::class)
+        cmd: MessageChain
+    ): CmdReceipt { with(context) {
+        val sub = context.fork(reader = MessageReader(cmd))
+        CmdHandler.execute(sub)
+        print(sub.getOutput())
+        return SUCCESS(uploadFile = 2)
+    } }
+
+}

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

@@ -4,4 +4,5 @@ object Config {
     val CMD_PREFIX = arrayOf('.','。','/')
     val REPL_YES = arrayOf("y","ok","yes","好","是","好的","是的")
     val REPL_NO = arrayOf("n","no","nop","不","否","不是","不要")
+    const val MAX_OUTPUT_LEN = 720
 }