koishi-plugin-gl-bot 0.0.11 → 0.0.12

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.
Files changed (66) hide show
  1. package/lib/gl/index.d.ts +36 -55
  2. package/lib/gl/index.js +4 -6
  3. package/lib/gl/queqiao.adapter.d.ts +11 -0
  4. package/lib/gl/queqiao.adapter.js +41 -0
  5. package/lib/mcsManager/api.d.ts +1 -0
  6. package/lib/mcsManager/api.js +13 -1
  7. package/lib/mcsManager/bot.d.ts +2 -2
  8. package/lib/mcsManager/bot.js +1 -0
  9. package/lib/mcsManager/commands/index.d.ts +1 -0
  10. package/lib/mcsManager/commands/index.js +3 -1
  11. package/lib/mcsManager/commands/mc/health.d.ts +16 -0
  12. package/lib/mcsManager/commands/mc/health.js +46 -0
  13. package/lib/mcsManager/commands/mc/list.d.ts +1 -0
  14. package/lib/mcsManager/commands/mc/list.js +21 -6
  15. package/lib/mcsManager/commands/mc/online.d.ts +6 -1
  16. package/lib/mcsManager/commands/mc/online.js +49 -12
  17. package/lib/mcsManager/config.d.ts +39 -0
  18. package/lib/mcsManager/config.js +21 -0
  19. package/lib/mcsManager/index.d.ts +32 -1
  20. package/lib/mcsManager/index.js +4 -1
  21. package/lib/mcsManager/type.d.ts +2 -0
  22. package/lib/queQiao/index.d.ts +47 -38
  23. package/lib/queQiao/index.js +82 -47
  24. package/lib/queQiao/locale/zh-CN.json +1 -1
  25. package/lib/queQiao/locale/zh-CN.yml +4 -4
  26. package/lib/queQiao/mcwss.d.ts +12 -9
  27. package/lib/queQiao/mcwss.js +34 -2
  28. package/lib/queQiao/values.js +2 -2
  29. package/lib/utils/game.mc.js +5 -4
  30. package/package.json +1 -1
  31. package/lib/constants/env.d.ts +0 -0
  32. package/lib/constants/env.js +0 -0
  33. package/lib/gl/index.type.d.ts +0 -0
  34. package/lib/gl/index.type.js +0 -0
  35. package/lib/mcsManager/commands/create.d.ts +0 -16
  36. package/lib/mcsManager/commands/create.js +0 -135
  37. package/lib/mcsManager/commands/list copy.d.ts +0 -13
  38. package/lib/mcsManager/commands/list copy.js +0 -34
  39. package/lib/mcsManager/commands/list.d.ts +0 -14
  40. package/lib/mcsManager/commands/list.js +0 -35
  41. package/lib/mcsManager/commands/mc/restart copy.d.ts +0 -15
  42. package/lib/mcsManager/commands/mc/restart copy.js +0 -62
  43. package/lib/mcsManager/commands/mc copy/create.d.ts +0 -16
  44. package/lib/mcsManager/commands/mc copy/create.js +0 -135
  45. package/lib/mcsManager/commands/mc copy/list.d.ts +0 -14
  46. package/lib/mcsManager/commands/mc copy/list.js +0 -35
  47. package/lib/mcsManager/commands/mc copy/restart.d.ts +0 -15
  48. package/lib/mcsManager/commands/mc copy/restart.js +0 -62
  49. package/lib/mcsManager/commands/mc copy/start.d.ts +0 -15
  50. package/lib/mcsManager/commands/mc copy/start.js +0 -54
  51. package/lib/mcsManager/commands/mc copy/stop.d.ts +0 -15
  52. package/lib/mcsManager/commands/mc copy/stop.js +0 -54
  53. package/lib/mcsManager/commands/restart.d.ts +0 -15
  54. package/lib/mcsManager/commands/restart.js +0 -62
  55. package/lib/mcsManager/commands/start copy.d.ts +0 -14
  56. package/lib/mcsManager/commands/start copy.js +0 -53
  57. package/lib/mcsManager/commands/start.d.ts +0 -15
  58. package/lib/mcsManager/commands/start.js +0 -54
  59. package/lib/mcsManager/commands/stop.d.ts +0 -15
  60. package/lib/mcsManager/commands/stop.js +0 -54
  61. package/lib/utils/file.download.d.ts +0 -47
  62. package/lib/utils/file.download.js +0 -142
  63. package/lib/utils/file.examples.d.ts +0 -12
  64. package/lib/utils/file.examples.js +0 -73
  65. package/lib/utils/napcat.file.d.ts +0 -63
  66. package/lib/utils/napcat.file.js +0 -133
