koishi-plugin-ll-brick 1.0.3 → 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.
package/lib/index.js CHANGED
@@ -52,14 +52,54 @@ exports.Config = koishi_1.Schema.intersect([
52
52
  ])
53
53
  ]);
54
54
  exports.inject = ["database"];
55
- // 生成消息中的 @。QQ 官方机器人使用 <qqbot-at-user id="..." /> 新格式,
56
- // 且需要 &lt; &gt; 转义以绕过 koishi 元素管线(否则未知标签会被丢弃);其他平台沿用 h.at。
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';
57
60
  function atUser(session, userId) {
58
61
  if (session?.platform === 'qq') {
59
- return `&lt;qqbot-at-user id="${userId}" /&gt;`;
62
+ return `<qqbot-at-user id="${userId}" />`;
60
63
  }
61
64
  return koishi_1.h.at(userId).toString();
62
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
+ }
63
103
  async function apply(ctx, config) {
64
104
  ctx.model.extend('brick', {
65
105
  id: 'unsigned',
@@ -109,7 +149,13 @@ async function apply(ctx, config) {
109
149
  brick: koishi_1.$.add(row.brick, 1),
110
150
  }], ["userId", "guildId"]);
111
151
  users[user].burning = false;
112
- await session.send(`${koishi_1.h.image('https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/xsnm/447X447/images_%282%29.jpg/webp')}${atUser(session, 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
+ }
113
159
  }
114
160
  }
115
161
  return next();
@@ -154,19 +200,28 @@ async function apply(ctx, config) {
154
200
  ? config.specialUser[targetUserId] / 100
155
201
  : config.reverse / 100;
156
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';
157
204
  if (koishi_1.Random.bool(probability)) {
158
205
  const muteErr = await tryMute(session.userId);
159
- let msg = `${brickImg}${atUser(session, targetUserId)} 夺过你的砖头,把你拍晕了 ${muteTime} 秒`;
206
+ let msg = `${atUser(session, targetUserId)} 夺过你的砖头,把你拍晕了 ${muteTime} 秒`;
160
207
  if (muteErr)
161
208
  msg += '\n因为我不是群管理员,所以并没什么卵用';
162
- return msg;
209
+ if (isQQ) {
210
+ await sendQQMarkdown(session, BRICK_IMG, msg);
211
+ return;
212
+ }
213
+ return `${brickImg}${msg}`;
163
214
  }
164
215
  else {
165
216
  const muteErr = await tryMute(targetUserId);
166
- let msg = `${brickImg}${atUser(session, targetUserId)} 你被 ${atUser(session, session.userId)} 拍晕了 ${muteTime} 秒`;
217
+ let msg = `${atUser(session, targetUserId)} 你被 ${atUser(session, session.userId)} 拍晕了 ${muteTime} 秒`;
167
218
  if (muteErr)
168
219
  msg += '\n因为我不是群管理员,所以并没什么卵用';
169
- return msg;
220
+ if (isQQ) {
221
+ await sendQQMarkdown(session, BRICK_IMG, msg);
222
+ return;
223
+ }
224
+ return `${brickImg}${msg}`;
170
225
  }
171
226
  async function tryMute(slapedUserId) {
172
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.3",
4
+ "version": "1.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -13,8 +13,13 @@
13
13
  - `砖头 查看` — 查看自己的砖头数量
14
14
  - `砖头 签到`(可选开启)— 每日签到获取随机砖头
15
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
+
16
23
  ## v1.0.3 修复
17
24
 
18
- - 修复 **QQ 官方机器人** 上回复消息中 @(艾特)不生效的问题:
19
- - 原实现通过 koishi 的 `at` 元素发送,适配器会序列化成已弃用的 `<@openid>` 协议
20
- - 现在 QQ 平台改用官方新格式 `<qqbot-at-user id="openid" />`,其他平台行为不变
25
+ - 尝试修复 QQ 官方机器人 @ 不生效(改标签格式,未改消息类型,实际无效,已被 1.0.4 取代)