MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接
    1. 主页
    2. kagg886
    K
    • 资料
    • 关注 0
    • 粉丝 0
    • 主题 10
    • 帖子 24
    • 最佳 2
    • 有争议的 0
    • 群组 0

    kagg886

    @kagg886

    3
    声望
    45
    资料浏览
    24
    帖子
    0
    粉丝
    0
    关注
    注册时间 最后登录

    kagg886 取消关注 关注

    kagg886 发布的最佳帖子

    • Seiko——将使用Mirai-CoreAPI的应用直接迁移到Android上

      一.标题没看懂是怎么回事

      如果你的项目仅使用了Mirai-CoreAPI,但最近希望将其迁移进Android中,那么Seiko可以解决滑动验证,Bot保活等问题。

      二.了解更多

      前往Seiko的Github仓库预览源代码
      前往Seiko的Realease下载Seiko

      发布在 项目发布
      K
      kagg886

    kagg886 发布的最新帖子

    • RE: 使用 Spring Websocket 托管 Overflow 默认的WebSocket实现

      补充:

      1. 由于网络延迟原因,可能需要增大overflow对onebot api响应的等待时间,在启动类的main方法添加属性以增大等待时间:
      System.getProperties().setProperty("overflow.timeout",1.minutes.inWholeMilliseconds.toString())
      
      1. 由于Spring Websocket分包问题,需要增大Tomcat默认处理ws的缓冲区,推荐将发送图片大小压缩到2M以内,同时在启动类添加属性:
      System.getProperties().setProperty("org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE","5242880")
      
      发布在 摸鱼区
      K
      kagg886
    • 使用 Spring Websocket 托管 Overflow 默认的WebSocket实现

      适用于只使用overflow-core开发bot,并且使用spring自带的IoC能力的一套ws解决方案。可以避免早期overflow版本中反向websocket存在的各种问题。

      1. 定义handler
      class WSHandler : WebSocketHandler, IAdapter {
          override val scope = CoroutineScope(Dispatchers.IO) + SupervisorJob()
      
          override val logger: Logger = LoggerFactory.getLogger(ActionHandler::class.java)
          override val actionHandler: ActionHandler = ActionHandler(scope.coroutineContext[Job], logger)
      
          init {
              top.mrxiaom.overflow.internal.Overflow.setup()
              log.info("Youmu WebSocket 已接管默认Overflow Bot Handler,WSBufferSize: ${System.getProperty("org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE")}")
          }
      
          override fun afterConnectionEstablished(session: WebSocketSession) {
              //在这里进行鉴权
              scope.launch {
                  val botImpl = Bot(
                      SpringDelegatedWebSocket(session),
                      BotConfig(),
                      actionHandler
                  )
      
                  val versionInfo = botImpl.getVersionInfo()
                  if (botImpl.onebotVersion == 12) {
                      session.close(CloseStatus.PROTOCOL_ERROR.withReason("不支持的onebot版本:12"))
                      return@launch
                  }
      
                  net.mamoe.mirai.Bot.getInstanceOrNull(botImpl.id)?.getOriginChannel()
                      ?.close(CloseStatus.NORMAL.withReason("当前连接下线"))
      
                  val bot = with(BotWrapper) {
                      val result = runCatching {
                          botImpl.wrap(
                              configuration = BotConfiguration {
                                  botLoggerSupplier = {
                                      LoggerFactory.getLogger("Bot#${botImpl.id}").asMiraiLogger()
                                  }
                                  networkLoggerSupplier = {
                                      LoggerFactory.getLogger("Net#${botImpl.id}").asMiraiLogger()
                                  }
                              }
                          )
                      }
                      if (result.isFailure) {
                          session.close(CloseStatus.PROTOCOL_ERROR.withReason("无法实例化bot"))
                          return@launch
                      }
                      result.getOrThrow()
                  }
                  log.info("Bot ${bot.id} 已连接,协议版本信息:$versionInfo")
                  net.mamoe.mirai.Bot._instances[botImpl.id] = bot
              }
          }
      
          override fun handleMessage(session: WebSocketSession, message: WebSocketMessage<*>) {
              if (message is TextMessage) {
                  val text = message.payload
                  onReceiveMessage(text)
              }
          }
      
          override fun handleTransportError(session: WebSocketSession, exception: Throwable) {
          }
      
          @OptIn(MiraiInternalApi::class)
          override fun afterConnectionClosed(session: WebSocketSession, closeStatus: CloseStatus) {
              val bot = net.mamoe.mirai.Bot.instances.find {
                  it.getOriginChannel() == session
              }
              if (bot !== null) {
                  bot as BotWrapper
                  bot.eventDispatcher.broadcastAsync(BotOfflineEvent.Dropped(bot, cause = RuntimeException("连接断开")))
                  net.mamoe.mirai.Bot._instances.remove(bot.id)
                  log.info("${bot.id}断开连接")
              }
          }
      
          override fun supportsPartialMessages(): Boolean = false
      }
      
      1. 定义ws session的wrapper。overflow中未使用的方法均可以使用TODO替代。
      class SpringDelegatedWebSocket(val delegated: WebSocketSession) : WebSocket {
          override fun close(p0: Int, p1: String?) {
              delegated.close(CloseStatus(p0, p1))
          }
      
          override fun close(p0: Int) {
              delegated.close(CloseStatus(p0))
          }
      
          override fun close() {
              delegated.close()
          }
      
          override fun closeConnection(p0: Int, p1: String?) {
              delegated.close(CloseStatus(p0, p1))
          }
      
          override fun send(p0: String?) {
              delegated.sendMessage(TextMessage(p0!!))
          }
      
          override fun send(p0: ByteBuffer?) {
              delegated.sendMessage(BinaryMessage(p0!!))
          }
      
          override fun send(p0: ByteArray?) {
              delegated.sendMessage(BinaryMessage(p0!!))
          }
      
          override fun sendFrame(p0: Framedata?) {
              TODO("Not yet implemented")
          }
      
          override fun sendFrame(p0: MutableCollection<Framedata>?) {
              TODO("Not yet implemented")
          }
      
          override fun sendPing() {
              delegated.sendMessage(PingMessage())
          }
      
          override fun sendFragmentedFrame(p0: Opcode?, p1: ByteBuffer?, p2: Boolean) {
              TODO("Not yet implemented")
          }
      
          override fun hasBufferedData(): Boolean {
              TODO("Not yet implemented")
          }
      
          override fun getRemoteSocketAddress(): InetSocketAddress = delegated.remoteAddress!!
      
          override fun getLocalSocketAddress(): InetSocketAddress = delegated.localAddress!!
      
          override fun isOpen(): Boolean = delegated.isOpen
      
          override fun isClosing(): Boolean = !isOpen
      
          override fun isFlushAndClose(): Boolean {
              TODO("Not yet implemented")
          }
      
          override fun isClosed(): Boolean = !isOpen
      
          override fun getDraft(): Draft {
              TODO("Not yet implemented")
          }
      
          override fun getReadyState(): ReadyState {
              TODO("Not yet implemented")
          }
      
          override fun getResourceDescriptor(): String {
              TODO("Not yet implemented")
          }
      
          override fun <T : Any?> setAttachment(p0: T) {
              TODO("Not yet implemented")
          }
      
          override fun <T : Any?> getAttachment(): T {
              TODO("Not yet implemented")
          }
      
          override fun hasSSLSupport(): Boolean {
              TODO("Not yet implemented")
          }
      
          override fun getSSLSession(): SSLSession {
              TODO("Not yet implemented")
          }
      
          override fun getProtocol(): IProtocol {
              TODO("Not yet implemented")
          }
      }
      
      1. 最后自行注册即可
      @Configuration
      @EnableWebSocket
      class WSConfig:WebSocketConfigurer {
          override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
              registry.addHandler(
                  WSHandler(),
                  "bot"
              )
          }
      }
      
      1. 补一个上文中出现的工具类
      @file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
      package top.kagg886.youmu.backend.socket
      
      import net.mamoe.mirai.Bot
      import org.springframework.web.socket.WebSocketSession
      import top.kagg886.youmu.bot.internal.spring.SpringDelegatedWebSocket
      import top.mrxiaom.overflow.internal.contact.BotWrapper
      import kotlin.reflect.KProperty1
      import kotlin.reflect.full.memberProperties
      import kotlin.reflect.jvm.isAccessible
      
      fun Bot.getOriginChannel(): WebSocketSession {
          val prop = BotWrapper::class.memberProperties.first { it.name == "implBot" } as KProperty1<BotWrapper, cn.evolvefield.onebot.client.core.Bot>
          prop.isAccessible = true
          val wrapper = prop.get(this as BotWrapper).channel
          return (wrapper as SpringDelegatedWebSocket).delegated
      }
      

      最后附赠一套使用此方案部署在公网上的反向websocket bot:

      wss://youmu.kagg886.top/bot

      接入教程见此:部署bot

      发布在 摸鱼区
      K
      kagg886
    • RE: jvm awt 图像处理入坑/退坑指南

      还是讲一下skiko吧(

      发布在 摸鱼区
      K
      kagg886
    • 舞萌DX开字母游戏插件

      注:虽然名字叫舞萌开字母,但是曲库是可以自定义的。即自定义的曲库也可以是别的引诱甚至是混合的

      一.下载地址

      https://github.com/kagg886/maimai-opening-song-game/releases

      二. 食用说明

      1. 在群内发送:舞萌开字母以开启一个新游戏。

        <注>:一个群仅允许运行一个猜曲名实例。

      2. 在群内发送:开字母 一个字 以获得部分提示

        <注>:这个字可以是数字可以是英文可以是标点符号甚至可以是日文

      3. 如果你知道了这是哪个曲子,那么请发送回答 id/别名/名字以进行回答,回答成功后该曲目将会被完全解禁。

      4. 重复2,3步骤,直到所有曲目完全解禁。此时会提示游戏结束,并放出猜正确曲目的排行榜

      5. 实在猜不出来了怎么办呢?发送公布答案以关闭这个游戏!

      三.配置文件,指令

      翻阅插件项目即可查看:项目地址

      四. 扣扣交流群

      973510746

      发布在 插件发布
      K
      kagg886
    • RE: 关于扫码登陆

      这个默认值是修改二维码状态刷新的时间
      你改的越少,onIntervalLoop()就调用的越频繁
      不过一般change的时候在CONFIRMED或CANCELLED的时候执行你的监听
      至于你说的关闭二维码页面,可以为关闭方法注册一个副作用,在onIntervalLoop中检测副作用并抛出UnsupportedQRCodeCaptchaException即可

      可以参考我写的扫码登录框架(
      https://github.com/kagg886/Seiko/blob/master/app/src/main/java/com/kagg886/seiko/bot/AndroidSolver.java

      发布在 开发交流
      K
      kagg886
    • RE: GroupYouWant —— 只允许用户加入其中一个联合群聊

      卧槽,好东西!冲了!

      发布在 插件发布
      K
      kagg886
    • RE: 和 mirai 娘贴贴!

      专属于miraier的浪漫(

      发布在 摸鱼区
      K
      kagg886
    • RE: SeikoDIC | 基于自制伪代码引擎的指令编写插件

      0.1.1已更新,支持在计算块中对初等函数求值,包括但不限于幂乘,三角函数,指对函数等

      发布在 插件发布
      K
      kagg886
    • 舞萌DX整合包

      有个朋友找我做一个,然后我就顺手做了一个(

      使用教程在压缩包里,
      压缩包加群下载:572360632
      QQ截图20230408205337.png

      发布在 其他项目发布
      K
      kagg886
    • RE: 使用最新版IDEA无法正常创建工程

      我使用gradle 7.X就好使了,你试试:
      设置搜索gradle,然后修改gradle版本至7.X后应用重载工程,应该就好使了

      发布在 开发交流
      K
      kagg886