Adachi-BOT
├── app.js # 主程序
├── config
│ ├── command.yml # 用户插件配置
│ ├── command_master.yml # 管理员插件配置
│ └── setting.yml # 基础配置
├── data
│ └── db # 数据库文件
├── resources # 资源目录
├── resources_custom
└── src
├── plugins # 插件
├── utils # 公共库
└── views # HTML
下面的 Patch 演示了如何添加一个插件。
From 8dad13377fb41f0fcbc44a1d2f818a7146dbf085 Mon Sep 17 00:00:00 2001
From: Qin Fandong <[email protected]>
Date: Sun, 7 Nov 2021 20:44:32 +0800
Subject: [PATCH] Hello World!
---
config_defaults/command.yml | 16 ++++++++++++++++
src/plugins/hello_world/index.js | 19 +++++++++++++++++++
src/plugins/master/index.js | 3 ++-
3 files changed, 37 insertions(+), 1 deletion(-)
create mode 100644 src/plugins/hello_world/index.js
diff --git a/config_defaults/command.yml b/config_defaults/command.yml
index e1240f5..4d66d20 100644
--- a/config_defaults/command.yml
+++ b/config_defaults/command.yml
@@ -192,6 +192,22 @@ gacha:
entrance:
- ^取消定轨
+hello_world:
+ enable: true
+ weights: 10099
+ regex:
+ - ^hello\sworld$
+ functions:
+ hello_world:
+ type: command
+ show: true
+ weights: 9999
+ name: hello world
+ usage:
+ description: 向你致以诚挚的问候
+ entrance:
+ - hello world
+
tools:
enable: true
weights: 99
diff --git a/src/plugins/hello_world/index.js b/src/plugins/hello_world/index.js
new file mode 100644
index 0000000..f7c0a0a
--- /dev/null
+++ b/src/plugins/hello_world/index.js
@@ -0,0 +1,19 @@
+import { checkAuth } from "../../utils/auth.js";
+import { hasEntrance } from "../../utils/config.js";
+
+async function doHelloWorld(msg) {
+ const message = `Welcome to world, ${msg.name} (${msg.uid}) !`;
+ await msg.bot.say(msg.sid, message, msg.type, msg.uid);
+}
+
+async function Plugin(msg) {
+ switch (true) {
+ case hasEntrance(msg.text, "hello_world", "hello_world"):
+ if (false !== (await checkAuth(msg, "hello_world"))) {
+ doHelloWorld(msg);
+ }
+ break;
+ }
+}
+
+export { Plugin as run };
diff --git a/src/plugins/master/index.js b/src/plugins/master/index.js
index 76e37a6..7cefe4d 100644
--- a/src/plugins/master/index.js
+++ b/src/plugins/master/index.js
@@ -63,7 +63,8 @@ async function Plugin(msg) {
await setAuth(msg, "menu", ...parsed);
await setAuth(msg, "prophecy", ...parsed);
await setAuth(msg, "roll", ...parsed);
- setAuth(msg, "quote", ...parsed);
+ await setAuth(msg, "quote", ...parsed);
+ setAuth(msg, "hello_world", ...parsed);
break;
}
case hasEntrance(msg.text, "master", "reply_auth"):
--
2.27.0
应用该 Patch 后,启动机器人,发送 QQ 聊天信息 hello world
则会得到回复 Welcome to world, <nickname> (<id>) !
。
除了 oicq 中原有的属性外,你还可以使用以下属性。
属性 | 内容 |
---|---|
msg.bot |
QQ Client |
msg.atMe |
有人 @ 机器人为 true ,否则为 false |
msg.uid |
消息发送者的 QQ 号 |
msg.gid |
群消息为群号,好友消息为 undefined |
msg.sid |
群消息为 msg.gid ,好友消息为 msg.uid |
msg.type |
群消息为 group ,好友消息为 private |
msg.name |
消息发送者的 QQ 昵称 |
msg.text |
依次去除了 @ 机器人的 CQ 码、命令前缀 config.prefixes 和行首空格的聊天文本 |
除了 oicq 中原有的属性外,你还可以使用以下属性。
方法 | 作用 |
---|---|
say |
发送一条消息 |
sayMaster |
给全体管理者发送一条消息 |
- 在
../config_defaults/command.yml
中添加命令入口。- 在
../src/plugins/
目录下创建插件目录并编写代码。
有以下几个全局变量包含了配置文件中的数据,可以在插件中直接使用。使用这些全局变量前确保仔细阅读了 ../src/utils/config.js
中的注释,清楚地了解你要用的数据结构。
变量 | 数据 |
---|---|
global.rootdir |
项目所在的目录 |
global.all |
command.yml 和 command_master.yml 的部分内容 |
global.command |
command.yml |
global.master |
command_master.yml |
global.artifacts |
artifacts.yml |
global.alias |
alias.yml |
global.config |
setting.yml 、greeting.yml |
global.eggs |
pool_eggs.yml |
如果你使用了这些全局变量,确保文件头用类似以下的注释注明用到的全局变量,以避免 npm run check
将全局变量视为未声明的变量。
/* global rootdir, config */
/* eslint no-undef: "error" */
当消息为一条命令时,插件通过第一个参数 msg
接收的 oicq 的数据结构可能改变。原本的 CommonMessageEventData 中的 message
字段是一个可能包含这些类型的数组,但是为了统一 message
和 raw_message
字段,在 ../src/utils/load.js
中剔除了 TextElem 之外的所有类型并只保留一个 TextElem
。除此之外,将 raw_message
和 GroupMessageEventData 中仅存的 TextElem
进行了统一。最后 GroupMessageEventData
中新增了字段 atMe: boolean
来表示这条消息是否 @
了机器人。
除此之外, raw_message
和 message[0].data.text
依次去除了 @
机器人的 CQ 码、命令前缀 config.prefixes
和行首空格。
在 ../src/utils/database.js
中使用 lodash 封装了 lowdb 。
import db from "../../utils/database.js";
初始化名称为 name
的数据库。如果数据库已存在,加载其数据;如果数据库不存在,创建空数据库。
default
默认设置为 { user: [] }
。
db.init(name: string, default?: object);
在
../src/utils/init.js
中使用,以便启动时初始化。
在数据库 name
中判断 path
是否存在。
db.has(name: string, ...path);
对应
lodash.hasIn
。
在数据库 name
中的 key
对应的 Array 中,检测所有的索引 index
在是否包含值 value
。
db.includes(name: string, key: string, index: string, value: any);
对应
lodash.includes
。
index
返回值 undefined
key
对应的 Arrayobject
key
对应的 Array 中,获取包含索引index
的对象
db.get(name: string, key: string, index?: object);
对应
lodash.get
和lodash.find
。
在数据库 name
中的 key
对应的 Array 中,插入一条数据 data
。此方法自动调用 db.write
。
db.push(name: string, key: string, data: object);
对应
lodash.push
。
在数据库 name
中的 key
对应的 Array 中,将包含索引 index
的对象更新为 data
。此方法自动调用 db.write
。
只更新
data
中包含的 pair ,不会修改其他数据。
db.update(name: string, key: string, index: object, data: object);
对应
lodash.assign
。
把数据库 name
中的 key
对应的数据设置为 data
。此方法自动调用 db.write
。
db.set(name: string, key: string, data: any);
对应
lodash.set
。
在数据库 name
中的 key
对应的 Array 中,将包含索引 index
的对象删除 。此方法自动调用 db.write
。
db.remove(name: string, key: string, index: object);
对应
lodash.reject
。
把数据库 name
的数据写入磁盘,一般无须手动调用。
db.write(name: string);
下面的代码演示了如何使用这些数据库 API 。
import db from "../../utils/database.js";
async function func () {
/* some code */
await db.init("info");
await db.has("info", "user", 0, "uid");
await db.includes("info", "user", uid);
await db.get("info", "user", { uid });
await db.get("info", "user");
await db.push("time", "user", { uid, time: 0 });
await db.update("music", "source", { ID: id }, { ...data, Source: source });
await db.set("gacha", "data", [indefinite, character, weapon]);
await db.remove("cookie", "uid", { cookie });
await db.write("info"); // 几乎在任何情况下你都不需要手动调用 db.write
/* some code */
}
注意这些 API 只提供异步版本,你在无法在一个非异步的环境中使用这些 API 。