koishi-plugin-cocoyyy-console 1.2.0-alpha.1 → 1.2.0
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/config/config.d.ts +1 -0
- package/lib/config/configs/function_config.d.ts +1 -0
- package/lib/config/configs/jm_config.d.ts +10 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +322 -49
- package/lib/services/group_func_limit_service.d.ts +12 -1
- package/lib/services/jm_func/jm_command.d.ts +4 -0
- package/lib/services/jm_func/jm_service.d.ts +34 -0
- package/package.json +1 -1
package/lib/config/config.d.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Schema } from 'koishi';
|
|
2
|
+
interface JmConfig {
|
|
3
|
+
api_url?: string;
|
|
4
|
+
api_key?: string;
|
|
5
|
+
poll_interval_ms?: number;
|
|
6
|
+
poll_timeout_ms?: number;
|
|
7
|
+
max_concurrent_per_guild?: number;
|
|
8
|
+
}
|
|
9
|
+
declare const JmConfigSchema: Schema<JmConfig>;
|
|
10
|
+
export { JmConfig, JmConfigSchema, };
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -39,7 +39,7 @@ __export(src_exports, {
|
|
|
39
39
|
savePath: () => savePath
|
|
40
40
|
});
|
|
41
41
|
module.exports = __toCommonJS(src_exports);
|
|
42
|
-
var
|
|
42
|
+
var import_koishi18 = require("koishi");
|
|
43
43
|
|
|
44
44
|
// src/config/configs/function_config.ts
|
|
45
45
|
var import_koishi = require("koishi");
|
|
@@ -54,7 +54,8 @@ var FunctionConfigSchema = import_koishi.Schema.object({
|
|
|
54
54
|
wish_flag: import_koishi.Schema.boolean().default(true).description("许愿功能是否启用"),
|
|
55
55
|
game_flag: import_koishi.Schema.boolean().default(true).description("游戏功能是否启用"),
|
|
56
56
|
kuro_flag: import_koishi.Schema.boolean().default(true).description("鸣潮功能是否启用"),
|
|
57
|
-
sum_flag: import_koishi.Schema.boolean().default(true).description("总结功能是否启用")
|
|
57
|
+
sum_flag: import_koishi.Schema.boolean().default(true).description("总结功能是否启用"),
|
|
58
|
+
jm_flag: import_koishi.Schema.boolean().default(false).description("禁漫下载功能是否启用")
|
|
58
59
|
});
|
|
59
60
|
var GroupFunctionLimitConfigSchema = import_koishi.Schema.object({
|
|
60
61
|
cofig_enable_flag: import_koishi.Schema.boolean().default(true).description("功能限制是否启用"),
|
|
@@ -117,6 +118,16 @@ var SumConfigSchema = import_koishi8.Schema.object({
|
|
|
117
118
|
api_model: import_koishi8.Schema.string().default("").description("AI模型")
|
|
118
119
|
});
|
|
119
120
|
|
|
121
|
+
// src/config/configs/jm_config.ts
|
|
122
|
+
var import_koishi9 = require("koishi");
|
|
123
|
+
var JmConfigSchema = import_koishi9.Schema.object({
|
|
124
|
+
api_url: import_koishi9.Schema.string().default("http://127.0.0.1:6789").description("JM 下载服务地址"),
|
|
125
|
+
api_key: import_koishi9.Schema.string().default("").description("JM 下载服务 API Key(X-API-Key)"),
|
|
126
|
+
poll_interval_ms: import_koishi9.Schema.number().default(5e3).description("任务状态轮询间隔(毫秒)"),
|
|
127
|
+
poll_timeout_ms: import_koishi9.Schema.number().default(18e5).description("任务轮询超时(毫秒,默认 30 分钟)"),
|
|
128
|
+
max_concurrent_per_guild: import_koishi9.Schema.number().default(5).description("每个群聊同时进行的最大下载任务数")
|
|
129
|
+
});
|
|
130
|
+
|
|
120
131
|
// src/infra/mysql_init.ts
|
|
121
132
|
var import_sequelize = require("sequelize");
|
|
122
133
|
var sequelize = null;
|
|
@@ -370,6 +381,27 @@ function loadGroupFunctionLimitConfig(config) {
|
|
|
370
381
|
}
|
|
371
382
|
}
|
|
372
383
|
__name(loadGroupFunctionLimitConfig, "loadGroupFunctionLimitConfig");
|
|
384
|
+
function getCtxForFunction(ctx, menuNumber) {
|
|
385
|
+
if (!groupFunctionLimitConfig || groupFunctionLimitConfig.length === 0) {
|
|
386
|
+
return ctx;
|
|
387
|
+
}
|
|
388
|
+
const defaultEntry = groupFunctionLimitConfig.find((item) => String(item.group_id) === "#");
|
|
389
|
+
const defaultAllowed = defaultEntry ? defaultEntry.menu_list.includes(menuNumber) : false;
|
|
390
|
+
const explicitGroups = groupFunctionLimitConfig.filter((item) => String(item.group_id) !== "#");
|
|
391
|
+
if (defaultAllowed) {
|
|
392
|
+
const excludedIds = explicitGroups.filter((item) => !item.menu_list.includes(menuNumber)).map((item) => String(item.group_id));
|
|
393
|
+
if (excludedIds.length === 0) return ctx;
|
|
394
|
+
return ctx.exclude((session) => !!session.guildId && excludedIds.includes(session.guildId));
|
|
395
|
+
} else {
|
|
396
|
+
const includedIds = explicitGroups.filter((item) => item.menu_list.includes(menuNumber)).map((item) => String(item.group_id));
|
|
397
|
+
if (includedIds.length === 0) {
|
|
398
|
+
logger.info(`[getCtxForFunction Info]: 功能 ${menuNumber} 在所有群组中均未启用,跳过注册`);
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
return ctx.guild(...includedIds);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
__name(getCtxForFunction, "getCtxForFunction");
|
|
373
405
|
function getGroupFunctionLimitConfig() {
|
|
374
406
|
return groupFunctionLimitConfig;
|
|
375
407
|
}
|
|
@@ -477,6 +509,12 @@ function getMenuListByCommand(command = null, functionConfig, session) {
|
|
|
477
509
|
if (!isCommandAllowedForGuild(9, guildId))
|
|
478
510
|
return "当前群聊已限制总结功能";
|
|
479
511
|
return buildFuncMenu("总结功能菜单", "总结功能", sumFuncMenuList);
|
|
512
|
+
case menuByNumber.get(10)?.name:
|
|
513
|
+
if (!functionConfig.jm_flag)
|
|
514
|
+
return "禁漫下载功能已关闭";
|
|
515
|
+
if (!isCommandAllowedForGuild(10, guildId))
|
|
516
|
+
return "当前群聊已限制禁漫下载功能";
|
|
517
|
+
return buildFuncMenu("禁漫下载功能菜单", "禁漫下载功能", jmFuncMenuList);
|
|
480
518
|
default:
|
|
481
519
|
const allowedMenuNumbers = getAllowedMenuNumbersForGuild(guildId);
|
|
482
520
|
const finalMenuList = allowedMenuNumbers ? allMenus.filter((item) => allowedMenuNumbers.includes(item.number)) : allMenus;
|
|
@@ -618,6 +656,13 @@ var sumFuncMenuList = [
|
|
|
618
656
|
command: "sum [时间范围(1-168小时)]"
|
|
619
657
|
}
|
|
620
658
|
];
|
|
659
|
+
var jmFuncMenuList = [
|
|
660
|
+
{
|
|
661
|
+
name: "jm",
|
|
662
|
+
description: "提交禁漫本子下载任务",
|
|
663
|
+
command: "jm [comic_id]"
|
|
664
|
+
}
|
|
665
|
+
];
|
|
621
666
|
function registerMenuCommands(ctx, connected, functionConfig) {
|
|
622
667
|
ctx.command("help <参数>", "帮助菜单").action(async ({ session }, ...args) => {
|
|
623
668
|
if (!dev_mode) {
|
|
@@ -631,7 +676,7 @@ function registerMenuCommands(ctx, connected, functionConfig) {
|
|
|
631
676
|
__name(registerMenuCommands, "registerMenuCommands");
|
|
632
677
|
|
|
633
678
|
// src/services/tag_func/tag_commands.ts
|
|
634
|
-
var
|
|
679
|
+
var import_koishi11 = require("koishi");
|
|
635
680
|
|
|
636
681
|
// src/services/tag_func/tag_service.ts
|
|
637
682
|
var import_sequelize4 = require("sequelize");
|
|
@@ -639,7 +684,7 @@ var import_fs3 = require("fs");
|
|
|
639
684
|
var import_path3 = require("path");
|
|
640
685
|
|
|
641
686
|
// src/services/tag_func/img_service.ts
|
|
642
|
-
var
|
|
687
|
+
var import_koishi10 = require("koishi");
|
|
643
688
|
var import_path2 = require("path");
|
|
644
689
|
var import_fs2 = require("fs");
|
|
645
690
|
async function loadImageFromUrl(ctx, url) {
|
|
@@ -714,7 +759,7 @@ async function randomImgByTag(tag_name, guild_id) {
|
|
|
714
759
|
if (ImgList.length <= 0) {
|
|
715
760
|
throw new Error("Don't have image!");
|
|
716
761
|
}
|
|
717
|
-
const random = new
|
|
762
|
+
const random = new import_koishi10.Random(() => Math.random());
|
|
718
763
|
let result = ImgList[random.int(0, ImgList.length)];
|
|
719
764
|
const filePath = result.get("img_url");
|
|
720
765
|
return filePath;
|
|
@@ -998,13 +1043,13 @@ function registerTagCommands(ctx, connected, savePath2) {
|
|
|
998
1043
|
if (!exec2)
|
|
999
1044
|
return `获取图片失败`;
|
|
1000
1045
|
return `第${exec2.page}页,共${exec2.total}页
|
|
1001
|
-
${exec2.result?.map((item) =>
|
|
1046
|
+
${exec2.result?.map((item) => import_koishi11.h.image((0, import_url.pathToFileURL)(item).href)).join("\n\n")}`;
|
|
1002
1047
|
}
|
|
1003
1048
|
let exec = await randomImgByTag(tag, session.guildId);
|
|
1004
1049
|
if (!exec)
|
|
1005
1050
|
return `获取图片失败`;
|
|
1006
1051
|
let path2 = (0, import_url.pathToFileURL)(exec).href;
|
|
1007
|
-
return
|
|
1052
|
+
return import_koishi11.h.image(path2);
|
|
1008
1053
|
});
|
|
1009
1054
|
ctx.command("bind <参数>", "标签绑定别名").action(async ({ session }, ...args) => {
|
|
1010
1055
|
if (!dev_mode) {
|
|
@@ -1147,7 +1192,7 @@ function registerRepeatMiddleware(ctx, config) {
|
|
|
1147
1192
|
__name(registerRepeatMiddleware, "registerRepeatMiddleware");
|
|
1148
1193
|
|
|
1149
1194
|
// src/services/rbq_func/rbq_command.ts
|
|
1150
|
-
var
|
|
1195
|
+
var import_koishi12 = require("koishi");
|
|
1151
1196
|
|
|
1152
1197
|
// src/models/rbq_persons.ts
|
|
1153
1198
|
var import_sequelize5 = require("sequelize");
|
|
@@ -1474,7 +1519,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1474
1519
|
if (!list || list.length === 0) {
|
|
1475
1520
|
return "当前群聊还没有设置任何rbq";
|
|
1476
1521
|
}
|
|
1477
|
-
return "当前群聊rbq列表:\n" + list.map((item) => (0,
|
|
1522
|
+
return "当前群聊rbq列表:\n" + list.map((item) => (0, import_koishi12.h)("at", { id: item })).join(",");
|
|
1478
1523
|
});
|
|
1479
1524
|
ctx.command("rbqadd <参数>", "添加rbq").action(async ({ session }, ...args) => {
|
|
1480
1525
|
if (!dev_mode) {
|
|
@@ -1492,7 +1537,7 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1492
1537
|
exec = await create_person(session.guildId, uid);
|
|
1493
1538
|
if (!exec.result)
|
|
1494
1539
|
return `添加rbq失败: ${exec.error}`;
|
|
1495
|
-
return "已添加rbq:" + (0,
|
|
1540
|
+
return "已添加rbq:" + (0, import_koishi12.h)("at", { id: uid });
|
|
1496
1541
|
});
|
|
1497
1542
|
ctx.command("rbqinstead <参数>", "替换rbq").action(async ({ session }, ...args) => {
|
|
1498
1543
|
if (!dev_mode) {
|
|
@@ -1517,12 +1562,12 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1517
1562
|
exec = await instead_person(session.guildId, source_uid, new_target);
|
|
1518
1563
|
if (!exec.result)
|
|
1519
1564
|
return `替换rbq失败:${exec.error}`;
|
|
1520
|
-
return "倒反天罡!进去吧你,已替换rbq:\n" + (0,
|
|
1565
|
+
return "倒反天罡!进去吧你,已替换rbq:\n" + (0, import_koishi12.h)("at", { id: source_uid }) + " -> " + (0, import_koishi12.h)("at", { id: new_target });
|
|
1521
1566
|
}
|
|
1522
1567
|
exec = await instead_person(session.guildId, source_uid, target_uid);
|
|
1523
1568
|
if (!exec.result)
|
|
1524
1569
|
return `替换rbq失败:${exec.error}`;
|
|
1525
|
-
return (0,
|
|
1570
|
+
return (0, import_koishi12.h)("p", "已替换rbq:", (0, import_koishi12.h)("at", { id: source_uid }), " -> ", (0, import_koishi12.h)("at", { id: target_uid }));
|
|
1526
1571
|
});
|
|
1527
1572
|
ctx.command("rbqadd_txt <参数>", "添加自定义文本").action(async ({ session }, ...args) => {
|
|
1528
1573
|
if (!dev_mode) {
|
|
@@ -1549,10 +1594,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1549
1594
|
const contents = await get_content_list(session.guildId, target_uid);
|
|
1550
1595
|
let content2 = "*死你";
|
|
1551
1596
|
if (contents && contents.length > 0) {
|
|
1552
|
-
const random = new
|
|
1597
|
+
const random = new import_koishi12.Random(() => Math.random());
|
|
1553
1598
|
content2 = contents[random.int(0, contents.length)];
|
|
1554
1599
|
}
|
|
1555
|
-
return (0,
|
|
1600
|
+
return (0, import_koishi12.h)("at", { id: target_uid }) + "还想自己加文本?!\n" + content2;
|
|
1556
1601
|
} catch (error) {
|
|
1557
1602
|
logger.error("[rbq rbqadd_txt] Error:", error);
|
|
1558
1603
|
return "不能给自己设置文本,请输入其他qq号";
|
|
@@ -1582,10 +1627,10 @@ function registerRbqCommands(ctx, connected) {
|
|
|
1582
1627
|
const contents = await get_content_list(guildId, matchedUid);
|
|
1583
1628
|
let content = "*死你";
|
|
1584
1629
|
if (contents && contents.length > 0) {
|
|
1585
|
-
const random = new
|
|
1630
|
+
const random = new import_koishi12.Random(() => Math.random());
|
|
1586
1631
|
content = contents[random.int(0, contents.length)];
|
|
1587
1632
|
}
|
|
1588
|
-
return (0,
|
|
1633
|
+
return (0, import_koishi12.h)("at", { id: matchedUid }) + " " + content;
|
|
1589
1634
|
} catch (error) {
|
|
1590
1635
|
logger.error("[rbq middleware] Error:", error);
|
|
1591
1636
|
return next();
|
|
@@ -1810,7 +1855,7 @@ __name(is_at_bot_quote, "is_at_bot_quote");
|
|
|
1810
1855
|
|
|
1811
1856
|
// src/services/himg_func/himg_service.ts
|
|
1812
1857
|
var import_axios2 = __toESM(require("axios"));
|
|
1813
|
-
var
|
|
1858
|
+
var import_koishi13 = require("koishi");
|
|
1814
1859
|
async function randomHImg(keywords, ...args) {
|
|
1815
1860
|
try {
|
|
1816
1861
|
const r18 = keywords?.[0];
|
|
@@ -1840,7 +1885,7 @@ async function randomHImg(keywords, ...args) {
|
|
|
1840
1885
|
let author = item.author;
|
|
1841
1886
|
let url = item.urls.regular;
|
|
1842
1887
|
let tags2 = item.tags;
|
|
1843
|
-
result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" +
|
|
1888
|
+
result_content += "作者: " + author + "\n标签: \n[" + tags2.join(",") + "]\n" + import_koishi13.h.image(url) + "\n";
|
|
1844
1889
|
}
|
|
1845
1890
|
return {
|
|
1846
1891
|
result: result_content,
|
|
@@ -1897,7 +1942,7 @@ function registerHImgCommands(ctx) {
|
|
|
1897
1942
|
__name(registerHImgCommands, "registerHImgCommands");
|
|
1898
1943
|
|
|
1899
1944
|
// src/services/wish_func/wish_command.ts
|
|
1900
|
-
var
|
|
1945
|
+
var import_koishi14 = require("koishi");
|
|
1901
1946
|
|
|
1902
1947
|
// src/services/wish_func/wish_service.ts
|
|
1903
1948
|
var chatHistory2 = [];
|
|
@@ -2272,9 +2317,9 @@ function registerWishCommands(ctx, yaml_config_path, ai_config, wish_config) {
|
|
|
2272
2317
|
if (!exec_generation) return "愿望实现失败,请重新许愿";
|
|
2273
2318
|
const imageResult = await renderWishImage(ctx, wish_content, exec_generation);
|
|
2274
2319
|
if (typeof imageResult === "string") {
|
|
2275
|
-
return (0,
|
|
2320
|
+
return (0, import_koishi14.h)("at", { id: session.userId }) + " " + imageResult + "\n" + exec_generation;
|
|
2276
2321
|
}
|
|
2277
|
-
return (0,
|
|
2322
|
+
return (0, import_koishi14.h)("at", { id: session.userId }) + " 祈祷成功,愿梦想成真!\n" + import_koishi14.h.image(imageResult, "image/png");
|
|
2278
2323
|
} finally {
|
|
2279
2324
|
think_flag2 = false;
|
|
2280
2325
|
}
|
|
@@ -2693,7 +2738,7 @@ function registerKuroCommands(ctx, connected) {
|
|
|
2693
2738
|
__name(registerKuroCommands, "registerKuroCommands");
|
|
2694
2739
|
|
|
2695
2740
|
// src/services/game_func/game_command.ts
|
|
2696
|
-
var
|
|
2741
|
+
var import_koishi15 = require("koishi");
|
|
2697
2742
|
|
|
2698
2743
|
// src/services/game_func/game_service.ts
|
|
2699
2744
|
var gameTimeout = null;
|
|
@@ -3059,7 +3104,7 @@ async function situationPuzzleMiddleware(session, ai_config) {
|
|
|
3059
3104
|
return checkResp(resp2);
|
|
3060
3105
|
}
|
|
3061
3106
|
const resp = await questSituationPuzzle(text, ai_config);
|
|
3062
|
-
return (0,
|
|
3107
|
+
return (0, import_koishi15.h)("at", { id: userId }) + " " + checkResp(resp);
|
|
3063
3108
|
} finally {
|
|
3064
3109
|
is_thinking = false;
|
|
3065
3110
|
}
|
|
@@ -3074,7 +3119,7 @@ function checkResp(resp) {
|
|
|
3074
3119
|
__name(checkResp, "checkResp");
|
|
3075
3120
|
|
|
3076
3121
|
// src/services/sum_func/sum_command.ts
|
|
3077
|
-
var
|
|
3122
|
+
var import_koishi16 = require("koishi");
|
|
3078
3123
|
|
|
3079
3124
|
// src/services/sum_func/sum_service.ts
|
|
3080
3125
|
var import_sequelize10 = require("sequelize");
|
|
@@ -3595,7 +3640,7 @@ function registerSumCommands(ctx, yaml_config_path, ai_config, sum_config) {
|
|
|
3595
3640
|
const imageResult = await renderChatSummaryImage(ctx, exec.result, exec.hours, exec.stats, false);
|
|
3596
3641
|
if (typeof imageResult === "string")
|
|
3597
3642
|
return imageResult + "\n" + exec.result;
|
|
3598
|
-
return
|
|
3643
|
+
return import_koishi16.h.image(imageResult, "image/png");
|
|
3599
3644
|
}
|
|
3600
3645
|
return exec.result;
|
|
3601
3646
|
});
|
|
@@ -3606,23 +3651,239 @@ function registerSumCommands(ctx, yaml_config_path, ai_config, sum_config) {
|
|
|
3606
3651
|
}
|
|
3607
3652
|
__name(registerSumCommands, "registerSumCommands");
|
|
3608
3653
|
|
|
3654
|
+
// src/services/jm_func/jm_service.ts
|
|
3655
|
+
var import_axios4 = __toESM(require("axios"));
|
|
3656
|
+
var import_fs4 = require("fs");
|
|
3657
|
+
var import_koishi17 = require("koishi");
|
|
3658
|
+
var guildActiveTasks = /* @__PURE__ */ new Map();
|
|
3659
|
+
function normalizeBaseUrl(apiUrl) {
|
|
3660
|
+
return apiUrl.replace(/\/+$/, "");
|
|
3661
|
+
}
|
|
3662
|
+
__name(normalizeBaseUrl, "normalizeBaseUrl");
|
|
3663
|
+
function buildHeaders(config) {
|
|
3664
|
+
const headers = {
|
|
3665
|
+
"Content-Type": "application/json"
|
|
3666
|
+
};
|
|
3667
|
+
if (config.api_key)
|
|
3668
|
+
headers["X-API-Key"] = config.api_key;
|
|
3669
|
+
return headers;
|
|
3670
|
+
}
|
|
3671
|
+
__name(buildHeaders, "buildHeaders");
|
|
3672
|
+
function getMaxConcurrent(config) {
|
|
3673
|
+
const max = config.max_concurrent_per_guild ?? 5;
|
|
3674
|
+
return max > 0 ? max : 5;
|
|
3675
|
+
}
|
|
3676
|
+
__name(getMaxConcurrent, "getMaxConcurrent");
|
|
3677
|
+
function registerTask(record, config) {
|
|
3678
|
+
const guildId = record.guildId;
|
|
3679
|
+
const list = guildActiveTasks.get(guildId) ?? [];
|
|
3680
|
+
if (list.length >= getMaxConcurrent(config))
|
|
3681
|
+
return false;
|
|
3682
|
+
list.push(record);
|
|
3683
|
+
guildActiveTasks.set(guildId, list);
|
|
3684
|
+
return true;
|
|
3685
|
+
}
|
|
3686
|
+
__name(registerTask, "registerTask");
|
|
3687
|
+
function updateTaskId(guildId, oldTaskId, newTaskId) {
|
|
3688
|
+
const list = guildActiveTasks.get(guildId);
|
|
3689
|
+
if (!list) return;
|
|
3690
|
+
const target = list.find((item) => item.taskId === oldTaskId);
|
|
3691
|
+
if (target)
|
|
3692
|
+
target.taskId = newTaskId;
|
|
3693
|
+
}
|
|
3694
|
+
__name(updateTaskId, "updateTaskId");
|
|
3695
|
+
function unregisterTask(guildId, taskId) {
|
|
3696
|
+
const list = guildActiveTasks.get(guildId);
|
|
3697
|
+
if (!list) return;
|
|
3698
|
+
const next = list.filter((item) => item.taskId !== taskId);
|
|
3699
|
+
if (next.length === 0)
|
|
3700
|
+
guildActiveTasks.delete(guildId);
|
|
3701
|
+
else
|
|
3702
|
+
guildActiveTasks.set(guildId, next);
|
|
3703
|
+
}
|
|
3704
|
+
__name(unregisterTask, "unregisterTask");
|
|
3705
|
+
function sleep(ms) {
|
|
3706
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3707
|
+
}
|
|
3708
|
+
__name(sleep, "sleep");
|
|
3709
|
+
async function submitDownload(albumId, config) {
|
|
3710
|
+
const baseUrl = normalizeBaseUrl(config.api_url || "http://127.0.0.1:6789");
|
|
3711
|
+
try {
|
|
3712
|
+
const response = await import_axios4.default.post(
|
|
3713
|
+
`${baseUrl}/api/download`,
|
|
3714
|
+
{ album_id: albumId },
|
|
3715
|
+
{ headers: buildHeaders(config), timeout: 3e4 }
|
|
3716
|
+
);
|
|
3717
|
+
return { ok: true, data: response.data };
|
|
3718
|
+
} catch (error) {
|
|
3719
|
+
const message = error?.response?.data?.detail ?? error?.response?.data?.message ?? error?.message ?? String(error);
|
|
3720
|
+
logger.error("[jm submitDownload Error]: " + message);
|
|
3721
|
+
return { ok: false, error: message };
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
__name(submitDownload, "submitDownload");
|
|
3725
|
+
async function getTask(taskId, config) {
|
|
3726
|
+
const baseUrl = normalizeBaseUrl(config.api_url || "http://127.0.0.1:6789");
|
|
3727
|
+
try {
|
|
3728
|
+
const response = await import_axios4.default.get(
|
|
3729
|
+
`${baseUrl}/api/task/${taskId}`,
|
|
3730
|
+
{ headers: buildHeaders(config), timeout: 3e4 }
|
|
3731
|
+
);
|
|
3732
|
+
return { ok: true, data: response.data };
|
|
3733
|
+
} catch (error) {
|
|
3734
|
+
const message = error?.response?.data?.detail ?? error?.response?.data?.message ?? error?.message ?? String(error);
|
|
3735
|
+
logger.error("[jm getTask Error]: " + message);
|
|
3736
|
+
return { ok: false, error: message };
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
__name(getTask, "getTask");
|
|
3740
|
+
async function deleteAlbum(albumId, config) {
|
|
3741
|
+
const baseUrl = normalizeBaseUrl(config.api_url || "http://127.0.0.1:6789");
|
|
3742
|
+
try {
|
|
3743
|
+
await import_axios4.default.delete(
|
|
3744
|
+
`${baseUrl}/api/album/${albumId}`,
|
|
3745
|
+
{ headers: buildHeaders(config), timeout: 3e4 }
|
|
3746
|
+
);
|
|
3747
|
+
logger.info(`[jm deleteAlbum Info]: album_id=${albumId} cleaned up`);
|
|
3748
|
+
} catch (error) {
|
|
3749
|
+
if (error?.response?.status === 404) {
|
|
3750
|
+
logger.info(`[jm deleteAlbum Info]: album_id=${albumId} no local files to delete`);
|
|
3751
|
+
return;
|
|
3752
|
+
}
|
|
3753
|
+
const message = error?.response?.data?.detail ?? error?.response?.data?.message ?? error?.message ?? String(error);
|
|
3754
|
+
logger.warn("[jm deleteAlbum Error]: " + message);
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
__name(deleteAlbum, "deleteAlbum");
|
|
3758
|
+
async function readLocalPdf(pdfPath) {
|
|
3759
|
+
return import_fs4.promises.readFile(pdfPath);
|
|
3760
|
+
}
|
|
3761
|
+
__name(readLocalPdf, "readLocalPdf");
|
|
3762
|
+
async function notifyUser(bot, record, message) {
|
|
3763
|
+
await bot.sendMessage(record.channelId, message);
|
|
3764
|
+
}
|
|
3765
|
+
__name(notifyUser, "notifyUser");
|
|
3766
|
+
async function pollAndDeliver(bot, record, config) {
|
|
3767
|
+
const pollInterval = config.poll_interval_ms ?? 5e3;
|
|
3768
|
+
const pollTimeout = config.poll_timeout_ms ?? 18e5;
|
|
3769
|
+
const startedAt = Date.now();
|
|
3770
|
+
const deliver = /* @__PURE__ */ __name(async (message) => {
|
|
3771
|
+
await deleteAlbum(record.albumId, config);
|
|
3772
|
+
await notifyUser(bot, record, message);
|
|
3773
|
+
}, "deliver");
|
|
3774
|
+
try {
|
|
3775
|
+
while (true) {
|
|
3776
|
+
if (Date.now() - startedAt > pollTimeout) {
|
|
3777
|
+
await deliver(`${(0, import_koishi17.h)("at", { id: record.userId })} 下载超时,请稍后重试。`);
|
|
3778
|
+
return;
|
|
3779
|
+
}
|
|
3780
|
+
await sleep(pollInterval);
|
|
3781
|
+
const result = await getTask(record.taskId, config);
|
|
3782
|
+
if (!result.ok) {
|
|
3783
|
+
await deliver(`${(0, import_koishi17.h)("at", { id: record.userId })} 查询任务失败:${result.error}`);
|
|
3784
|
+
return;
|
|
3785
|
+
}
|
|
3786
|
+
const task = result.data;
|
|
3787
|
+
if (task.status === "pending" || task.status === "running")
|
|
3788
|
+
continue;
|
|
3789
|
+
if (task.status === "failed") {
|
|
3790
|
+
const errorMsg = task.error || task.message || "未知错误";
|
|
3791
|
+
logger.error(
|
|
3792
|
+
`[jm task Failed]: album_id=${record.albumId} task_id=${record.taskId} error=${errorMsg}`
|
|
3793
|
+
);
|
|
3794
|
+
await deliver(`${(0, import_koishi17.h)("at", { id: record.userId })} 下载失败:${errorMsg}`);
|
|
3795
|
+
return;
|
|
3796
|
+
}
|
|
3797
|
+
if (task.status === "success") {
|
|
3798
|
+
let message;
|
|
3799
|
+
try {
|
|
3800
|
+
const pdfPath = task.pdf_path;
|
|
3801
|
+
if (!pdfPath)
|
|
3802
|
+
throw new Error("任务成功但未返回文件路径");
|
|
3803
|
+
const pdfBuffer = await readLocalPdf(pdfPath);
|
|
3804
|
+
const filename = `${record.albumId}.pdf` || task.pdf_filename;
|
|
3805
|
+
message = [
|
|
3806
|
+
(0, import_koishi17.h)("at", { id: record.userId }),
|
|
3807
|
+
` 本子[${record.albumId}]下载完成:`,
|
|
3808
|
+
import_koishi17.h.file(pdfBuffer, "application/pdf", { name: filename })
|
|
3809
|
+
];
|
|
3810
|
+
} catch (error) {
|
|
3811
|
+
const errorMsg = error?.message || String(error);
|
|
3812
|
+
logger.error("[jm readLocalPdf Error]: " + errorMsg);
|
|
3813
|
+
message = `${(0, import_koishi17.h)("at", { id: record.userId })} 文件读取失败:${errorMsg}`;
|
|
3814
|
+
}
|
|
3815
|
+
await deliver(message);
|
|
3816
|
+
return;
|
|
3817
|
+
}
|
|
3818
|
+
}
|
|
3819
|
+
} finally {
|
|
3820
|
+
unregisterTask(record.guildId, record.taskId);
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3823
|
+
__name(pollAndDeliver, "pollAndDeliver");
|
|
3824
|
+
async function startJmDownload(bot, record, config) {
|
|
3825
|
+
void pollAndDeliver(bot, record, config);
|
|
3826
|
+
}
|
|
3827
|
+
__name(startJmDownload, "startJmDownload");
|
|
3828
|
+
|
|
3829
|
+
// src/services/jm_func/jm_command.ts
|
|
3830
|
+
function registerJmCommands(ctx, jm_config) {
|
|
3831
|
+
ctx.command("jm <参数>", "提交禁漫本子下载任务").action(async ({ session }, ...args) => {
|
|
3832
|
+
if (!dev_mode) {
|
|
3833
|
+
if (!is_at_bot(session)) return;
|
|
3834
|
+
}
|
|
3835
|
+
const albumId = args?.[0]?.trim();
|
|
3836
|
+
if (!albumId)
|
|
3837
|
+
return "请提供正确格式,如:@bot jm [comic_id]";
|
|
3838
|
+
if (!/^\d+$/.test(albumId))
|
|
3839
|
+
return "comic_id 应为数字,如:@bot jm 123456";
|
|
3840
|
+
const guildId = session.guildId;
|
|
3841
|
+
const channelId = session.channelId;
|
|
3842
|
+
const userId = session.userId;
|
|
3843
|
+
if (!guildId || !channelId || !userId)
|
|
3844
|
+
return "无法获取群聊或用户信息";
|
|
3845
|
+
const maxConcurrent = jm_config.max_concurrent_per_guild ?? 5;
|
|
3846
|
+
const pendingTaskId = `pending-${Date.now()}-${userId}`;
|
|
3847
|
+
const record = {
|
|
3848
|
+
taskId: pendingTaskId,
|
|
3849
|
+
guildId,
|
|
3850
|
+
channelId,
|
|
3851
|
+
userId,
|
|
3852
|
+
albumId
|
|
3853
|
+
};
|
|
3854
|
+
if (!registerTask(record, jm_config))
|
|
3855
|
+
return `当前群聊已有${maxConcurrent}个下载任务进行中,请稍后再试`;
|
|
3856
|
+
const submitResult = await submitDownload(albumId, jm_config);
|
|
3857
|
+
if (!submitResult.ok) {
|
|
3858
|
+
unregisterTask(guildId, pendingTaskId);
|
|
3859
|
+
return `提交下载失败:${submitResult.error}`;
|
|
3860
|
+
}
|
|
3861
|
+
const taskId = submitResult.data.task_id;
|
|
3862
|
+
updateTaskId(guildId, pendingTaskId, taskId);
|
|
3863
|
+
startJmDownload(session.bot, record, jm_config);
|
|
3864
|
+
return `已收到本子[${albumId}]的下载请求,完成后会在此群@你。`;
|
|
3865
|
+
});
|
|
3866
|
+
}
|
|
3867
|
+
__name(registerJmCommands, "registerJmCommands");
|
|
3868
|
+
|
|
3609
3869
|
// src/index.ts
|
|
3610
3870
|
var name = "cocoyyy-console";
|
|
3611
3871
|
var inject = { optional: ["puppeteer"] };
|
|
3612
3872
|
var dev_mode;
|
|
3613
|
-
var Config =
|
|
3873
|
+
var Config = import_koishi18.Schema.object({
|
|
3614
3874
|
function_config: FunctionConfigSchema.description("功能开关配置"),
|
|
3615
3875
|
function_enable_config: GroupFunctionLimitConfigSchema.description("群聊功能限制配置"),
|
|
3616
3876
|
ai_config: AiAPIConfigSchema.description("AI API配置"),
|
|
3617
|
-
yaml_config_path:
|
|
3877
|
+
yaml_config_path: import_koishi18.Schema.string().default("").description("统一配置文件路径"),
|
|
3618
3878
|
mysql_config: MysqlConfigSchema.description("MySQL 数据库配置"),
|
|
3619
3879
|
tag_config: SaveConfigSchema.description("tag图片保存配置"),
|
|
3620
3880
|
repeat_config: RepeatConfigSchema.description("复读配置"),
|
|
3621
3881
|
wish_config: WishConfigSchema.description("许愿配置"),
|
|
3622
3882
|
sum_config: SumConfigSchema.description("总结配置"),
|
|
3623
|
-
|
|
3883
|
+
jm_config: JmConfigSchema.description("禁漫下载配置"),
|
|
3884
|
+
test: import_koishi18.Schema.string().description("测试")
|
|
3624
3885
|
});
|
|
3625
|
-
var logger = new
|
|
3886
|
+
var logger = new import_koishi18.Logger(name);
|
|
3626
3887
|
var savePath = null;
|
|
3627
3888
|
async function apply(ctx, config) {
|
|
3628
3889
|
ctx = ctx.guild();
|
|
@@ -3640,26 +3901,38 @@ async function apply(ctx, config) {
|
|
|
3640
3901
|
savePath = resolveTagBaseDir(config?.tag_config);
|
|
3641
3902
|
loadGroupFunctionLimitConfig(config?.function_enable_config);
|
|
3642
3903
|
registerMenuCommands(ctx, connected, config.function_config);
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
if (config.function_config.
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
if (config.function_config.
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
if (config.function_config)
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3904
|
+
const tagCtx = getCtxForFunction(ctx, 1);
|
|
3905
|
+
if (config.function_config.tag_flag && tagCtx)
|
|
3906
|
+
registerTagCommands(tagCtx, connected, savePath);
|
|
3907
|
+
const repeatCtx = getCtxForFunction(ctx, 2);
|
|
3908
|
+
if (config.function_config.repeat_flag && repeatCtx)
|
|
3909
|
+
registerRepeatMiddleware(repeatCtx, config?.repeat_config);
|
|
3910
|
+
const rbqCtx = getCtxForFunction(ctx, 3);
|
|
3911
|
+
if (config.function_config.rbq_flag && rbqCtx)
|
|
3912
|
+
registerRbqCommands(rbqCtx, connected);
|
|
3913
|
+
const sonCtx = getCtxForFunction(ctx, 4);
|
|
3914
|
+
if (config.function_config.son_flag && sonCtx)
|
|
3915
|
+
registerShitOrNotCommands(sonCtx, config?.yaml_config_path, config?.ai_config);
|
|
3916
|
+
const setuCtx = getCtxForFunction(ctx, 5);
|
|
3917
|
+
if (config.function_config.setu_flag && setuCtx)
|
|
3918
|
+
registerHImgCommands(setuCtx);
|
|
3919
|
+
const wishCtx = getCtxForFunction(ctx, 6);
|
|
3920
|
+
if (config.function_config.wish_flag && wishCtx)
|
|
3921
|
+
registerWishCommands(wishCtx, config?.yaml_config_path, config?.ai_config, config?.wish_config);
|
|
3922
|
+
const gameCtx = getCtxForFunction(ctx, 7);
|
|
3923
|
+
if (config.function_config.game_flag && gameCtx) {
|
|
3924
|
+
registerGameCommands(gameCtx, config?.yaml_config_path, config?.ai_config);
|
|
3925
|
+
registerGameMiddleware(gameCtx, config?.ai_config);
|
|
3926
|
+
}
|
|
3927
|
+
const kuroCtx = getCtxForFunction(ctx, 8);
|
|
3928
|
+
if (config.function_config.kuro_flag && kuroCtx)
|
|
3929
|
+
registerKuroCommands(kuroCtx, connected);
|
|
3930
|
+
const sumCtx = getCtxForFunction(ctx, 9);
|
|
3931
|
+
if (config.function_config.sum_flag && sumCtx)
|
|
3932
|
+
registerSumCommands(sumCtx, config?.yaml_config_path, config?.ai_config, config?.sum_config);
|
|
3933
|
+
const jmCtx = getCtxForFunction(ctx, 10);
|
|
3934
|
+
if (config.function_config.jm_flag && jmCtx)
|
|
3935
|
+
registerJmCommands(jmCtx, config?.jm_config ?? {});
|
|
3663
3936
|
if (dev_mode)
|
|
3664
3937
|
registerTestCommands(ctx, config);
|
|
3665
3938
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as my_config from '../config/config';
|
|
2
|
+
import { Context } from 'koishi';
|
|
2
3
|
type GroupFunctionLimitItem = {
|
|
3
4
|
group_id: string | number;
|
|
4
5
|
menu_list: number[];
|
|
@@ -10,7 +11,17 @@ type MenuList = {
|
|
|
10
11
|
description: string;
|
|
11
12
|
};
|
|
12
13
|
declare function loadGroupFunctionLimitConfig(config: my_config.GroupFunctionLimitConfig): boolean;
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* 根据 groupFuncLimit.json 的 groupList 配置,为指定功能编号返回对应的 Koishi Context:
|
|
16
|
+
*
|
|
17
|
+
* - "#" 条目作为默认规则(适用于未在 groupList 中显式列出的所有群组)
|
|
18
|
+
* - 若默认规则允许该功能:返回排除了显式禁用该功能的群组的 ctx
|
|
19
|
+
* - 若默认规则不允许该功能:返回仅限显式允许该功能的群组的 ctx
|
|
20
|
+
* - 若没有任何群组允许该功能:返回 null(调用方应跳过注册)
|
|
21
|
+
* - 若未加载功能限制配置:直接返回原始 ctx(不加限制)
|
|
22
|
+
*/
|
|
23
|
+
declare function getCtxForFunction(ctx: Context, menuNumber: number): Context | null;
|
|
24
|
+
export { groupFunctionLimitConfig, loadGroupFunctionLimitConfig, getCtxForFunction, };
|
|
14
25
|
declare function getGroupFunctionLimitConfig(): GroupFunctionLimitItem[];
|
|
15
26
|
declare function getMenuList(): MenuList[];
|
|
16
27
|
export { getGroupFunctionLimitConfig, getMenuList, };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Bot } from 'koishi';
|
|
2
|
+
import { JmConfig } from '../../config/config';
|
|
3
|
+
type TaskStatus = 'pending' | 'running' | 'success' | 'failed';
|
|
4
|
+
interface DownloadResponse {
|
|
5
|
+
task_id: string;
|
|
6
|
+
status: TaskStatus;
|
|
7
|
+
album_id: string;
|
|
8
|
+
pdf_path?: string | null;
|
|
9
|
+
pdf_filename?: string | null;
|
|
10
|
+
error?: string | null;
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
interface JmTaskRecord {
|
|
14
|
+
taskId: string;
|
|
15
|
+
guildId: string;
|
|
16
|
+
channelId: string;
|
|
17
|
+
userId: string;
|
|
18
|
+
albumId: string;
|
|
19
|
+
}
|
|
20
|
+
declare function getActiveTaskCount(guildId: string): number;
|
|
21
|
+
declare function registerTask(record: JmTaskRecord, config: JmConfig): boolean;
|
|
22
|
+
declare function updateTaskId(guildId: string, oldTaskId: string, newTaskId: string): void;
|
|
23
|
+
declare function unregisterTask(guildId: string, taskId: string): void;
|
|
24
|
+
declare function submitDownload(albumId: string, config: JmConfig): Promise<{
|
|
25
|
+
ok: true;
|
|
26
|
+
data: DownloadResponse;
|
|
27
|
+
error?: undefined;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
error: any;
|
|
31
|
+
data?: undefined;
|
|
32
|
+
}>;
|
|
33
|
+
declare function startJmDownload(bot: Bot, record: JmTaskRecord, config: JmConfig): Promise<void>;
|
|
34
|
+
export { DownloadResponse, JmTaskRecord, getActiveTaskCount, registerTask, submitDownload, startJmDownload, unregisterTask, updateTaskId, };
|