koishi-plugin-ll-brick 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/lib/index.js +68 -5
  2. package/package.json +2 -2
  3. package/readme.md +25 -0
package/lib/index.js CHANGED
@@ -52,6 +52,54 @@ exports.Config = koishi_1.Schema.intersect([
52
52
  ])
53
53
  ]);
54
54
  exports.inject = ["database"];
55
+ // QQ 官方机器人的 @ 只有在 markdown 消息里才会渲染,纯文本消息不识别任何 at 标签。
56
+ // 因此 QQ 平台的回复直接走开放平台 internal API 发 markdown(图片嵌入 markdown),
57
+ // 与欢迎插件同一方案;其他平台沿用原 h.at 文本消息。
58
+ const BRICK_IMG = 'https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/lOIl/240X240/images.jpg/webp';
59
+ const FIRE_IMG = 'https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/xsnm/447X447/images_%282%29.jpg/webp';
60
+ function atUser(session, userId) {
61
+ if (session?.platform === 'qq') {
62
+ return `<qqbot-at-user id="${userId}" />`;
63
+ }
64
+ return koishi_1.h.at(userId).toString();
65
+ }
66
+ function stripMarkdown(md) {
67
+ return md
68
+ .replace(/<qqbot-at-user[^>]*\/>/g, '')
69
+ .replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '[$1]($2)')
70
+ .replace(/^#{1,6}\s*/gm, '')
71
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
72
+ .replace(/\*([^*]+)\*/g, '$1')
73
+ .replace(/`([^`]+)`/g, '$1')
74
+ .replace(/^>\s?/gm, '')
75
+ .replace(/\n{3,}/g, '\n\n')
76
+ .trim();
77
+ }
78
+ async function sendQQMarkdown(session, imageUrl, text) {
79
+ const channelId = session.guildId;
80
+ const internal = session.bot?.internal;
81
+ if (!channelId || !internal || typeof internal.sendMessage !== 'function') {
82
+ return false;
83
+ }
84
+ const md = imageUrl ? `![](${imageUrl})\n\n${text}` : text;
85
+ const plain = stripMarkdown(md) || ' ';
86
+ try {
87
+ await internal.sendMessage(channelId, {
88
+ msg_type: 2,
89
+ msg_seq: 0,
90
+ content: plain,
91
+ markdown: { content: md },
92
+ });
93
+ return true;
94
+ }
95
+ catch (e) {
96
+ try {
97
+ await internal.sendMessage(channelId, { msg_type: 0, content: plain });
98
+ }
99
+ catch (e2) { /* 忽略 */ }
100
+ return false;
101
+ }
102
+ }
55
103
  async function apply(ctx, config) {
56
104
  ctx.model.extend('brick', {
57
105
  id: 'unsigned',
@@ -101,7 +149,13 @@ async function apply(ctx, config) {
101
149
  brick: koishi_1.$.add(row.brick, 1),
102
150
  }], ["userId", "guildId"]);
103
151
  users[user].burning = false;
104
- await session.send(`${koishi_1.h.image('https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/xsnm/447X447/images_%282%29.jpg/webp')}${koishi_1.h.at(session.userId)} 砖已经烧好啦`);
152
+ const fireDone = `${atUser(session, session.userId)} 砖已经烧好啦`;
153
+ if (session.platform === 'qq') {
154
+ await sendQQMarkdown(session, FIRE_IMG, fireDone);
155
+ }
156
+ else {
157
+ await session.send(`${koishi_1.h.image(FIRE_IMG)}${fireDone}`);
158
+ }
105
159
  }
106
160
  }
107
161
  return next();
@@ -146,19 +200,28 @@ async function apply(ctx, config) {
146
200
  ? config.specialUser[targetUserId] / 100
147
201
  : config.reverse / 100;
148
202
  const brickImg = koishi_1.h.image('https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/lOIl/240X240/images.jpg/webp');
203
+ const isQQ = session.platform === 'qq';
149
204
  if (koishi_1.Random.bool(probability)) {
150
205
  const muteErr = await tryMute(session.userId);
151
- let msg = `${brickImg}${koishi_1.h.at(targetUserId)} 夺过你的砖头,把你拍晕了 ${muteTime} 秒`;
206
+ let msg = `${atUser(session, targetUserId)} 夺过你的砖头,把你拍晕了 ${muteTime} 秒`;
152
207
  if (muteErr)
153
208
  msg += '\n因为我不是群管理员,所以并没什么卵用';
154
- return msg;
209
+ if (isQQ) {
210
+ await sendQQMarkdown(session, BRICK_IMG, msg);
211
+ return;
212
+ }
213
+ return `${brickImg}${msg}`;
155
214
  }
156
215
  else {
157
216
  const muteErr = await tryMute(targetUserId);
158
- let msg = `${brickImg}${koishi_1.h.at(targetUserId)} 你被 ${koishi_1.h.at(session.userId)} 拍晕了 ${muteTime} 秒`;
217
+ let msg = `${atUser(session, targetUserId)} 你被 ${atUser(session, session.userId)} 拍晕了 ${muteTime} 秒`;
159
218
  if (muteErr)
160
219
  msg += '\n因为我不是群管理员,所以并没什么卵用';
161
- return msg;
220
+ if (isQQ) {
221
+ await sendQQMarkdown(session, BRICK_IMG, msg);
222
+ return;
223
+ }
224
+ return `${brickImg}${msg}`;
162
225
  }
163
226
  async function tryMute(slapedUserId) {
164
227
  users[`${session.guildId}:${slapedUserId}`].muted = true;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ll-brick",
3
3
  "description": "砖头拍人插件(克隆自 koishi-plugin-brick),非管理员时会提示",
4
- "version": "1.0.2",
4
+ "version": "1.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -11,7 +11,7 @@
11
11
  "license": "MIT",
12
12
  "koishi": {
13
13
  "description": {
14
- "zh": "砖头拍人插件:烧砖、拍人、随机拍人、签到,修复了异步禁言bug,非管理员会提示"
14
+ "zh": "砖头拍人插件:烧砖、拍人、随机拍人、签到,修复了异步禁言bug和QQ官方机器人艾特不生效问题"
15
15
  }
16
16
  },
17
17
  "keywords": [
package/readme.md ADDED
@@ -0,0 +1,25 @@
1
+ # koishi-plugin-ll-brick
2
+
3
+ 砖头拍人插件(克隆自 [koishi-plugin-brick](https://www.npmjs.com/package/koishi-plugin-brick))。
4
+
5
+ 烧制砖块,然后拍晕群友!如果机器人没有禁言权限,会提示"没什么卵用"。
6
+ 开始烧制之后,群内其他群友发送一定数量的消息就能完成烧制!
7
+
8
+ ## 功能
9
+
10
+ - `砖头 烧砖` — 烧砖,需要群友聊天攒进度
11
+ - `砖头 拍人 @某人` — 用砖头拍晕(禁言)对方随机时间,有概率被反将一军
12
+ - `砖头 随机拍人` — 随机挑一个群友拍
13
+ - `砖头 查看` — 查看自己的砖头数量
14
+ - `砖头 签到`(可选开启)— 每日签到获取随机砖头
15
+
16
+ ## v1.0.4 修复
17
+
18
+ - 彻底修复 **QQ 官方机器人** 上回复消息中 @(艾特)不生效的问题:
19
+ - 根因:QQ 官方机器人的 @ 标签(`<qqbot-at-user>`)**只在 markdown 消息里渲染**,纯文本消息会原样显示成文字(之前的 1.0.3 只改了标签格式,没改消息类型,所以还是不行)
20
+ - 现在:QQ 平台的回复改为**直接走开放平台 API 发送 markdown 消息**(与 `koishi-plugin-ll-group-welcome` 欢迎插件同一方案),图片嵌入 markdown,`<qqbot-at-user>` 标签正常渲染为 @ 提及
21
+ - 其他平台行为不变
22
+
23
+ ## v1.0.3 修复
24
+
25
+ - 尝试修复 QQ 官方机器人 @ 不生效(改标签格式,未改消息类型,实际无效,已被 1.0.4 取代)