From 4c384cc991c2266621aa675da5298bb3ca763a57 Mon Sep 17 00:00:00 2001 From: LamGC Date: Sat, 19 Dec 2020 14:08:27 +0800 Subject: [PATCH] =?UTF-8?q?[Add][Update][Document]=20Framework-API,=20Proj?= =?UTF-8?q?ect=20=E6=9B=B4=E6=96=B0Readme=E6=96=87=E6=A1=A3=E5=86=85?= =?UTF-8?q?=E5=AE=B9;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Update] Project/README.md 更新一些贡献内容, 修正文档问题; [Update] Framework-API/Readme.md 补充框架生命周期内容; [Add] Framework-API/Quick-Start.md 添加尚未完成的快速开始教程文档, 计划在 3.0.0 正式版发布时完成; --- .../Quick-Start.md | 186 ++++++++++++++++++ ContentGrabbingJi-framework-api/Readme.md | 21 +- README.md | 13 +- 3 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 ContentGrabbingJi-framework-api/Quick-Start.md diff --git a/ContentGrabbingJi-framework-api/Quick-Start.md b/ContentGrabbingJi-framework-api/Quick-Start.md new file mode 100644 index 0000000..e54910d --- /dev/null +++ b/ContentGrabbingJi-framework-api/Quick-Start.md @@ -0,0 +1,186 @@ +# Quick Start:开发一个框架组件 # +> 提示:标题写成“框架组件”是有原因的,可能你并不是真的开发了某个平台的框架, +>而是开发了一个将 ContentGrabbingJi 与某平台框架连接在一起的一个组件,在这块地方纠结下去没有意义。 + +注意,开发框架组件,你不仅需要 Java (或其他与 Java 有兼容性的语言)的开发经验,你还需要会使用 Maven,Gradle 这些编译工具。 +一旦你准备就绪了,就可以开始开发一个框架组件了! + +> 嘿!如果你想开发一个框架组件,然后放出来给大家使用,那么你就要对这个框架组件负责点, +>因为大家会使用你的组件,就代表对你,和你的组件有信心,有期望,认为你做的很好, +>所以你不能辜负大家对你的期望,坚持维护框架组件,或者当你无法继续维护组件(项目)时, +>大胆的跟大家说明清楚,对框架组件项目存档,或者转手让一个信得过的人帮你继续维护它! + +## 开始 ## +开始时,你需要创建一个 `framework.json` 来描述你的框架,告诉用户这个框架组件叫什么,有什么用途,谁做的,适配了什么平台。 +一个完整的 `framework.json` 示例如下(使用 ContentGrabbingJi 官方开发的 QQ-Mirai 框架组件作为示例): +```json5 +{ + // 【必填】框架组件的 Id,必须是唯一的。(只能用大小写字母和半角符号,最好只用"_"、"-"和".") + "id": "cgj-mirai", + //【可选】 对框架组件的说明内容,比如介绍这个组件,使用组件需要注意什么.....之类的。 + "description": "ContentGrabbingJi官方实现的, 基于 Mirai 框架的QQ平台组件", + // 【必填】框架组件的版本号,建议遵循 语义化版本控制 规范。 + "version": "3.0.0-alpha", + // 【可选】对 ContentGrabbingJi 的最低要求版本。 + "requiresVersion": "3.0.0", + // 【可选】组件由谁提供(例如:xxx开发者,xxx工作室)。 + "provider": "Github@LamGC, Github@mamoe", + // 【可选】组件以什么协议提供使用? + "license": "AGPL-3.0", + // 【必填】组件的主类是什么?(带有包名的类名) + "frameworkClass": "net.lamgc.cgj.bot.framework.mirai.MiraiFramework", + // 【可选】组件需要依赖什么其他的组件?(填写其他框架组件的 Id) + "dependencies": [ + ], + // 【必填】组件所支持的平台是什么?(规范请参见【平台信息】章节) + // 如果不需要处理消息,无用户命令交互,可设为【Unknown】(identify 为【unknown】,小写的就好) + "platform": { + "name": "Tencent QQ", + "identify": "qq" + }, + // 【可选】开发组件的作者(如果人数过多,可以只填写主要开发者,不一定要填全,看你们选择) + "authors": [ + { + // 【必填】该作者的名称 + "name": "LamGC", + // 【可选】有没有相关的网页?(比如 Github、Blog 等) + "url": "https://github.com/LamGC", + // 【可选】联系该作者所使用的邮箱。 + "email": "lam827@lamgc.net" + } + ], + // 【可选】如果框架使用文本机器人功能码(比如【CQ码】之类的)的信息。 + "botCode": { + // 【可选】如果有相关功能码,填写所有功能码格式的匹配用正则表达式。 + "patterns": [ + "(?:\\[mirai:([^:]+)\\])", + "(?:\\[mirai:([^\\]]*)?:(.*?)?\\])", + "(?:\\[mirai:([^\\]]*)?(:(.*?))*?\\])" + ] + } +} +``` + +也就是说,你需要准备的最小的 `framework.json` 必须是这样的: +```json5 +{ + // 【必填】框架组件的 Id,必须是唯一的。 + "id": "cgj-mirai", + // 【必填】框架组件的版本号,建议遵循 语义化版本控制 规范。 + "version": "3.0.0-alpha", + // 【必填】组件的主类是什么?(带有包名的类名) + "frameworkClass": "net.lamgc.cgj.bot.framework.mirai.MiraiFramework", + // 【必填】组件所支持的平台是什么?(规范请参见【平台信息】章节) + "platform": { + "name": "Tencent QQ", + "identify": "qq" + } +} +``` +只要 `framework.json` 配置了以上内容,ContentGrabbingJi 就会将其视为一个框架组件,并加载启动。 + +## 框架的主类 ## +光是编写了 `framework.json` 还远远不够,你还需要一个框架主类来让 ContentGrabbingJi 启动你的框架组件。 +框架主类并不像一般的 Java 应用一样,在某个类里写上 `main(String[])` 方法就可以了,你需要继承 `Frameowrk` 类。 +```java +package org.example; + +import net.lamgc.cgj.bot.framework.Framework; +import net.lamgc.cgj.bot.framework.FrameworkContext; +import net.lamgc.cgj.bot.framework.FrameworkDescriptor; +import org.pf4j.PluginWrapper; + +import java.io.File; + +class SimpleFrameworkMain extends Framework { + + /** + * 由 FrameworkManager 执行的构造方法. + *

