MiraiForum

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

    Yuanning 发布的帖子

    • RE: 开发不能使用第三方库吗?

      打包的时候把依赖也打包进去不就好了

      发布在 开发交流
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      @VatinaCharo
      ping命令的格式不是这样的,你应该在服务器上敲如下命令看能不能ping通

      ping rsshub.app
      

      本项目暂时不打算提供配置代理的功能,因为我过一段时间就开学了,开学之后可能就没啥时间了。所以打算在开学之前把rss订阅的最基本功能搞定,剩下的开学后再看情况。

      追番的话,论坛里已经有一个比较成熟的rss订阅插件了,而且好像已经有代理功能了,我也是逛论坛的时候才发现的(悲伤),你可以去看看他的简单的Rss订阅插件 已添加RssHub支持 番剧订阅Bt种子自动上传

      发布在 插件发布
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      @VatinaCharo
      先给出一条可能的原因:你的这个链接我去试了,我直连连不上这个网站,需要挂梯子才能连上。同理,你需要确保你开着mirai机器人的服务器最起码ping rsshub.app 这个网址能ping通,同时ping所用的链接时间不要太长(我不太清楚okhttp的默认超时时间是多少,不过一般来说只要网络正常应该是够用的),否则可能会获取数据超时,进而抛出你看到的异常。

      我去看了这个rss网站,在0.2.0版插件中,这个rss订阅他的item的title,description,pubDate,link这四个属性是可以进行替换的,只要不去替换其他的属性,在“替换item通知属性”的问题上不会出问题。

      (如果想要测试插件是否有bug的话,可以手动修改RssDate参数中的notifideDate和minNotifideDate,插件会对比这两个日期新的item进行通知,注:minNotifideDate为所有subscriber的notifideDate的最旧的值,如notifideDate一个为2021年,一个为2022年,minNotifideDate则是2021年)

      (目前插件0.3.0版正在适配该网站,以及rss2.0协议中channal和item标签的必须元素)

      发布在 插件发布
      Y
      Yuanning
    • 开发mcl插件时,集成mybatis进行开发的方法

      注:在本文中,所有PluginMain无特殊说明均指代继承了KotlinPlugin抽象类的子类,也即该插件的主类。

      开发环境:gradle:7.6版,jdk:eclipse-temurin-17,kotlin版本:1.8.0,mirai-console版本:2.14.0,mybatis依赖版本:3.5.11(org.mybatis:mybatis:3.5.11)

      使用该方法配置成功的插件项目:rss_subscribe-订阅rss更新的插件,如果一切顺利的话,等发布0.3.x版本时就能看到了该项目集成mybatis了(目前版本是0.2.0)(虽然估计到时候集成了也没用上)

      好了,作者罗嗦完了,接下来进入正题

      首先我们要达成一个共识,即直接都用mybatis官方的配置文件直接进行配置是可行的,但我们开发插件是为了给别人用,因此不能在mybatis-config.xml文件中把数据库链接的配置写死,但是在我探索出来的方法中,使用mybatis-config.xml进行配置是必须的,否则调用Mapper接口时,会抛出无法绑定Mapper.xml文件之类的异常。

      因此对于在mybatis-config.xml文件中把数据库链接的配置写死和自行修改数据库链接配置中的不同点在于,拦截官方样例中如下方式

      String resource = "org/mybatis/example/mybatis-config.xml";
      InputStream inputStream = Resources.getResourceAsStream(resource);
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      

      通过输入流得到的configuration对象实例,修改其中的数据库链接配置,然后在将修改后的configuration移交给SqlSessionFactoryBuilder().build,即

      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
      

      首先我们要根据官方样例,生成一个具有正确的数据库链接配置的environment:

      DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
      TransactionFactory transactionFactory = new JdbcTransactionFactory();
      Environment environment = new Environment("development", transactionFactory, dataSource);
      

      代码样例(仅作为参考,请自行修改):

      fun getEnvironmentOfConfiguration() : Environment{
          val dataSource = PooledDataSource()
          dataSource.username = RssConfig.mysqlConfig.userName
          dataSource.password = RssConfig.mysqlConfig.password
          dataSource.url = RssConfig.mysqlConfig.url
          dataSource.driver = RssConfig.mysqlConfig.driver
          val transactionFactory: TransactionFactory = JdbcTransactionFactory()
          val environment = Environment("development", transactionFactory, dataSource)
          return environment
      }//得到具有正确的数据库链接配置的environment实例
      

      其次我们用输入流生成configuration实例,然后更改configuration实例的environment为自己手动生成的environment,最后我们将修改好的configuration交给SqlSessionFactoryBuilder().build方法

      private var sqlSessionFactory : SqlSessionFactory // MybatisUtil的用于保存全局唯一sqlSessionFactory的变量
      
      init {
          val thread = Thread.currentThread()
          val oc = thread.contextClassLoader
          try {
              thread.contextClassLoader = PluginMain::class.java.classLoader //此处切换类加载器是为了正确加载resource中的所有xml配置文件,包括Mapper.xml
      
              val resource = "mybatis-config.xml"
              val inputStream: InputStream = Resources.getResourceAsStream(resource)!! //TODO 此处强制转为非空,因为mybatis-config.xml文件是存在的,以及类加载器是正常的,我们确定可以读取到该配置文件
              val configuration = XMLConfigBuilder(inputStream).parse() //从inputStream流生成configuration实例
              configuration.environment = getEnvironmentOfConfiguration() //修改configuration的environment的值为自己需要的值
              sqlSessionFactory = SqlSessionFactoryBuilder().build(configuration)
      
          } finally {
              thread.contextClassLoader = oc
          }
      }// MybatisUtil的构造函数的执行体,因为MybatisUtil是object,所以第一次调用MybatisUtil时会自动调用该段代码
      

      当然,为了方便,我们可以封装一个切换线程类加载器的方法:

      fun changeClassLoader(block : () -> Unit){
          val thread = Thread.currentThread()
          val oc = thread.contextClassLoader
          try {
              thread.contextClassLoader = PluginMain::class.java.classLoader
      
              block()
      
          } finally {
              thread.contextClassLoader = oc
          }
      }
      

      此时,我们得到了可供参考的MybatisUtil.kt的参考版本:

      object MybatisUtil {
      
          private lateinit var sqlSessionFactory : SqlSessionFactory
      
          fun getEnvironmentOfConfiguration() : Environment{
              val dataSource = PooledDataSource()
              dataSource.username = RssConfig.mysqlConfig.userName
              dataSource.password = RssConfig.mysqlConfig.password
              dataSource.url = RssConfig.mysqlConfig.url
              dataSource.driver = RssConfig.mysqlConfig.driver
              dataSource.poolMaximumActiveConnections = 100
              dataSource.poolMaximumIdleConnections = 8
              val transactionFactory: TransactionFactory = JdbcTransactionFactory()
              val environment = Environment("development", transactionFactory, dataSource)
              return environment
          }//得到具有正确的数据库链接配置的environment实例
      
          init {
              ChangeClassLoaderUtil.changeClassLoader {
      
                  val resource = "mybatis-config.xml"
                  val inputStream: InputStream = Resources.getResourceAsStream(resource)!!//TODO 此处强制转为非空,因为mybatis-config.xml文件是存在的,以及类加载器是正常的
      
                  val configuration = XMLConfigBuilder(inputStream).parse()
                  configuration.environment = getEnvironmentOfConfiguration()
      
                  sqlSessionFactory = SqlSessionFactoryBuilder().build(configuration)
              }
          }
      
          fun getSqlSession():SqlSession{
              return sqlSessionFactory.openSession()
          }
      
      }
      

      mybatis-config.xml配置文件的参考版本:

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "https://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
      
          <mappers>
              <mapper resource="mapper/UserMapper.xml"/>
          </mappers>
      
      </configuration>
      

      注:由于configuration的environment是被我们拦截了下来,使用的我们自己生成的environment,所以在此处配置configuration标签的子标签environment是无效的,必须在MybatisUtil.getEnvironmentOfConfiguration()方法中手动修改对应参数,或将对应参数设计默认值后"映射"到Config类中,让插件使用者可以自己修改对应的配置

      致谢:
      关于如何切换类加载器的方法的文章:切换类加载器,解决Java Services 加载问题(大概也能解决Spring的上下文问题)
      以及让我找到上面那篇文章的文章:使用Mybatis时找不到配置文件

      发布在 开发交流
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      不知道为什么,有的rss会被自动渲染成html格式(里面会有html标签),用Jmeter进行测试的时候是正常的格式,如果你访问时是html格式的话,也可以考虑发我一下,看看Jmeter里是xml格式还是html格式。

      发布在 插件发布
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      @VatinaCharo

      只要一打开这个链接就返回且只返回xml格式的内容就行(用f12看一眼,不能是html格式,必须是xml格式),可以不需要.xml后缀,因为默认是按照xml解析的(汗)。

      但是刚刚发现了一个问题,rss格式的xml内子标签都有什么是不固定的,我以为rss格式内子标签都是固定的,所以目前rssconfig的 ${title}替换item的title 这种替换必须看你要订阅的rss的item项里有没有这个子标签,如果没有还要替换的话,我没有在那里捕获异常,不知道他会抛出什么异常,有可能会导致mcl直接退出。(我最开始是照着www.miobt.com的rss订阅做的,以为rss规范都是那个格式的)

      你可以发我一个公网能打开的链接,我去看看,如果能适配的话会优先适配(只要满足上述两个条件的话,应该可以直接拿来用,你不确定的话发我一个公网能打开的可供参考的链接,我看一下再告诉你能不能用)

      发布在 插件发布
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      0.2.0版已更新,更新了检查rss更新的逻辑,同时release了打包好的jar文件

      发布在 插件发布
      Y
      Yuanning
    • RE: rss_subscribe —— 订阅rss更新的插件

      因为第一版在准备发布前才发现插件目前不适用于查询结果超过20条的这个问题,所以暂时没有在项目中发布release,打算等bug修好再发布release,如果有需要可以clone后自行打包

      发布在 插件发布
      Y
      Yuanning
    • rss_subscribe —— 订阅rss更新的插件

      项目地址:
      github地址
      gitee地址

      rss-subscribe

      Mirai Console 插件, 使用 Kotlin + Gradle.

      订阅rss更新的项目√

      项目的0.3.0版本,对item标签的title,link,description元素可以在config中进行替换

      项目使用方式:

      该插件第一次运行结束后,会生成config/top.yuanning.rss_subscribe/RssConfig.yml和data/top.yuanning.rss_subscribe/RssData.yml两个文件,

      RssConfig样例如下:

      # 订阅内容有更新时发送的消息的模板,
      # ${title}替换item的title
      # ${link}替换item的link
      # ${description}替换item的description
      # ${pubDate}替换item的pubDate
      subscribeInfoSendMessage: "订阅内容更新了\n标题:${title}\n链接:${link}\n更新时间:${pubDate}"
      # 发送消息的周期,即发送消息后,经过该时间段后才会继续执行订阅任务,单位:毫秒
      sendMessageTime: 5000
      # 检测的周期,检测结束后,经过该时间段才会开始下一轮检测,单位:毫秒
      checkTime: 60000
      # 最多通知更新的数量,最大值为20,建议不要设置的过大,防止封号,最小值为1
      maxNotifyNum: 2
      # mysql连接配置,都是字符串格式,用不上,不用管这个配置,
      # 这只是作者突然抽风想试试能不能把mirai插件集成mybatis后的结果
      # 项目暂时还用不到(以后大概率也不会用到)mysql数据库,所以在目前版本中,即使不配置这个,也不会报错
      # 该配置不支持启动后修改,必须在mcl关闭的情况下修改
      mysqlConfig: 
        driver: com.mysql.cj.jdbc.Driver
        url: 'jdbc:mysql://localhost:3306/temp'
        userName: root
        password: root
      

      RssData样例如下:

      subscribes: 
        - name: Lolihouse组的《别当欧尼酱》
          targetUrl: 'https://www.miobt.com/rss-%E5%88%AB%E5%BD%93%E6%AC%A7%E5%B0%BC%E9%85%B1+LoliHouse.xml'
          subscribers: 
            - type: friend
              id: 123456
              notifideDate: '2023年02月10日-02时54分24秒'
            - type: group
              id: 123456
              notifideDate: '2023年02月10日-02时54分24秒'
          initialized: false
          minNotifideDate: '2023年02月10日-02时54分24秒'
      

      如果想要添加订阅,则需要修改RssData,

      name是自定义订阅的名称(目前没用上)

      targetUrl是订阅rss的地址,要求是访问该地址是返回且只返回rss订阅信息(xml格式)

      subscribers是订阅者集合,其中type只有两种值:friend或group,id则是对应的qq号或群号,

      其他配置项为插件自用,不建议修改,用于判断是否需要通知

      注意事项:

      在第一次加载插件生成config以及data文件后请退mcl,修改config与data为想要的且正确的内容后重新启动mcl,
      当然,有插件使用经验的人可以直接拷贝上面的样例,改改拿去用

      目前版本为0.3.0,在1.0.0版本以前,项目的每次0.x.0版本的更新都有可能会有较大的更新,导致上一个0.x-1.0版本的config,data文件不能直接拿来用,在版本升级的过程中请注意
      本插件的使用有一个前提条件,就是rss订阅中,item的属性中必须包含且直接包含pubDate属性,否则按照目前逻辑无法检查是否需要通知,会出现未经测试的bug。(比如密柑计划的rss订阅的item子属性就是没有直接包含pubDate属性的,因此该插件无法使用于订阅密柑计划的rss)

      同时注意:RssData中的样例配置是无法通知到的,如果保留的话会导致每次项目检查更新时都会尝试通知该样例配置的subscriber,影响性能

      功能上的注意:本插件目前版本的作用更多的是倾向于通知有更新了,让使用者去看更新了啥,而不是插件通知都更新了哪些内容。

      比如,在检测更新的间隔内,网站更新了6条数据,如果配置了maxNotifyNum为2,那么本插件只会通知两条数据,剩下的四条没通知到的数据不会再进行通知

      换句话说,作为使用者,如果在某个时刻接受到了插件的通知,那么这个时刻之前的通知,就算没有通知到,也不会再通知了

      本软件的后续版本可能会考虑集成mybatis,从而对已通知内容进行记录,才有可能保证不会有没通知到的更新

      项目情况概述:

      目前的通知策略:如果该subscriber通知不到(有可能是因为没有bot能联系上该好友/群聊)则会跳过该subscriber,等到下一次检查更新时再尝试通知
      因此请确保所有的作为订阅者的联系人/群都在bot(如果登录了多个bot只需要在任意一个bot)的好友列表/群列表中

      如果发现bug作者看到了的话会进行修复

      虽说功能测试正常,但是用起来不方便,目前只能通过修改data文件的方式修改订阅。以后1.x.x版本开始可能会做通过控制台和通过qq聊天的方式,根据权限修改订阅

      发布在 插件发布
      Y
      Yuanning
    • RE: mcl-kotlin插件-如何关闭ServerSocket以及里面的while循环

      好的,非常感谢,我去了解学习一下kotlin的协程方面的东西

      发布在 开发交流
      Y
      Yuanning
    • mcl-kotlin插件-如何关闭ServerSocket以及里面的while循环

      (kotlin新手求助)
      我在onEnable中初始化了并监听了一个ServerSocket,想要在onDisable函数中关闭它,但是失败了

      报错大概信息如下:
      MIRAI CONSOLE CRASH REPORT.
      Console has take too long to shutdown.

      我的onDisable函数是这么写的

          override fun onDisable() {
              logger.info { "准备关闭socket" }
              serverToClose?.close()
          }
      

      注:
      serverToClose的初始化操作如下:

      PluginMain.launch {
                  try {
                      println("Socket服务器开始运行...")
                      val serverSocket = ServerSocket(12345)
                      serverSocketToClose = serverSocket
                      while (true) {
                          val socket = serverSocket.accept()
                          println("接受了一个socket链接")
                          Thread(ServerHandler(socket)).start()
                      }
                  } catch (e: Exception) {
                      e.printStackTrace()
                  }
              }
      

      但是在“准备关闭socket”这句话输出前就已经报错了,也就是我貌似无法在onDisable中关闭ServerSocket以及试图退出while循环

      不知道应该怎么在mcl退出时,关闭之前的ServerSocket以及while循环,从而正常退出mcl。

      求大佬指点

      发布在 开发交流
      Y
      Yuanning
    • RE: 有关AGPL开源许可的问题

      卧槽,神奇的想法,开源了,但开源了个寂寞
      (虽然我也不懂开源许可证,但感觉这个想法真的很灵性

      发布在 摸鱼区
      Y
      Yuanning
    • 咨询关于ipv6

      这个项目目前支持ipv6么,如果不支持,以后会考虑支持么(问题背景:今天在一台只有ipv6的便宜国外服务器上跑mcl,看报错说是网络连接失败,所以过来咨询一下,为了了解一下可能是哪方面除了问题)(问题的末尾,趁机感谢大佬的贡献,降低了插件编写的门槛,像我这种刚学java一个月的都能写出代码和功能都很简单的插件了)

      发布在 开发交流
      Y
      Yuanning
    • 1 / 1