koishi-plugin-lili-hub 0.3.1 → 0.3.2
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 +121 -33
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -264,7 +264,6 @@ var Config = import_koishi.Schema.object({
|
|
|
264
264
|
enabled: import_koishi.Schema.boolean().description("\u542F\u7528\u4E3D\u4E3D\u6298\u53E0\u529F\u80FD").default(false),
|
|
265
265
|
groups: import_koishi.Schema.string().description("\u7FA4\u53F7\u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").default(""),
|
|
266
266
|
groupMode: import_koishi.Schema.union(["whitelist", "blacklist"]).description("\u7FA4\u7EC4\u8FC7\u6EE4\u6A21\u5F0F\uFF1A\u767D\u540D\u5355 / \u9ED1\u540D\u5355").default("whitelist"),
|
|
267
|
-
adminOnly: import_koishi.Schema.boolean().description("\u4EC5\u7FA4\u4E3B\u548C\u7BA1\u7406\u5458\u53EF\u4EE5\u4F7F\u7528\u4E3D\u4E3D\u6298\u53E0").default(false),
|
|
268
267
|
minutes: import_koishi.Schema.number().description("\u6298\u53E0\u65F6\u95F4\u8303\u56F4\uFF08\u5206\u949F\uFF09").default(10).min(1).max(1440)
|
|
269
268
|
}).description("\u{1F4E6} \u4E3D\u4E3D\u6298\u53E0"),
|
|
270
269
|
imitation: import_koishi.Schema.object({
|
|
@@ -288,7 +287,12 @@ var Config = import_koishi.Schema.object({
|
|
|
288
287
|
drawTimeoutSeconds: import_koishi.Schema.number().description("\u62D4\u67AA\u7A97\u53E3\u8D85\u65F6\uFF08\u79D2\uFF09").default(10).min(3).max(60),
|
|
289
288
|
earlyDrawMuteSeconds: import_koishi.Schema.number().description("\u63D0\u524D\u62D4\u67AA\u7981\u8A00\u65F6\u957F\uFF08\u79D2\uFF09").default(600).min(0).max(2592e3),
|
|
290
289
|
lateMuteSeconds: import_koishi.Schema.number().description("\u665A\u62D4\u67AA/\u672A\u62D4\u67AA\u7981\u8A00\u65F6\u957F\uFF08\u79D2\uFF09").default(300).min(0).max(2592e3)
|
|
291
|
-
}).description("\u2694\uFE0F \u4E3D\u4E3D\u5BF9\u51B3")
|
|
290
|
+
}).description("\u2694\uFE0F \u4E3D\u4E3D\u5BF9\u51B3"),
|
|
291
|
+
chain: import_koishi.Schema.object({
|
|
292
|
+
enabled: import_koishi.Schema.boolean().description("\u542F\u7528\u7FA4\u63A5\u9F99\u529F\u80FD").default(false),
|
|
293
|
+
groups: import_koishi.Schema.string().description("\u7FA4\u53F7\u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").default(""),
|
|
294
|
+
groupMode: import_koishi.Schema.union(["whitelist", "blacklist"]).description("\u7FA4\u7EC4\u8FC7\u6EE4\u6A21\u5F0F\uFF1A\u767D\u540D\u5355 / \u9ED1\u540D\u5355").default("whitelist")
|
|
295
|
+
}).description("\u{1F4DD} \u7FA4\u63A5\u9F99")
|
|
292
296
|
});
|
|
293
297
|
function getGroupId(session) {
|
|
294
298
|
return session.guildId || session.channelId;
|
|
@@ -389,6 +393,15 @@ function apply(ctx, config) {
|
|
|
389
393
|
const rouletteStates = /* @__PURE__ */ new Map();
|
|
390
394
|
const imitationCounters = /* @__PURE__ */ new Map();
|
|
391
395
|
const duelStates = /* @__PURE__ */ new Map();
|
|
396
|
+
const chainStates = /* @__PURE__ */ new Map();
|
|
397
|
+
function formatChain(chain) {
|
|
398
|
+
const lines = [chain.content];
|
|
399
|
+
for (let i = 0; i < chain.participants.length; i++) {
|
|
400
|
+
const p = chain.participants[i];
|
|
401
|
+
lines.push(`${i + 1}.${p.userName}\uFF08${p.userId}\uFF09`);
|
|
402
|
+
}
|
|
403
|
+
return lines.join("\n");
|
|
404
|
+
}
|
|
392
405
|
function isDrunk(gid) {
|
|
393
406
|
const s = drinkStates.get(gid);
|
|
394
407
|
if (!s || s.drunkUntil === 0) return false;
|
|
@@ -709,26 +722,19 @@ ${import_koishi.segment.at(targetId)} \u5DF2\u88AB\u89E3\u9664\u7981\u8A00\u3002
|
|
|
709
722
|
const fc = config.fold;
|
|
710
723
|
if (!fc.enabled) return;
|
|
711
724
|
if (!isGroupAllowed(gid, fc.groups, fc.groupMode)) return;
|
|
712
|
-
if (fc.adminOnly) {
|
|
713
|
-
try {
|
|
714
|
-
const info = await session.bot.getGroupMemberInfo(gid, String(session.userId));
|
|
715
|
-
if (!info || info.role !== "owner" && info.role !== "admin") {
|
|
716
|
-
return "\u{1F4E6} \u4EC5\u7FA4\u4E3B\u6216\u7BA1\u7406\u5458\u53EF\u4EE5\u4F7F\u7528\u4E3D\u4E3D\u6298\u53E0\u529F\u80FD\u3002";
|
|
717
|
-
}
|
|
718
|
-
} catch {
|
|
719
|
-
return "\u{1F4E6} \u65E0\u6CD5\u9A8C\u8BC1\u7BA1\u7406\u5458\u8EAB\u4EFD\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
725
|
const targetId = extractTarget(session, targetUser);
|
|
723
726
|
if (!targetId) return "\u{1F4E6} \u65E0\u6CD5\u89E3\u6790\u76EE\u6807\u7528\u6237\u3002\u8BF7\u4F7F\u7528 @ \u529F\u80FD\u6216\u76F4\u63A5\u8F93\u5165 QQ \u53F7\u3002";
|
|
724
727
|
const foldedMinutes = typeof minutesArg === "number" && minutesArg >= 1 && minutesArg <= 1440 ? minutesArg : fc.minutes;
|
|
725
728
|
const since = Date.now() - foldedMinutes * 60 * 1e3;
|
|
729
|
+
dbg("\u6298\u53E0-\u67E5\u8BE2", { gid, targetId, since: new Date(since).toLocaleTimeString("zh-CN"), foldedMinutes });
|
|
726
730
|
let messages;
|
|
727
731
|
try {
|
|
728
732
|
messages = await ctx.database.get("lili_message", { gid, userId: targetId, timestamp: { $gte: since } }, { sort: { timestamp: "asc" }, limit: 100 });
|
|
729
|
-
} catch {
|
|
733
|
+
} catch (e) {
|
|
734
|
+
dbg("\u6298\u53E0-\u67E5\u8BE2\u5931\u8D25", { gid, error: String(e) });
|
|
730
735
|
return "\u{1F4E6} \u67E5\u8BE2\u6D88\u606F\u5931\u8D25\u3002";
|
|
731
736
|
}
|
|
737
|
+
dbg("\u6298\u53E0-\u67E5\u8BE2\u7ED3\u679C", { gid, targetId, count: messages?.length || 0 });
|
|
732
738
|
if (!messages || messages.length === 0) return `\u{1F4E6} ${import_koishi.segment.at(targetId)} \u6700\u8FD1 ${foldedMinutes} \u5206\u949F\u5185\u6CA1\u6709\u53D1\u8A00\u8BB0\u5F55\u3002`;
|
|
733
739
|
const nodes = messages.map((m) => ({
|
|
734
740
|
type: "node",
|
|
@@ -1031,6 +1037,78 @@ ${import_koishi.segment.at(targetId)} \u5DF2\u88AB\u89E3\u9664\u7981\u8A00\u3002
|
|
|
1031
1037
|
}
|
|
1032
1038
|
return next();
|
|
1033
1039
|
});
|
|
1040
|
+
ctx.command("\u521B\u5EFA\u63A5\u9F99 <content:string>", "\u521B\u5EFA\u7FA4\u63A5\u9F99\uFF0C\u521B\u5EFA\u8005\u81EA\u52A8\u4E3A\u7B2C\u4E00\u4F4D").action(async ({ session }, content) => {
|
|
1041
|
+
if (!session?.userId) return;
|
|
1042
|
+
const gid = getGroupId(session);
|
|
1043
|
+
const cc = config.chain;
|
|
1044
|
+
if (!cc.enabled) return;
|
|
1045
|
+
if (!isGroupAllowed(gid, cc.groups, cc.groupMode)) return;
|
|
1046
|
+
if (!content || !content.trim()) {
|
|
1047
|
+
return "\u{1F4DD} \u8BF7\u63D0\u4F9B\u63A5\u9F99\u5185\u5BB9\uFF0C\u4F8B\u5982\uFF1A\u521B\u5EFA\u63A5\u9F99 \u4ECA\u5929\u4E2D\u5348\u5403\u4EC0\u4E48";
|
|
1048
|
+
}
|
|
1049
|
+
const chainContent = content.trim();
|
|
1050
|
+
const userId = String(session.userId);
|
|
1051
|
+
const userName = session.username || userId;
|
|
1052
|
+
chainStates.set(gid, {
|
|
1053
|
+
content: chainContent,
|
|
1054
|
+
creatorId: userId,
|
|
1055
|
+
creatorName: userName,
|
|
1056
|
+
participants: [{ userId, userName }],
|
|
1057
|
+
createdAt: Date.now()
|
|
1058
|
+
});
|
|
1059
|
+
dbg("\u63A5\u9F99-\u521B\u5EFA", { gid, creatorId: userId, content: chainContent });
|
|
1060
|
+
return formatChain(chainStates.get(gid));
|
|
1061
|
+
});
|
|
1062
|
+
ctx.command("\u67E5\u770B\u63A5\u9F99", "\u67E5\u770B\u5F53\u524D\u7FA4\u63A5\u9F99").action(async ({ session }) => {
|
|
1063
|
+
const gid = getGroupId(session);
|
|
1064
|
+
const cc = config.chain;
|
|
1065
|
+
if (!cc.enabled) return;
|
|
1066
|
+
if (!isGroupAllowed(gid, cc.groups, cc.groupMode)) return;
|
|
1067
|
+
const chain = chainStates.get(gid);
|
|
1068
|
+
if (!chain) return '\u{1F4DD} \u672C\u7FA4\u6682\u65E0\u63A5\u9F99\uFF0C\u4F7F\u7528"\u521B\u5EFA\u63A5\u9F99 <\u5185\u5BB9>"\u5F00\u59CB\u4E00\u4E2A\u5427\uFF01';
|
|
1069
|
+
return formatChain(chain);
|
|
1070
|
+
});
|
|
1071
|
+
ctx.command("\u9000\u51FA\u63A5\u9F99", "\u9000\u51FA\u5F53\u524D\u7FA4\u63A5\u9F99").alias("\u53D6\u6D88\u63A5\u9F99").action(async ({ session }) => {
|
|
1072
|
+
const gid = getGroupId(session);
|
|
1073
|
+
const cc = config.chain;
|
|
1074
|
+
if (!cc.enabled) return;
|
|
1075
|
+
if (!isGroupAllowed(gid, cc.groups, cc.groupMode)) return;
|
|
1076
|
+
const chain = chainStates.get(gid);
|
|
1077
|
+
if (!chain) return "\u{1F4DD} \u672C\u7FA4\u6682\u65E0\u63A5\u9F99\u3002";
|
|
1078
|
+
const userId = String(session.userId);
|
|
1079
|
+
const idx = chain.participants.findIndex((p) => p.userId === userId);
|
|
1080
|
+
if (idx === -1) return "\u{1F4DD} \u4F60\u6CA1\u6709\u53C2\u4E0E\u8FD9\u4E2A\u63A5\u9F99\u3002";
|
|
1081
|
+
const userName = chain.participants[idx].userName;
|
|
1082
|
+
chain.participants.splice(idx, 1);
|
|
1083
|
+
dbg("\u63A5\u9F99-\u9000\u51FA", { gid, userId, userName, remaining: chain.participants.length });
|
|
1084
|
+
if (chain.participants.length === 0) {
|
|
1085
|
+
chainStates.delete(gid);
|
|
1086
|
+
return "\u{1F4DD} \u4F60\u9000\u51FA\u4E86\u63A5\u9F99\uFF0C\u63A5\u9F99\u5DF2\u56E0\u65E0\u4EBA\u53C2\u4E0E\u800C\u7ED3\u675F\u3002";
|
|
1087
|
+
}
|
|
1088
|
+
await session.send(`\u{1F4DD} ${userName} \u5DF2\u9000\u51FA\u63A5\u9F99\u3002
|
|
1089
|
+
|
|
1090
|
+
${formatChain(chain)}`);
|
|
1091
|
+
});
|
|
1092
|
+
ctx.middleware(async (session, next) => {
|
|
1093
|
+
if (!config.chain.enabled) return next();
|
|
1094
|
+
const gid = getGroupId(session);
|
|
1095
|
+
if (!gid) return next();
|
|
1096
|
+
if (!isGroupAllowed(gid, config.chain.groups, config.chain.groupMode)) return next();
|
|
1097
|
+
const text = (session.content || "").trim();
|
|
1098
|
+
if (text !== "\u63A5\u9F99") return next();
|
|
1099
|
+
const chain = chainStates.get(gid);
|
|
1100
|
+
if (!chain) return next();
|
|
1101
|
+
const userId = String(session.userId);
|
|
1102
|
+
if (chain.participants.some((p) => p.userId === userId)) {
|
|
1103
|
+
await session.send("\u{1F4DD} \u4F60\u5DF2\u7ECF\u53C2\u4E0E\u8FC7\u8FD9\u4E2A\u63A5\u9F99\u4E86\uFF01");
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
const userName = session.username || userId;
|
|
1107
|
+
chain.participants.push({ userId, userName });
|
|
1108
|
+
dbg("\u63A5\u9F99-\u53C2\u4E0E", { gid, userId, participantCount: chain.participants.length });
|
|
1109
|
+
await session.send(formatChain(chain));
|
|
1110
|
+
return;
|
|
1111
|
+
});
|
|
1034
1112
|
ctx.middleware(async (session, next) => {
|
|
1035
1113
|
const gid = getGroupId(session);
|
|
1036
1114
|
const content = session.content || "";
|
|
@@ -1128,15 +1206,19 @@ ${import_koishi.segment.at(targetId)} \u5DF2\u88AB\u89E3\u9664\u7981\u8A00\u3002
|
|
|
1128
1206
|
forwardTextsCount: forwardTexts.length
|
|
1129
1207
|
});
|
|
1130
1208
|
if (isFwd && forwardTexts.length > 0) {
|
|
1131
|
-
const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1e3;
|
|
1132
1209
|
dbg("\u67E5\u91CD\u68C0\u6D4B", { gid, forwardTextsCount: forwardTexts.length });
|
|
1133
1210
|
for (const fwdText of forwardTexts) {
|
|
1134
1211
|
if (!fwdText) continue;
|
|
1135
1212
|
try {
|
|
1136
|
-
const
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1213
|
+
const sevenDaysAgoMs = Date.now() - 7 * 24 * 60 * 60 * 1e3;
|
|
1214
|
+
const recentMsgs = await ctx.database.get("lili_message", { gid, timestamp: { $gte: sevenDaysAgoMs } }, { sort: { timestamp: "asc" }, limit: 1e3 });
|
|
1215
|
+
const match = recentMsgs.find((m) => {
|
|
1216
|
+
if (m.content === fwdText) return true;
|
|
1217
|
+
return normalizeText(m.content) === fwdText;
|
|
1218
|
+
});
|
|
1219
|
+
dbg("\u67E5\u91CD\u67E5\u8BE2", { gid, fwdText: fwdText.substring(0, 50), recentMsgCount: recentMsgs?.length || 0, matched: !!match });
|
|
1220
|
+
if (match) {
|
|
1221
|
+
const original = match;
|
|
1140
1222
|
const dateStr = new Date(original.timestamp).toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" });
|
|
1141
1223
|
await session.send([
|
|
1142
1224
|
(0, import_koishi.h)("quote", { id: original.messageId }),
|
|
@@ -1179,8 +1261,8 @@ ${import_koishi.segment.at(targetId)} \u5DF2\u88AB\u89E3\u9664\u7981\u8A00\u3002
|
|
|
1179
1261
|
try {
|
|
1180
1262
|
await ctx.database.create("lili_message", {
|
|
1181
1263
|
gid,
|
|
1182
|
-
userId: session.userId,
|
|
1183
|
-
userName: session.username || session.userId,
|
|
1264
|
+
userId: String(session.userId),
|
|
1265
|
+
userName: session.username || String(session.userId),
|
|
1184
1266
|
content: fwdText,
|
|
1185
1267
|
timestamp: Date.now(),
|
|
1186
1268
|
messageId: session.messageId || ""
|
|
@@ -1191,19 +1273,25 @@ ${import_koishi.segment.at(targetId)} \u5DF2\u88AB\u89E3\u9664\u7981\u8A00\u3002
|
|
|
1191
1273
|
}
|
|
1192
1274
|
}
|
|
1193
1275
|
}
|
|
1194
|
-
if (shouldRecord && !isFwd
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1276
|
+
if (shouldRecord && !isFwd) {
|
|
1277
|
+
const shouldStore = shouldRecordAll || normalizedText && textLen >= 15 && textLen <= 60;
|
|
1278
|
+
if (shouldStore) {
|
|
1279
|
+
const storeContent = shouldRecordAll ? session.content || normalizedText || "" : normalizedText;
|
|
1280
|
+
if (storeContent) {
|
|
1281
|
+
try {
|
|
1282
|
+
await ctx.database.create("lili_message", {
|
|
1283
|
+
gid,
|
|
1284
|
+
userId: String(session.userId),
|
|
1285
|
+
userName: session.username || String(session.userId),
|
|
1286
|
+
content: storeContent,
|
|
1287
|
+
timestamp: Date.now(),
|
|
1288
|
+
messageId: session.messageId || ""
|
|
1289
|
+
});
|
|
1290
|
+
dbg("\u6D88\u606F\u5DF2\u5165\u5E93", { gid, userId: String(session.userId), contentLen: storeContent.length, shouldRecordAll, messageId: session.messageId });
|
|
1291
|
+
} catch (e) {
|
|
1292
|
+
dbg("\u6D88\u606F\u5165\u5E93\u5931\u8D25", { gid, error: String(e) });
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1207
1295
|
}
|
|
1208
1296
|
}
|
|
1209
1297
|
if (config.imitation.enabled && isGroupAllowed(gid, config.imitation.groups, config.imitation.groupMode)) {
|