不要在构造方法内做任何处理. 如果你需要, 请在 {@link #initial()} 进行初始化. + * + * @param wrapper 包含框架运行期间需要使用对象的包装器. + * @param dataFolder 框架专属的数据存取目录. + * @param context 框架运行上下文, 由不同 ContentGrabbingJi 实例加载的 Framework 所获得的的 Context 是不一样的. + */ + public SimpleFrameworkMain(PluginWrapper wrapper, File dataFolder, FrameworkContext context) { + super(wrapper, dataFolder, context); + // 看到上面的文档说了什么了吗?不要在这里做任何的操作!(即使你想初始化组件) + } + + @Override + protected void initial() { + // 这里是初始化方法!当你的框架组件被加载后,首先会调用这个方法。 + // 可以在这里执行任何初始化的操作,但注意:不要让你的框架组件开始工作,因为时候未到! + + // 还记得你刚刚写的 framework.json 吗,ContentGrabbingJi 并没有忘记它。 + // framework.json 将会直接解析并生成一个 FrameworkDescriptor 对象, + // 你可以通过【getDescriptor()】获取它,通过这个对象获取你在 framework.json 编写的任何内容。 + FrameworkDescriptor descriptor = getDescriptor(); + + // Framework 提供了一个日志记录器,可以很方便的记录日志内容。 + // 使用【log】变量开始使用它! + log.info("框架 {} 正在启动!当前版本为 {},由 {} 提供。", + descriptor.getPluginId(), + descriptor.getVersion(), + descriptor.getProvider()); + + // 千万不要随便在任何地方存放文件,这样会给用户带来麻烦的。 + // 使用【getDataFolder()】可以获取到 ContentGrabbingJi 为框架组件分配的存储路径,这个路径是专属于框架组件的! + File dataFolder = getDataFolder(); + log.info("框架数据的存放路径:{}", dataFolder.getAbsolutePath()); + + log.info("框架初始化完成!"); + } + + @Override + public void start() { + // 是时候让你的框架组件开始工作了! + // 当本方法被调用时,代表已经到了合适的时机让你的框架组件开始处理来自平台用户的功能请求了。 + // 你可以在这里【使用机器人帐号登录平台】,【连接第三方机器人框架以接收平台消息】等。 + + log.info("框架已启动!"); + } + + @Override + public void stop() { + // 该让你的框架组件停下来了。 + // 当本方法被调用时,需要让你的框架组件停止工作(比如退出平台帐号,断开与第三方机器人框架的连接)。 + + } + + @Override + public void delete() { + // 当你的框架组件要被删除时,本方法将会被调用。 + // 在这里选择是否清理框架组件的数据,或者说清理第三方运行时等等。 + // 如果你要清除包含用户数据的框架组件数据,建议你认真询问一下用户是否需要删除(用户体验提升!)。 + + } +} +``` + +当你继承了 `Framework` 类后,别忘记在 `framework.json` 加上主类的类路径(比如示例中的类路径为 `org.example.SimpleFrameworkMain`)! +```json5 +{ + "id": "simple-framework", + "version": "0.0.1-SNAPSHOT", + "frameworkClass": "org.example.SimpleFrameworkMain", + "platform": { + "name": "Unknown", + "identify": "unknown" + } +} +``` +这样你就创建好一个框架主类了。 + +## 处理消息 ## +框架并不需要过多的处理消息,但是需要将框架的消息形式转换成 ContentGrabbingJi 的消息形式。 +以 QQ 平台为例,大多数基于 C/C++ 的机器人框架对一些特殊消息以【功能码】(例如 酷Q机器人 的 CQ 码)的形式表示在文本消息内容中(常见的功能码有【Image】,【At】和【Reply】)。 +但是这对 ContentGrabbingJi 来说:太难理解了。 +因此,框架虽然不需要处理消息并执行命令,但是还需要将接收到的消息(可能是文本形式的,或者是其他形式的)转换成 ContentGrabbingJi 所能处理的形式。 + +## 我可不可以不处理消息? ## +是的,你可以不处理消息! +ContentGrabbingJi 计划添加运行监测组件,用于遥测应用的整体运行状态。 +所以你不一定需要让框架组件处理消息,用于接收运行监测数据,并发送到运维端也是可以的! +> 官方运行监测组件计划在 ContentGrabbingJi v3.10.0 发布后开始开发。 + diff --git a/ContentGrabbingJi-framework-api/Readme.md b/ContentGrabbingJi-framework-api/Readme.md index ab2d8c9..b8c023b 100644 --- a/ContentGrabbingJi-framework-api/Readme.md +++ b/ContentGrabbingJi-framework-api/Readme.md @@ -3,6 +3,23 @@ 我为 ContentGrabbingJi 设计了一套**框架抽象层**(`Framework Abstraction Layer`,简称 `FAL`)。 FAL 用于为各个平台的框架提供统一的接口,保证了 ContentGrabbingJi 对各个平台框架的兼容性, 并由 ContentGrabbingJi 统一管理其**生命周期**。 -> 备注:当 QQ 机器人发生大动摇(CoolQ 机器人因个别原因关闭)的时候,我更佳确信了创建 FAL 的决定是正确的。 +> 备注:当 QQ 机器人发生大动摇(CoolQ 机器人因特别原因关闭,导致大量机器人平台接连关闭)的时候, +>我更加确信了创建 FAL 的决定是正确的。 + +开始开发一个框架组件: ![Quick-Start](./Quick-Start.md) + +## 框架的生命周期 ## +ContentGrabbingJi 的框架系统基于 [Pf4j](https://github.com/pf4j/pf4j) 。 +框架的生命周期将由 ContentGrabbingJi 管理。 +由于框架系统基于 Pf4j,所以框架拥有以下生命周期: +- `CREATED`:框架已被识别并确定可以进行加载(此时框架文件已被读取并成功解析了 FrameworkDescriptor)。 +- `DISABLED`:框架虽然被加载,但由于某些原因(例如不符合系统最低版本要求,被手动禁用)而被禁用。 +- `RESOLVED`:框架已经成功加载并做好了启动的准备,此时框架已经初始化完成。 +- `STARTED`:框架的 `start()` 被成功调用,视为已启动,此时框架可开始接收处理用户的使用请求。 +- `STOPPED`:框架的 `stop()` 被成功调用,视为已停止, +此时框架应该停止接收处理请求,关闭与处理相关的功能(例如断开平台连接,停止与第三方机器人平台的通讯等)。 +- `FAILED`:框架启动时出错。 + +由于 ContentGrabbingJi 并不能完全控制框架的运行和启停, +因此希望框架能够遵守生命周期(如果平台的连接无法关闭,或关闭后重新连接会很麻烦,那么你可以停止向框架投递事件,以达到停止工作的效果)。 -... diff --git a/README.md b/README.md index 37afbbf..fb672e7 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,19 @@ ## Usage ## ## Contributing ## +> 本项目遵循[语义化版本控制 SemVer](https://semver.org/) 规范, +>不同版本号之间的兼容性将依照 SemVer 规范得到保证(不会出现 1.0.1 版本不兼容 1.0.0 版本,或 1.2.0 版本不支持 1.1.0 版本的情况)。 +欢迎你为 ContentGrabbingJi 项目作出贡献! +在开始作出贡献前,请阅读 [贡献者公约 (Code of conduct)](./CODE_OF_CONDUCT.md), +一旦你开始为本项目作出贡献(无论通过何种形式),将会视你为同意遵守贡献者公约,并接受因违反贡献者公约而带来的后果。 + +如果你准备好开始为本项目做出贡献(或正在做出贡献)时,请阅读并遵守[贡献准则](.github/CONTRIBUTING.md)。 ## License ## -ContentGrabbingJi 是遵循 GNU Affero General Public License v3.0 协议开源的, -完全免费的项目(软件),任何人(或组织)不允许违反开源协议来使用本项目。 ->通过使用本项目为用户提供服务时,请注意遵守服务使用者所在地的法律法规,因违规使用本项目而带来的后果自行负责。 +ContentGrabbingJi 是遵循 GNU Affero General Public License v3.0 协议(下称 AGPLv3)开源的, +完全免费的项目(软件),任何人(或组织)不允许违反 AGPLv3 开源协议来使用本项目。 +> 使用者通过使用本项目为用户提供服务时,请注意遵守服务使用者所在地的法律法规,因违规使用本项目而带来的后果由使用者自行负责。 ``` Copyright (C) 2020 LamGC