@@ -1,15 +0,0 @@
1
- import { Argv } from 'koishi';
2
- import { MCSManagerBot } from '../../bot';
3
- import { MCBotCommandBase, MCBotCommandRole } from '../base';
4
- /**
5
- * 服务器关闭指令
6
- *
7
- * @example 服务器 关闭 神话
8
- */
9
- export declare class MCBotStopCommand extends MCBotCommandBase {
10
- readonly bot: MCSManagerBot;
11
- command: string[];
12
- roles: MCBotCommandRole[];
13
- constructor(bot: MCSManagerBot);
14
- handle({ session }: Argv, args: string[]): Promise<string>;
15
- }
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCBotStopCommand = void 0;
4
- const lodash_1 = require("lodash");
5
- const constants_1 = require("../../constants");
6
- const base_1 = require("../base");
7
- const tempSelections = new Map();
8
- /**
9
- * 服务器关闭指令
10
- *
11
- * @example 服务器 关闭 神话
12
- */
13
- class MCBotStopCommand extends base_1.MCBotCommandBase {
14
- constructor(bot) {
15
- super(bot);
16
- this.bot = bot;
17
- this.command = ['服务器.关闭 <name...>', 'MC.关闭 <name...>'];
18
- this.roles = [base_1.MCBotCommandRole.Admin, base_1.MCBotCommandRole.Owner];
19
- this.initialize();
20
- }
21
- async handle({ session }, args) {
22
- let name = (0, lodash_1.isString)(args) ? args : args.join(' ');
23
- let selectIndex = -1;
24
- const userId = Number(session.event.user.id);
25
- // 溯源前搜索项
26
- if (tempSelections.has(userId) && !isNaN(Number(name))) {
27
- selectIndex = Number(name) - 1;
28
- name = tempSelections.get(userId);
29
- }
30
- tempSelections.delete(userId);
31
- const nameInstances = await this.bot.panel.searchInstanceByName(name);
32
- if (nameInstances.length === 0) {
33
- return `未找到名称包含 "${name}" 的服务器`;
34
- }
35
- if (nameInstances.length > 1 && selectIndex === -1) {
36
- tempSelections.set(userId, name);
37
- return `请输入序号以选择:\n\n${nameInstances
38
- .map((item, index) => `${index + 1}. [${constants_1.RemoteInstanceStatusName[item.instance.cfg.status]}] ${item.instance.cfg.config.nickname}`)
39
- .join('\n')}\n ==== 例如发送: (服务器 关闭 1) ====`;
40
- }
41
- const targetInstance = selectIndex !== -1 ? nameInstances[selectIndex] : nameInstances[0];
42
- if (!targetInstance || !targetInstance.instance) {
43
- return `未找到名称包含 "${name}" 的服务器`;
44
- }
45
- const { cfg } = targetInstance.instance;
46
- if ((0, lodash_1.isEqual)(cfg.status, constants_1.RemoteInstanceStatusEnum.RUNNING)) {
47
- await targetInstance.instance.stopInstance();
48
- this.bot.panel.handleRemoteServices();
49
- return `已向服务器实例 "${cfg.config.nickname}" 发送关闭操作`;
50
- }
51
- return `服务器实例 "${cfg.config.nickname}" 当前状态为 ${cfg.status},无法执行关闭操作`;
52
- }
53
- }
54
- exports.MCBotStopCommand = MCBotStopCommand;
@@ -1,15 +0,0 @@
1
- import { Argv } from 'koishi';
2
- import { MCSManagerBot } from '../bot';
3
- import { MCBotCommandBase, MCBotCommandRole } from './base';
4
- /**
5
- * 服务器重启指令
6
- *
7
- * @example 服务器 重启 神话
8
- */
9
- export declare class MCBotRestartCommand extends MCBotCommandBase {
10
- readonly bot: MCSManagerBot;
11
- command: string[];
12
- roles: MCBotCommandRole[];
13
- constructor(bot: MCSManagerBot);
14
- handle({ session }: Argv, args: string[]): Promise<string>;
15
- }
@@ -1,62 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCBotRestartCommand = void 0;
4
- const lodash_1 = require("lodash");
5
- const constants_1 = require("../constants");
6
- const base_1 = require("./base");
7
- const tempSelections = new Map();
8
- /**
9
- * 服务器重启指令
10
- *
11
- * @example 服务器 重启 神话
12
- */
13
- class MCBotRestartCommand extends base_1.MCBotCommandBase {
14
- constructor(bot) {
15
- super(bot);
16
- this.bot = bot;
17
- this.command = ['服务器.重启 <name...>', 'MC.重启 <name...>'];
18
- this.roles = [base_1.MCBotCommandRole.Admin, base_1.MCBotCommandRole.Owner];
19
- this.initialize();
20
- }
21
- async handle({ session }, args) {
22
- let name = (0, lodash_1.isString)(args) ? args : args.join(' ');
23
- let selectIndex = -1;
24
- const userId = Number(session.event.user.id);
25
- // 溯源前搜索项
26
- if (tempSelections.has(userId) && !isNaN(Number(name))) {
27
- selectIndex = Number(name) - 1;
28
- name = tempSelections.get(userId);
29
- }
30
- tempSelections.delete(userId);
31
- const nameInstances = await this.bot.panel.searchInstanceByName(name);
32
- if (nameInstances.length === 0) {
33
- return `未找到名称包含 "${name}" 的服务器`;
34
- }
35
- if (nameInstances.length > 1 && selectIndex === -1) {
36
- tempSelections.set(userId, name);
37
- return `请输入序号以选择:\n\n${nameInstances
38
- .map((item, index) => `${index + 1}. [${constants_1.RemoteInstanceStatusName[item.instance.cfg.status]}] ${item.instance.cfg.config.nickname}`)
39
- .join('\n')}\n ==== 例如发送: (服务器 重启 1) ====`;
40
- }
41
- const targetInstance = selectIndex !== -1 ? nameInstances[selectIndex] : nameInstances[0];
42
- if (!targetInstance || !targetInstance.instance) {
43
- return `未找到名称包含 "${name}" 的服务器`;
44
- }
45
- const { cfg } = targetInstance.instance;
46
- switch (cfg.status) {
47
- // 关闭状态:启动
48
- case constants_1.RemoteInstanceStatusEnum.RUNNING:
49
- await targetInstance.instance.restartInstance();
50
- this.bot.panel.handleRemoteServices();
51
- return `已向服务器实例 "${cfg.config.nickname}" 发送重启操作`;
52
- // 启动状态:重启
53
- case constants_1.RemoteInstanceStatusEnum.STOPPED:
54
- await targetInstance.instance.startInstance();
55
- this.bot.panel.handleRemoteServices();
56
- return `已向服务器实例 "${cfg.config.nickname}" 发送启动操作`;
57
- default:
58
- return `服务器实例 "${cfg.config.nickname}" 当前状态为 ${cfg.status},无法执行重启操作`;
59
- }
60
- }
61
- }
62
- exports.MCBotRestartCommand = MCBotRestartCommand;
@@ -1,14 +0,0 @@
1
- import { Argv } from 'koishi';
2
- import { MCSManagerBot } from '../bot';
3
- import { MCBotCommandBase } from './base';
4
- /**
5
- * 服务器启动指令
6
- *
7
- * @example 服务器 启动 神话
8
- */
9
- export declare class MCBotStartCommand extends MCBotCommandBase {
10
- readonly bot: MCSManagerBot;
11
- command: string;
12
- constructor(bot: MCSManagerBot);
13
- handle({ session }: Argv, args: string[]): Promise<string>;
14
- }
@@ -1,53 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCBotStartCommand = void 0;
4
- const lodash_1 = require("lodash");
5
- const constants_1 = require("../constants");
6
- const base_1 = require("./base");
7
- const tempSelections = new Map();
8
- /**
9
- * 服务器启动指令
10
- *
11
- * @example 服务器 启动 神话
12
- */
13
- class MCBotStartCommand extends base_1.MCBotCommandBase {
14
- constructor(bot) {
15
- super(bot);
16
- this.bot = bot;
17
- this.command = '服务器.启动 <name...>';
18
- this.initialize();
19
- }
20
- async handle({ session }, args) {
21
- let name = (0, lodash_1.isString)(args) ? args : args.join(' ');
22
- let selectIndex = -1;
23
- const userId = Number(session.event.user.id);
24
- // 溯源前搜索项
25
- if (tempSelections.has(userId) && !isNaN(Number(name))) {
26
- selectIndex = Number(name) - 1;
27
- name = tempSelections.get(userId);
28
- }
29
- tempSelections.delete(userId);
30
- const nameInstances = await this.bot.panel.searchInstanceByName(name);
31
- if (nameInstances.length === 0) {
32
- return `未找到名称包含 "${name}" 的服务器实例`;
33
- }
34
- if (nameInstances.length > 1 && selectIndex === -1) {
35
- tempSelections.set(userId, name);
36
- return `请输入序号以选择:\n\n${nameInstances
37
- .map((item, index) => `${index + 1}. [${constants_1.RemoteInstanceStatusName[item.instance.cfg.status]}] ${item.instance.cfg.config.nickname}`)
38
- .join('\n')}\n ==== 例如发送: (服务器 启动 1) ====`;
39
- }
40
- const targetInstance = selectIndex !== -1 ? nameInstances[selectIndex] : nameInstances[0];
41
- if (!targetInstance || !targetInstance.instance) {
42
- return `未找到名称包含 "${name}" 的服务器实例`;
43
- }
44
- const { cfg } = targetInstance.instance;
45
- if ((0, lodash_1.isEqual)(cfg.status, constants_1.RemoteInstanceStatusEnum.STOPPED)) {
46
- await targetInstance.instance.startInstance();
47
- this.bot.panel.handleRemoteServices();
48
- return `已向服务器实例 "${cfg.config.nickname}" 发送启动操作`;
49
- }
50
- return `服务器实例 "${cfg.config.nickname}" 当前状态为 ${cfg.status},无法执行启动操作`;
51
- }
52
- }
53
- exports.MCBotStartCommand = MCBotStartCommand;
@@ -1,15 +0,0 @@
1
- import { Argv } from 'koishi';
2
- import { MCSManagerBot } from '../bot';
3
- import { MCBotCommandBase, MCBotCommandRole } from './base';
4
- /**
5
- * 服务器启动指令
6
- *
7
- * @example 服务器 启动 神话
8
- */
9
- export declare class MCBotStartCommand extends MCBotCommandBase {
10
- readonly bot: MCSManagerBot;
11
- command: string[];
12
- roles: MCBotCommandRole[];
13
- constructor(bot: MCSManagerBot);
14
- handle({ session }: Argv, args: string[]): Promise<string>;
15
- }
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCBotStartCommand = void 0;
4
- const lodash_1 = require("lodash");
5
- const constants_1 = require("../constants");
6
- const base_1 = require("./base");
7
- const tempSelections = new Map();
8
- /**
9
- * 服务器启动指令
10
- *
11
- * @example 服务器 启动 神话
12
- */
13
- class MCBotStartCommand extends base_1.MCBotCommandBase {
14
- constructor(bot) {
15
- super(bot);
16
- this.bot = bot;
17
- this.command = ['服务器.启动 <name...>', 'MC.启动 <name...>'];
18
- this.roles = [base_1.MCBotCommandRole.Admin, base_1.MCBotCommandRole.Owner];
19
- this.initialize();
20
- }
21
- async handle({ session }, args) {
22
- let name = (0, lodash_1.isString)(args) ? args : args.join(' ');
23
- let selectIndex = -1;
24
- const userId = Number(session.event.user.id);
25
- // 溯源前搜索项
26
- if (tempSelections.has(userId) && !isNaN(Number(name))) {
27
- selectIndex = Number(name) - 1;
28
- name = tempSelections.get(userId);
29
- }
30
- tempSelections.delete(userId);
31
- const nameInstances = await this.bot.panel.searchInstanceByName(name);
32
- if (nameInstances.length === 0) {
33
- return `未找到名称包含 "${name}" 的服务器`;
34
- }
35
- if (nameInstances.length > 1 && selectIndex === -1) {
36
- tempSelections.set(userId, name);
37
- return `请输入序号以选择:\n\n${nameInstances
38
- .map((item, index) => `${index + 1}. [${constants_1.RemoteInstanceStatusName[item.instance.cfg.status]}] ${item.instance.cfg.config.nickname}`)
39
- .join('\n')}\n ==== 例如发送: (服务器 启动 1) ====`;
40
- }
41
- const targetInstance = selectIndex !== -1 ? nameInstances[selectIndex] : nameInstances[0];
42
- if (!targetInstance || !targetInstance.instance) {
43
- return `未找到名称包含 "${name}" 的服务器`;
44
- }
45
- const { cfg } = targetInstance.instance;
46
- if ((0, lodash_1.isEqual)(cfg.status, constants_1.RemoteInstanceStatusEnum.STOPPED)) {
47
- await targetInstance.instance.startInstance();
48
- this.bot.panel.handleRemoteServices();
49
- return `已向服务器实例 "${cfg.config.nickname}" 发送启动操作`;
50
- }
51
- return `服务器实例 "${cfg.config.nickname}" 当前状态为 ${cfg.status},无法执行启动操作`;
52
- }
53
- }
54
- exports.MCBotStartCommand = MCBotStartCommand;
@@ -1,15 +0,0 @@
1
- import { Argv } from 'koishi';
2
- import { MCSManagerBot } from '../bot';
3
- import { MCBotCommandBase, MCBotCommandRole } from './base';
4
- /**
5
- * 服务器关闭指令
6
- *
7
- * @example 服务器 关闭 神话
8
- */
9
- export declare class MCBotStopCommand extends MCBotCommandBase {
10
- readonly bot: MCSManagerBot;
11
- command: string[];
12
- roles: MCBotCommandRole[];
13
- constructor(bot: MCSManagerBot);
14
- handle({ session }: Argv, args: string[]): Promise<string>;
15
- }
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MCBotStopCommand = void 0;
4
- const lodash_1 = require("lodash");
5
- const constants_1 = require("../constants");
6
- const base_1 = require("./base");
7
- const tempSelections = new Map();
8
- /**
9
- * 服务器关闭指令
10
- *
11
- * @example 服务器 关闭 神话
12
- */
13
- class MCBotStopCommand extends base_1.MCBotCommandBase {
14
- constructor(bot) {
15
- super(bot);
16
- this.bot = bot;
17
- this.command = ['服务器.关闭 <name...>', 'MC.关闭 <name...>'];
18
- this.roles = [base_1.MCBotCommandRole.Admin, base_1.MCBotCommandRole.Owner];
19
- this.initialize();
20
- }
21
- async handle({ session }, args) {
22
- let name = (0, lodash_1.isString)(args) ? args : args.join(' ');
23
- let selectIndex = -1;
24
- const userId = Number(session.event.user.id);
25
- // 溯源前搜索项
26
- if (tempSelections.has(userId) && !isNaN(Number(name))) {
27
- selectIndex = Number(name) - 1;
28
- name = tempSelections.get(userId);
29
- }
30
- tempSelections.delete(userId);
31
- const nameInstances = await this.bot.panel.searchInstanceByName(name);
32
- if (nameInstances.length === 0) {
33
- return `未找到名称包含 "${name}" 的服务器`;
34
- }
35
- if (nameInstances.length > 1 && selectIndex === -1) {
36
- tempSelections.set(userId, name);
37
- return `请输入序号以选择:\n\n${nameInstances
38
- .map((item, index) => `${index + 1}. [${constants_1.RemoteInstanceStatusName[item.instance.cfg.status]}] ${item.instance.cfg.config.nickname}`)
39
- .join('\n')}\n ==== 例如发送: (服务器 关闭 1) ====`;
40
- }
41
- const targetInstance = selectIndex !== -1 ? nameInstances[selectIndex] : nameInstances[0];
42
- if (!targetInstance || !targetInstance.instance) {
43
- return `未找到名称包含 "${name}" 的服务器`;
44
- }
45
- const { cfg } = targetInstance.instance;
46
- if ((0, lodash_1.isEqual)(cfg.status, constants_1.RemoteInstanceStatusEnum.RUNNING)) {
47
- await targetInstance.instance.stopInstance();
48
- this.bot.panel.handleRemoteServices();
49
- return `已向服务器实例 "${cfg.config.nickname}" 发送关闭操作`;
50
- }
51
- return `服务器实例 "${cfg.config.nickname}" 当前状态为 ${cfg.status},无法执行关闭操作`;
52
- }
53
- }
54
- exports.MCBotStopCommand = MCBotStopCommand;
@@ -1,47 +0,0 @@
1
- import { Context } from 'koishi';
2
- /**
3
- * 文件下载工具
4
- */
5
- export declare class FileDownloader {
6
- private ctx;
7
- constructor(ctx: Context);
8
- /**
9
- * 从消息内容中提取文件元素
10
- * @param content 消息内容
11
- * @returns 文件元素数组
12
- */
13
- extractFileElements(content: string): {
14
- src: string;
15
- fileId: string;
16
- fileSize?: number;
17
- fileName?: string;
18
- }[];
19
- /**
20
- * 下载文件到本地
21
- * @param fileId 文件ID
22
- * @param fileName 文件名
23
- * @param downloadDir 下载目录
24
- * @param bot 机器人实例(可选,如果平台支持直接获取文件URL)
25
- * @returns 下载的文件路径
26
- */
27
- downloadFile(fileId: string, fileName: string, downloadDir?: string, bot?: any): Promise<string | null>;
28
- /**
29
- * 从URL下载文件
30
- * @param url 文件URL
31
- * @param filePath 保存路径
32
- * @returns 文件路径或null
33
- */
34
- private downloadFromUrl;
35
- /**
36
- * 根据文件ID构造可能的文件URL
37
- * @param fileId 文件ID
38
- * @returns 可能的URL数组
39
- */
40
- private constructPossibleFileUrls;
41
- /**
42
- * 格式化文件大小
43
- * @param bytes 字节数
44
- * @returns 格式化的文件大小
45
- */
46
- formatFileSize(bytes: number): string;
47
- }
@@ -1,142 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FileDownloader = void 0;
4
- const fs_1 = require("fs");
5
- const koishi_1 = require("koishi");
6
- const path_1 = require("path");
7
- const promises_1 = require("stream/promises");
8
- /**
9
- * 文件下载工具
10
- */
11
- class FileDownloader {
12
- constructor(ctx) {
13
- this.ctx = ctx;
14
- }
15
- /**
16
- * 从消息内容中提取文件元素
17
- * @param content 消息内容
18
- * @returns 文件元素数组
19
- */
20
- extractFileElements(content) {
21
- const fileElements = koishi_1.h.select(content, 'file');
22
- return fileElements.map(element => ({
23
- src: element.attrs?.src || '',
24
- fileId: element.attrs?.['file-id'] || '',
25
- fileSize: element.attrs?.['file-size']
26
- ? parseInt(element.attrs['file-size'])
27
- : undefined,
28
- fileName: element.attrs?.file || element.attrs?.src || '',
29
- }));
30
- }
31
- /**
32
- * 下载文件到本地
33
- * @param fileId 文件ID
34
- * @param fileName 文件名
35
- * @param downloadDir 下载目录
36
- * @param bot 机器人实例(可选,如果平台支持直接获取文件URL)
37
- * @returns 下载的文件路径
38
- */
39
- async downloadFile(fileId, fileName, downloadDir = './downloads', bot) {
40
- try {
41
- // 确保下载目录存在
42
- if (!(0, fs_1.existsSync)(downloadDir)) {
43
- (0, fs_1.mkdirSync)(downloadDir, { recursive: true });
44
- }
45
- const filePath = (0, path_1.join)(downloadDir, fileName);
46
- // 方法1: 尝试通过bot获取文件URL(如果平台支持)
47
- if (bot && typeof bot.getFileUrl === 'function') {
48
- try {
49
- const fileUrl = await bot.getFileUrl(fileId);
50
- return await this.downloadFromUrl(fileUrl, filePath);
51
- }
52
- catch (error) {
53
- console.warn('通过bot.getFileUrl下载失败,尝试其他方式:', error.message);
54
- }
55
- }
56
- // 方法2: 尝试通过HTTP直接访问文件ID
57
- if (fileId.startsWith('http://') || fileId.startsWith('https://')) {
58
- return await this.downloadFromUrl(fileId, filePath);
59
- }
60
- // 方法3: 构造可能的文件URL(需要根据具体平台调整)
61
- const possibleUrls = this.constructPossibleFileUrls(fileId);
62
- for (const url of possibleUrls) {
63
- try {
64
- const result = await this.downloadFromUrl(url, filePath);
65
- if (result) {
66
- return result;
67
- }
68
- }
69
- catch (error) {
70
- continue; // 尝试下一个URL
71
- }
72
- }
73
- throw new Error('无法下载文件:所有下载方式都失败了');
74
- }
75
- catch (error) {
76
- console.error('文件下载失败:', error);
77
- return null;
78
- }
79
- }
80
- /**
81
- * 从URL下载文件
82
- * @param url 文件URL
83
- * @param filePath 保存路径
84
- * @returns 文件路径或null
85
- */
86
- async downloadFromUrl(url, filePath) {
87
- try {
88
- const response = await this.ctx.http.get(url, {
89
- responseType: 'stream',
90
- timeout: 60000, // 60秒超时
91
- });
92
- // 确保目录存在
93
- const dir = (0, path_1.dirname)(filePath);
94
- if (!(0, fs_1.existsSync)(dir)) {
95
- (0, fs_1.mkdirSync)(dir, { recursive: true });
96
- }
97
- const writeStream = (0, fs_1.createWriteStream)(filePath);
98
- await (0, promises_1.pipeline)(response, writeStream);
99
- console.log(`文件下载成功: ${filePath}`);
100
- return filePath;
101
- }
102
- catch (error) {
103
- console.error(`从 ${url} 下载文件失败:`, error);
104
- throw error;
105
- }
106
- }
107
- /**
108
- * 根据文件ID构造可能的文件URL
109
- * @param fileId 文件ID
110
- * @returns 可能的URL数组
111
- */
112
- constructPossibleFileUrls(fileId) {
113
- const urls = [];
114
- // 如果fileId就是完整URL
115
- if (fileId.startsWith('http')) {
116
- urls.push(fileId);
117
- }
118
- // QQ群文件的常见URL格式(需要根据实际情况调整)
119
- if (fileId.startsWith('/')) {
120
- // 可能的QQ文件服务器地址
121
- urls.push(`https://groupfiles.qq.com${fileId}`);
122
- urls.push(`https://grouptalk.c2c.qq.com${fileId}`);
123
- }
124
- // 其他平台的文件URL格式可以在这里添加
125
- return urls;
126
- }
127
- /**
128
- * 格式化文件大小
129
- * @param bytes 字节数
130
- * @returns 格式化的文件大小
131
- */
132
- formatFileSize(bytes) {
133
- if (bytes === 0) {
134
- return '0 B';
135
- }
136
- const k = 1024;
137
- const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
138
- const i = Math.floor(Math.log(bytes) / Math.log(k));
139
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
140
- }
141
- }
142
- exports.FileDownloader = FileDownloader;
@@ -1,12 +0,0 @@
1
- import { Session } from 'koishi';
2
- /**
3
- * Koishi 文件处理示例
4
- */
5
- export declare function getFileFromSession(session: Session): {
6
- src: any;
7
- fileId: any;
8
- fileName: any;
9
- fileSize: any;
10
- };
11
- export declare function downloadFileFromSession(session: Session, fileId: string): Promise<string>;
12
- export declare function processFileMessage(session: Session): Promise<string>;
@@ -1,73 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFileFromSession = getFileFromSession;
4
- exports.downloadFileFromSession = downloadFileFromSession;
5
- exports.processFileMessage = processFileMessage;
6
- const koishi_1 = require("koishi");
7
- /**
8
- * Koishi 文件处理示例
9
- */
10
- // 示例1: 直接从 session 中获取文件元素
11
- function getFileFromSession(session) {
12
- // 方法1: 使用 h.select 选择文件元素
13
- const fileElements = koishi_1.h.select(session.elements, 'file');
14
- for (const element of fileElements) {
15
- const fileInfo = {
16
- src: element.attrs?.src,
17
- fileId: element.attrs?.['file-id'],
18
- fileName: element.attrs?.file,
19
- fileSize: element.attrs?.['file-size'],
20
- };
21
- console.log('检测到文件:', fileInfo);
22
- return fileInfo;
23
- }
24
- return null;
25
- }
26
- // 示例2: 通过平台API下载文件
27
- async function downloadFileFromSession(session, fileId) {
28
- try {
29
- // 不同平台的文件下载方法可能不同
30
- // QQ平台示例
31
- if (session.platform === 'onebot') {
32
- // OneBot协议中可能需要调用get_group_file_url等API
33
- // const fileUrl = await session.bot.internal.getGroupFileUrl(session.guildId, fileId);
34
- // return fileUrl;
35
- }
36
- // Discord平台示例
37
- if (session.platform === 'discord') {
38
- // Discord文件通常直接有URL
39
- return fileId; // 在Discord中,file-id通常就是直接的URL
40
- }
41
- // 通用方法:尝试直接访问fileId作为URL
42
- if (fileId.startsWith('http')) {
43
- return fileId;
44
- }
45
- throw new Error(`平台 ${session.platform} 不支持文件下载或文件ID格式不正确`);
46
- }
47
- catch (error) {
48
- console.error('获取文件URL失败:', error);
49
- throw error;
50
- }
51
- }
52
- // 示例3: 完整的文件处理流程
53
- async function processFileMessage(session) {
54
- const fileInfo = getFileFromSession(session);
55
- if (!fileInfo) {
56
- return '未检测到文件';
57
- }
58
- try {
59
- const fileUrl = await downloadFileFromSession(session, fileInfo.fileId);
60
- // 使用 session.bot.ctx.http 下载文件
61
- const response = await session.bot.ctx.http.get(fileUrl, {
62
- responseType: 'arraybuffer',
63
- });
64
- // 这里你可以:
65
- // 1. 保存文件到本地
66
- // 2. 处理文件内容
67
- // 3. 上传到其他服务
68
- return `文件 "${fileInfo.fileName}" 下载成功,大小:${response.byteLength} 字节`;
69
- }
70
- catch (error) {
71
- return `文件下载失败:${error.message}`;
72
- }
73
- }