koishi-plugin-maibot 1.9.7 → 1.9.9
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.d.ts.map +1 -1
- package/lib/index.js +101 -11
- package/lib/index.js.map +1 -1
- package/lib/priority-cooldown.d.ts +6 -2
- package/lib/priority-cooldown.d.ts.map +1 -1
- package/lib/priority-cooldown.js +40 -9
- package/lib/priority-cooldown.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1565,13 +1565,28 @@ function apply(ctx, config) {
|
|
|
1565
1565
|
const wl = checkWhitelist(sess, config);
|
|
1566
1566
|
if (!wl.allowed)
|
|
1567
1567
|
return;
|
|
1568
|
-
|
|
1568
|
+
// 获取当前用户绑定的 maiUid(用于共享冷却)
|
|
1569
|
+
let sessionMaiUid;
|
|
1570
|
+
try {
|
|
1571
|
+
const binding = await getBindingBySession(ctx, sess);
|
|
1572
|
+
if (binding?.maiUid)
|
|
1573
|
+
sessionMaiUid = binding.maiUid;
|
|
1574
|
+
}
|
|
1575
|
+
catch { /* 忽略 */ }
|
|
1576
|
+
// 超过2个绑定时拦截有冷却的命令
|
|
1577
|
+
if (sessionMaiUid) {
|
|
1578
|
+
const sameUidBindings = await ctx.database.get('maibot_bindings', { maiUid: sessionMaiUid });
|
|
1579
|
+
if (sameUidBindings.length > 2) {
|
|
1580
|
+
return `❌ 您的游戏账号已被 ${sameUidBindings.length} 个用户绑定,请先解绑多余账号后再使用此功能。\n(使用 /mai解绑 解绑当前账号)`;
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
const hit = await (0, priority_cooldown_1.checkCommandCooldown)(ctx, sess, priorityCooldownCfg, cmdName, getCooldownPrimaryUserId, async (s) => getSessionBindingKeys(ctx, s), sessionMaiUid);
|
|
1569
1584
|
if (hit)
|
|
1570
1585
|
return hit;
|
|
1571
1586
|
const uid = await getCooldownPrimaryUserId(sess);
|
|
1572
1587
|
if (!uid)
|
|
1573
1588
|
return;
|
|
1574
|
-
await (0, priority_cooldown_1.recordCommandCooldown)(ctx, uid, cmdName, priorityCooldownCfg);
|
|
1589
|
+
await (0, priority_cooldown_1.recordCommandCooldown)(ctx, uid, cmdName, priorityCooldownCfg, sessionMaiUid);
|
|
1575
1590
|
});
|
|
1576
1591
|
/**
|
|
1577
1592
|
* 获取上传任务的统计信息(平均处理时长和今日成功率)
|
|
@@ -2036,6 +2051,29 @@ function apply(ctx, config) {
|
|
|
2036
2051
|
const legacy = await getBindRelatedLegacyUserIdsForTarget(ctx, platform, extracted);
|
|
2037
2052
|
for (const id of legacy)
|
|
2038
2053
|
keys.add(id);
|
|
2054
|
+
// 通过 bind 插件反查 aid,补上 koishi:<aid>(实际记录冷却用的统一键)
|
|
2055
|
+
const db = ctx.database;
|
|
2056
|
+
if (db && typeof db.get === 'function') {
|
|
2057
|
+
try {
|
|
2058
|
+
const pidCandidates = platform
|
|
2059
|
+
? [`${platform}:${extracted}`, extracted]
|
|
2060
|
+
: [extracted];
|
|
2061
|
+
let aid;
|
|
2062
|
+
for (const pid of pidCandidates) {
|
|
2063
|
+
const rows = await db.get('binding', { pid });
|
|
2064
|
+
if (rows?.length) {
|
|
2065
|
+
aid = rows[0]?.aid;
|
|
2066
|
+
break;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
if (aid !== undefined && aid !== null) {
|
|
2070
|
+
keys.add(`koishi:${String(aid)}`);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
catch {
|
|
2074
|
+
// binding 表不存在或结构不一致时忽略
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2039
2077
|
for (const id of [...keys]) {
|
|
2040
2078
|
const rows = await ctx.database.get('maibot_bindings', { userId: id });
|
|
2041
2079
|
for (const b of rows)
|
|
@@ -2735,6 +2773,14 @@ function apply(ctx, config) {
|
|
|
2735
2773
|
const maiUid = String(previewResult.UserID);
|
|
2736
2774
|
const userName = previewResult.UserName;
|
|
2737
2775
|
const rating = previewResult.Rating ? String(previewResult.Rating) : undefined;
|
|
2776
|
+
// 检查同一游戏账号是否已被其他 Bot 用户绑定
|
|
2777
|
+
const sameUidBindings = await ctx.database.get('maibot_bindings', { maiUid });
|
|
2778
|
+
const otherBindings = sameUidBindings.filter(b => b.userId !== userId);
|
|
2779
|
+
if (otherBindings.length > 0) {
|
|
2780
|
+
const earliest = otherBindings.sort((a, b) => new Date(a.bindTime).getTime() - new Date(b.bindTime).getTime())[0];
|
|
2781
|
+
await session.send(`⚠️ 此游戏账号已被其他用户绑定(最早绑定时间: ${new Date(earliest.bindTime).toLocaleString('zh-CN')})。\n` +
|
|
2782
|
+
`持有 SGID 即证明账号所有权,继续绑定后进入冷却期。`);
|
|
2783
|
+
}
|
|
2738
2784
|
// 存储到数据库
|
|
2739
2785
|
await ctx.database.create('maibot_bindings', {
|
|
2740
2786
|
userId,
|
|
@@ -6665,7 +6711,7 @@ function apply(ctx, config) {
|
|
|
6665
6711
|
const n = await (0, priority_cooldown_1.adminRemovePersonalPriorityRows)(ctx, candidates);
|
|
6666
6712
|
return `✅ 已清除 ${n} 条个人优先记录。\n匹配键:${candidates.join('、')}`;
|
|
6667
6713
|
});
|
|
6668
|
-
ctx.command('mai管理员设置个人优先
|
|
6714
|
+
ctx.command('mai管理员设置个人优先 [targetUserId:text] [spec:text]', '设置个人优先:永久 / 时长 / clear(无参数走交互式)')
|
|
6669
6715
|
.userFields(['authority'])
|
|
6670
6716
|
.action(async ({ session }, targetUserId, spec) => {
|
|
6671
6717
|
if (!session)
|
|
@@ -6673,8 +6719,24 @@ function apply(ctx, config) {
|
|
|
6673
6719
|
if ((session.user?.authority ?? 0) < authLevelForCardAdmin) {
|
|
6674
6720
|
return `❌ 权限不足,需要 auth 等级 ${authLevelForCardAdmin} 以上`;
|
|
6675
6721
|
}
|
|
6676
|
-
|
|
6677
|
-
|
|
6722
|
+
const promptMs = Math.max(90000, rebindTimeout);
|
|
6723
|
+
// 交互式:未提供目标用户
|
|
6724
|
+
if (!targetUserId?.trim()) {
|
|
6725
|
+
await session.send(`【设置个人优先】请在 ${Math.floor(promptMs / 1000)} 秒内发送目标用户(@用户 或数字ID)\n${INTERACTIVE_CANCEL_HINT}`);
|
|
6726
|
+
const r1 = await waitForUserReply(session, ctx, promptMs);
|
|
6727
|
+
const replyText = r1?.content?.trim() || '';
|
|
6728
|
+
if (!replyText || isInteractiveCancel(replyText))
|
|
6729
|
+
return '操作已取消';
|
|
6730
|
+
targetUserId = replyText;
|
|
6731
|
+
}
|
|
6732
|
+
// 交互式:未提供时长
|
|
6733
|
+
if (!spec?.trim()) {
|
|
6734
|
+
await session.send(`请发送时长规格(永久 / 7d / 30d / clear 等)\n${INTERACTIVE_CANCEL_HINT}`);
|
|
6735
|
+
const r2 = await waitForUserReply(session, ctx, promptMs);
|
|
6736
|
+
const replyText = r2?.content?.trim() || '';
|
|
6737
|
+
if (!replyText || isInteractiveCancel(replyText))
|
|
6738
|
+
return '操作已取消';
|
|
6739
|
+
spec = replyText;
|
|
6678
6740
|
}
|
|
6679
6741
|
const sp = (0, priority_cooldown_1.parsePriorityAdminSpec)(spec);
|
|
6680
6742
|
if (sp === null) {
|
|
@@ -6687,11 +6749,11 @@ function apply(ctx, config) {
|
|
|
6687
6749
|
const r = await (0, priority_cooldown_1.adminSetPersonalPriorityForUserIds)(ctx, candidates, sp);
|
|
6688
6750
|
return r.message;
|
|
6689
6751
|
});
|
|
6690
|
-
ctx.command('mai管理员设置群组优先
|
|
6752
|
+
ctx.command('mai管理员设置群组优先 [spec:text]', '直接设置群组优先(-g 指定群;无参数走交互式)')
|
|
6691
6753
|
.userFields(['authority'])
|
|
6692
6754
|
.usage(' 示例:/mai管理员设置群组优先 clear -g qq:5911013814031454\n' +
|
|
6693
6755
|
'或:/mai管理员设置群组优先 -g qq:5911013814031454 永久\n' +
|
|
6694
|
-
'
|
|
6756
|
+
'无参数:发指令后按提示输入群标识与时长(仅数字群号请写 qq:群号;在群内执行可省略群标识)')
|
|
6695
6757
|
.option('guild', '-g <guildKey:string> 群标识,如 qq:群号')
|
|
6696
6758
|
.action(async ({ session, options }, spec) => {
|
|
6697
6759
|
if (!session)
|
|
@@ -6699,15 +6761,43 @@ function apply(ctx, config) {
|
|
|
6699
6761
|
if ((session.user?.authority ?? 0) < authLevelForCardAdmin) {
|
|
6700
6762
|
return `❌ 权限不足,需要 auth 等级 ${authLevelForCardAdmin} 以上`;
|
|
6701
6763
|
}
|
|
6764
|
+
const promptMs = Math.max(90000, rebindTimeout);
|
|
6702
6765
|
const { spec: specOnly, guild: guildOpt } = splitGroupPrioritySpecAndGuild(spec, options?.guild);
|
|
6703
|
-
|
|
6704
|
-
|
|
6766
|
+
let specFinal = specOnly;
|
|
6767
|
+
let guildFinal = guildOpt;
|
|
6768
|
+
// 无任何参数 → 全交互式
|
|
6769
|
+
if (!specFinal) {
|
|
6770
|
+
// 群标识
|
|
6771
|
+
if (!guildFinal) {
|
|
6772
|
+
const fromSessionGuild = (0, priority_cooldown_1.canonicalGuildPriorityKey)(session);
|
|
6773
|
+
await session.send(`【设置群组优先】请在 ${Math.floor(promptMs / 1000)} 秒内发送群标识(如 qq:123456)${fromSessionGuild ? `\n直接发送 0 则使用当前群 ${fromSessionGuild}` : ''}\n${INTERACTIVE_CANCEL_HINT}`);
|
|
6774
|
+
const r1 = await waitForUserReply(session, ctx, promptMs);
|
|
6775
|
+
const replyText = r1?.content?.trim() || '';
|
|
6776
|
+
if (isInteractiveCancel(replyText))
|
|
6777
|
+
return '操作已取消';
|
|
6778
|
+
if (replyText === '0' && fromSessionGuild) {
|
|
6779
|
+
guildFinal = fromSessionGuild;
|
|
6780
|
+
}
|
|
6781
|
+
else if (replyText) {
|
|
6782
|
+
guildFinal = replyText;
|
|
6783
|
+
}
|
|
6784
|
+
else {
|
|
6785
|
+
return '操作已取消';
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
// 时长
|
|
6789
|
+
await session.send(`请发送时长规格(永久 / 7d / 30d / clear 等)\n${INTERACTIVE_CANCEL_HINT}`);
|
|
6790
|
+
const r2 = await waitForUserReply(session, ctx, promptMs);
|
|
6791
|
+
const replyText = r2?.content?.trim() || '';
|
|
6792
|
+
if (!replyText || isInteractiveCancel(replyText))
|
|
6793
|
+
return '操作已取消';
|
|
6794
|
+
specFinal = replyText;
|
|
6705
6795
|
}
|
|
6706
|
-
const sp = (0, priority_cooldown_1.parsePriorityAdminSpec)(
|
|
6796
|
+
const sp = (0, priority_cooldown_1.parsePriorityAdminSpec)(specFinal);
|
|
6707
6797
|
if (sp === null) {
|
|
6708
6798
|
return '❌ 无效的 spec,示例:永久、7d、clear';
|
|
6709
6799
|
}
|
|
6710
|
-
let gk = (
|
|
6800
|
+
let gk = (guildFinal.trim() || (0, priority_cooldown_1.canonicalGuildPriorityKey)(session) || '').trim();
|
|
6711
6801
|
gk = normalizeGuildKeyForPriority(gk, session);
|
|
6712
6802
|
if (!gk) {
|
|
6713
6803
|
return '❌ 请使用 -g 指定群标识(platform:guildId),或在群聊内执行。';
|