@zaofan/dsh-qqbot 1.10.10 → 1.10.11
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/README.md +83 -0
- package/README_EN.md +31 -0
- package/client/qqbot-settings.js +116 -4
- package/dist/channel-tools.d.ts +0 -12
- package/dist/channel-tools.d.ts.map +1 -1
- package/dist/channel-tools.js +202 -20
- package/dist/channel-tools.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/features/msg-history.d.ts +78 -0
- package/dist/features/msg-history.d.ts.map +1 -0
- package/dist/features/msg-history.js +312 -0
- package/dist/features/msg-history.js.map +1 -0
- package/dist/features/msg-recent.d.ts +72 -0
- package/dist/features/msg-recent.d.ts.map +1 -0
- package/dist/features/msg-recent.js +131 -0
- package/dist/features/msg-recent.js.map +1 -0
- package/dist/gateway/bootstrap.d.ts.map +1 -1
- package/dist/gateway/bootstrap.js +83 -4
- package/dist/gateway/bootstrap.js.map +1 -1
- package/dist/gateway/middleware-setup.d.ts.map +1 -1
- package/dist/gateway/middleware-setup.js +36 -0
- package/dist/gateway/middleware-setup.js.map +1 -1
- package/dist/transport/inbound.d.ts.map +1 -1
- package/dist/transport/inbound.js +87 -1
- package/dist/transport/inbound.js.map +1 -1
- package/dist/transport/msg-content-cache.d.ts +50 -0
- package/dist/transport/msg-content-cache.d.ts.map +1 -1
- package/dist/transport/msg-content-cache.js +58 -14
- package/dist/transport/msg-content-cache.js.map +1 -1
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ import { appendFileSync, mkdirSync, readFileSync, statSync, writeFileSync } from
|
|
|
15
15
|
import { dirname, join } from 'node:path';
|
|
16
16
|
/** 单个 peer 保留的台账行数上限(超出只留尾部,防文件无限膨胀) */
|
|
17
17
|
const MAX_LINES = 2000;
|
|
18
|
+
const NL = String.fromCharCode(10);
|
|
18
19
|
/** 文件路径 → { mtimeKey, index, lines } */
|
|
19
20
|
const cache = new Map();
|
|
20
21
|
function fileOf(dataRoot) {
|
|
@@ -34,8 +35,9 @@ function load(dataRoot) {
|
|
|
34
35
|
const hit = cache.get(file);
|
|
35
36
|
// 'dirty' = 本进程刚写过,内存比文件新 → 直接用内存,别重读整个文件
|
|
36
37
|
if (hit && (hit.key === key || hit.key === 'dirty'))
|
|
37
|
-
return { index: hit.index, lines: hit.lines };
|
|
38
|
+
return { index: hit.index, lines: hit.lines, list: hit.list };
|
|
38
39
|
const index = new Map();
|
|
40
|
+
const list = [];
|
|
39
41
|
let lines = 0;
|
|
40
42
|
try {
|
|
41
43
|
for (const line of readFileSync(file, 'utf8').split('\n')) {
|
|
@@ -47,17 +49,23 @@ function load(dataRoot) {
|
|
|
47
49
|
const r = JSON.parse(s);
|
|
48
50
|
if (!r || !r.p || !r.i)
|
|
49
51
|
continue;
|
|
52
|
+
list.push(r);
|
|
50
53
|
index.set(indexKey(r.p, r.i), {
|
|
51
54
|
...(r.t ? { t: r.t } : {}),
|
|
52
55
|
...(Array.isArray(r.imgs) && r.imgs.length ? { imgs: r.imgs } : {}),
|
|
56
|
+
...(r.m ? { m: r.m } : {}),
|
|
57
|
+
...(r.s ? { s: r.s } : {}),
|
|
58
|
+
...(r.n ? { n: r.n } : {}),
|
|
59
|
+
...(r.k ? { k: r.k } : {}),
|
|
60
|
+
...(r.me ? { me: true } : {}),
|
|
53
61
|
});
|
|
54
62
|
}
|
|
55
63
|
catch { /* 坏行跳过 */ }
|
|
56
64
|
}
|
|
57
65
|
}
|
|
58
66
|
catch { /* 没有文件 */ }
|
|
59
|
-
cache.set(file, { key, index, lines });
|
|
60
|
-
return { index, lines };
|
|
67
|
+
cache.set(file, { key, index, lines, list });
|
|
68
|
+
return { index, lines, list };
|
|
61
69
|
}
|
|
62
70
|
/**
|
|
63
71
|
* 记一条:这条消息(msgIdx)的文本与图片本地路径。
|
|
@@ -67,9 +75,10 @@ export function rememberMsgContent(dataRoot, peerKey, msgIdx, rec) {
|
|
|
67
75
|
const idx = String(msgIdx ?? '').trim();
|
|
68
76
|
if (!dataRoot || !peerKey || !idx)
|
|
69
77
|
return;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
// 2026-10-20: 现在也承载"撤回台账",只有 message_id 没有正文时同样要记
|
|
79
|
+
if (!rec.t && !(rec.imgs && rec.imgs.length) && !rec.m)
|
|
80
|
+
return;
|
|
81
|
+
const { index, lines, list } = load(dataRoot);
|
|
73
82
|
index.set(indexKey(peerKey, idx), rec);
|
|
74
83
|
const file = fileOf(dataRoot);
|
|
75
84
|
try {
|
|
@@ -78,16 +87,13 @@ export function rememberMsgContent(dataRoot, peerKey, msgIdx, rec) {
|
|
|
78
87
|
const nextLines = lines + 1;
|
|
79
88
|
if (nextLines > MAX_LINES) {
|
|
80
89
|
// 超上限 → 重写成尾部 MAX_LINES 条(内存里已有的直接重建)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
writeFileSync(file, tail.slice(-MAX_LINES).join('\n') + '\n', 'utf8');
|
|
87
|
-
cache.set(file, { key: 'dirty', index, lines: Math.min(nextLines, MAX_LINES) });
|
|
90
|
+
// 用 list 重写(保留每行 at 与顺序); 旧实现按 index 重建会把 at 丢成 0, 按时间窗扫描会全判过期。
|
|
91
|
+
const keep = list.slice(-MAX_LINES);
|
|
92
|
+
writeFileSync(file, keep.map((r) => JSON.stringify(r)).join(NL) + NL, 'utf8');
|
|
93
|
+
cache.set(file, { key: 'dirty', index, lines: keep.length, list: keep });
|
|
88
94
|
return;
|
|
89
95
|
}
|
|
90
|
-
cache.set(file, { key: 'dirty', index, lines: nextLines });
|
|
96
|
+
cache.set(file, { key: 'dirty', index, lines: nextLines, list });
|
|
91
97
|
}
|
|
92
98
|
catch { /* 落盘失败不影响主链(内存索引已经更新) */ }
|
|
93
99
|
}
|
|
@@ -102,4 +108,42 @@ export function lookupMsgContent(dataRoot, peerKey, msgIdx) {
|
|
|
102
108
|
return undefined;
|
|
103
109
|
}
|
|
104
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* 扫该 peer 的台账(2026-10-20 撤回功能/消息搜索用)。
|
|
113
|
+
* ★ 严格按 peerKey 过滤 —— 群与群、群与私聊绝不串。
|
|
114
|
+
* 返回新→旧(同一毫秒内按写入顺序倒序)。
|
|
115
|
+
*/
|
|
116
|
+
export function scanMsgContent(dataRoot, peerKey, q = {}) {
|
|
117
|
+
if (!dataRoot || !peerKey)
|
|
118
|
+
return [];
|
|
119
|
+
let list = [];
|
|
120
|
+
try {
|
|
121
|
+
list = load(dataRoot).list;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
const now = Date.now();
|
|
127
|
+
const within = q.withinMs ?? 2 * 60 * 60 * 1000;
|
|
128
|
+
const limit = Math.max(1, Math.min(200, q.limit ?? 20));
|
|
129
|
+
const kw = String(q.keyword ?? '').trim().toLowerCase();
|
|
130
|
+
const out = [];
|
|
131
|
+
for (let i = list.length - 1; i >= 0 && out.length < limit; i--) {
|
|
132
|
+
const r = list[i];
|
|
133
|
+
if (!r || r.p !== peerKey)
|
|
134
|
+
continue;
|
|
135
|
+
if (now - Number(r.at ?? 0) > within)
|
|
136
|
+
continue;
|
|
137
|
+
if (q.fromSelf !== undefined && Boolean(r.me) !== q.fromSelf)
|
|
138
|
+
continue;
|
|
139
|
+
if (q.senderId && r.s !== q.senderId)
|
|
140
|
+
continue;
|
|
141
|
+
if (q.kind && (r.k ?? 'text') !== q.kind)
|
|
142
|
+
continue;
|
|
143
|
+
if (kw && !String(r.t ?? '').toLowerCase().includes(kw))
|
|
144
|
+
continue;
|
|
145
|
+
out.push(r);
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
105
149
|
//# sourceMappingURL=msg-content-cache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msg-content-cache.js","sourceRoot":"","sources":["../../src/transport/msg-content-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,wCAAwC;AACxC,MAAM,SAAS,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"msg-content-cache.js","sourceRoot":"","sources":["../../src/transport/msg-content-cache.ts"],"names":[],"mappings":"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"}
|