koishi-plugin-gl-bot 0.0.9 → 0.0.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/lib/constants/env.d.ts +0 -0
- package/lib/constants/env.js +0 -0
- package/lib/gl/index.d.ts +9 -0
- package/lib/gl/index.js +9 -2
- package/lib/gl/index.type.d.ts +0 -0
- package/lib/gl/index.type.js +0 -0
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -2
- package/lib/mcsManager/api.d.ts +18 -3
- package/lib/mcsManager/api.js +157 -7
- package/lib/mcsManager/bot.d.ts +5 -3
- package/lib/mcsManager/bot.js +18 -10
- package/lib/mcsManager/commands/ark/create.d.ts +15 -0
- package/lib/mcsManager/commands/ark/create.js +66 -0
- package/lib/mcsManager/commands/ark/list.d.ts +14 -0
- package/lib/mcsManager/commands/ark/list.js +35 -0
- package/lib/mcsManager/commands/ark/restart.d.ts +15 -0
- package/lib/mcsManager/commands/ark/restart.js +62 -0
- package/lib/mcsManager/commands/ark/start.d.ts +15 -0
- package/lib/mcsManager/commands/ark/start.js +54 -0
- package/lib/mcsManager/commands/ark/stop.d.ts +15 -0
- package/lib/mcsManager/commands/ark/stop.js +54 -0
- package/lib/mcsManager/commands/base.d.ts +20 -1
- package/lib/mcsManager/commands/base.js +41 -3
- package/lib/mcsManager/commands/create.d.ts +16 -0
- package/lib/mcsManager/commands/create.js +135 -0
- package/lib/mcsManager/commands/index.d.ts +10 -7
- package/lib/mcsManager/commands/index.js +22 -11
- package/lib/mcsManager/commands/list copy.d.ts +13 -0
- package/lib/mcsManager/commands/list copy.js +34 -0
- package/lib/mcsManager/commands/list.d.ts +14 -0
- package/lib/mcsManager/commands/list.js +35 -0
- package/lib/mcsManager/commands/mc/create.d.ts +15 -0
- package/lib/mcsManager/commands/mc/create.js +79 -0
- package/lib/mcsManager/commands/mc/list.d.ts +14 -0
- package/lib/mcsManager/commands/mc/list.js +39 -0
- package/lib/mcsManager/commands/mc/online.d.ts +24 -0
- package/lib/mcsManager/commands/mc/online.js +112 -0
- package/lib/mcsManager/commands/mc/restart copy.d.ts +15 -0
- package/lib/mcsManager/commands/mc/restart copy.js +62 -0
- package/lib/mcsManager/commands/mc/restart.d.ts +15 -0
- package/lib/mcsManager/commands/mc/restart.js +62 -0
- package/lib/mcsManager/commands/mc/start.d.ts +15 -0
- package/lib/mcsManager/commands/mc/start.js +54 -0
- package/lib/mcsManager/commands/mc/stop.d.ts +15 -0
- package/lib/mcsManager/commands/mc/stop.js +54 -0
- package/lib/mcsManager/commands/mc copy/create.d.ts +16 -0
- package/lib/mcsManager/commands/mc copy/create.js +135 -0
- package/lib/mcsManager/commands/mc copy/list.d.ts +14 -0
- package/lib/mcsManager/commands/mc copy/list.js +35 -0
- package/lib/mcsManager/commands/mc copy/restart.d.ts +15 -0
- package/lib/mcsManager/commands/mc copy/restart.js +62 -0
- package/lib/mcsManager/commands/mc copy/start.d.ts +15 -0
- package/lib/mcsManager/commands/mc copy/start.js +54 -0
- package/lib/mcsManager/commands/mc copy/stop.d.ts +15 -0
- package/lib/mcsManager/commands/mc copy/stop.js +54 -0
- package/lib/mcsManager/commands/restart.d.ts +15 -0
- package/lib/mcsManager/commands/restart.js +62 -0
- package/lib/mcsManager/commands/start copy.d.ts +14 -0
- package/lib/mcsManager/commands/{reset.js → start copy.js } +23 -15
- package/lib/mcsManager/commands/start.d.ts +15 -0
- package/lib/mcsManager/commands/start.js +54 -0
- package/lib/mcsManager/commands/stop.d.ts +15 -0
- package/lib/mcsManager/commands/stop.js +54 -0
- package/lib/mcsManager/constants.d.ts +4 -0
- package/lib/mcsManager/constants.js +4 -0
- package/lib/mcsManager/index.d.ts +4 -3
- package/lib/mcsManager/index.js +5 -2
- package/lib/mcsManager/instance.d.ts +3 -1
- package/lib/mcsManager/instance.js +8 -2
- package/lib/mcsManager/json/createInstanceUpload.json +49 -0
- package/lib/mcsManager/panel.d.ts +1 -1
- package/lib/mcsManager/panel.js +7 -5
- package/lib/mcsManager/schedules/index.d.ts +8 -0
- package/lib/mcsManager/schedules/index.js +41 -0
- package/lib/mcsManager/schedules/mc.schedule.d.ts +11 -0
- package/lib/mcsManager/schedules/mc.schedule.js +15 -0
- package/lib/mcsManager/type.d.ts +102 -0
- package/lib/mcsManager/ws.js +6 -6
- package/lib/napCat/api.d.ts +21 -0
- package/lib/napCat/api.js +43 -0
- package/lib/napCat/config.d.ts +10 -0
- package/lib/napCat/config.js +16 -0
- package/lib/napCat/index.d.ts +16 -0
- package/lib/napCat/index.js +15 -0
- package/lib/queQiao/index.d.ts +1 -0
- package/lib/queQiao/index.js +70 -3
- package/lib/queQiao/locale/en-US.yml +9 -9
- package/lib/queQiao/locale/zh-CN.json +1 -1
- package/lib/queQiao/locale/zh-CN.yml +9 -9
- package/lib/utils/file.download.d.ts +47 -0
- package/lib/utils/file.download.js +142 -0
- package/lib/utils/file.examples.d.ts +12 -0
- package/lib/utils/file.examples.js +73 -0
- package/lib/utils/index.d.ts +7 -0
- package/lib/utils/index.js +58 -0
- package/lib/utils/napcat.file.d.ts +63 -0
- package/lib/utils/napcat.file.js +133 -0
- package/package.json +4 -3
- package/lib/mcsManager/commands/reset.d.ts +0 -12
|
@@ -0,0 +1,142 @@
|
|
|
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;
|
|
@@ -0,0 +1,12 @@
|
|
|
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>;
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
}
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -14,4 +14,62 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.formatDuration = formatDuration;
|
|
18
|
+
exports.formatOnlineTime = formatOnlineTime;
|
|
17
19
|
__exportStar(require("./game.mc"), exports);
|
|
20
|
+
/**
|
|
21
|
+
* 格式化时间差为易读格式
|
|
22
|
+
* @param milliseconds 时间差(毫秒)
|
|
23
|
+
* @returns 格式化后的时间字符串
|
|
24
|
+
*/
|
|
25
|
+
function formatDuration(milliseconds) {
|
|
26
|
+
if (milliseconds <= 0) {
|
|
27
|
+
return '0分钟';
|
|
28
|
+
}
|
|
29
|
+
const seconds = Math.floor(milliseconds / 1000);
|
|
30
|
+
const minutes = Math.floor(seconds / 60);
|
|
31
|
+
const hours = Math.floor(minutes / 60);
|
|
32
|
+
const days = Math.floor(hours / 24);
|
|
33
|
+
const months = Math.floor(days / 30);
|
|
34
|
+
const years = Math.floor(days / 365);
|
|
35
|
+
if (years > 0) {
|
|
36
|
+
const remainingMonths = Math.floor((days % 365) / 30);
|
|
37
|
+
return remainingMonths > 0
|
|
38
|
+
? `${years}年${remainingMonths}个月`
|
|
39
|
+
: `${years}年`;
|
|
40
|
+
}
|
|
41
|
+
if (months > 0) {
|
|
42
|
+
const remainingDays = days % 30;
|
|
43
|
+
return remainingDays > 0
|
|
44
|
+
? `${months}个月${remainingDays}天`
|
|
45
|
+
: `${months}月`;
|
|
46
|
+
}
|
|
47
|
+
if (days > 0) {
|
|
48
|
+
const remainingHours = hours % 24;
|
|
49
|
+
return remainingHours > 0 ? `${days}天${remainingHours}小时` : `${days}天`;
|
|
50
|
+
}
|
|
51
|
+
if (hours > 0) {
|
|
52
|
+
const remainingMinutes = minutes % 60;
|
|
53
|
+
return remainingMinutes > 0
|
|
54
|
+
? `${hours}小时${remainingMinutes}分钟`
|
|
55
|
+
: `${hours}小时`;
|
|
56
|
+
}
|
|
57
|
+
if (minutes > 0) {
|
|
58
|
+
return `${minutes}分钟`;
|
|
59
|
+
}
|
|
60
|
+
return `${seconds}秒`;
|
|
61
|
+
}
|
|
62
|
+
function formatOnlineTime(seconds) {
|
|
63
|
+
const hours = Math.floor(seconds / 3600);
|
|
64
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
65
|
+
const remainingSeconds = seconds % 60;
|
|
66
|
+
if (hours > 0) {
|
|
67
|
+
return `${hours}小时${minutes}分钟${remainingSeconds}秒`;
|
|
68
|
+
}
|
|
69
|
+
else if (minutes > 0) {
|
|
70
|
+
return `${minutes}分钟${remainingSeconds}秒`;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return `${remainingSeconds}秒`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Session } from 'koishi';
|
|
2
|
+
/**
|
|
3
|
+
* NapCat 群文件下载工具
|
|
4
|
+
* 用于处理 NapCat OneBot 协议的群文件下载
|
|
5
|
+
*/
|
|
6
|
+
export declare class NapCatFileDownloader {
|
|
7
|
+
/**
|
|
8
|
+
* 获取群文件下载URL
|
|
9
|
+
* @param session Koishi Session 对象
|
|
10
|
+
* @param fileId 群文件ID
|
|
11
|
+
* @returns 文件下载URL或null
|
|
12
|
+
*/
|
|
13
|
+
static getGroupFileUrl(session: Session, fileId: string): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* 获取群文件信息
|
|
16
|
+
* @param session Koishi Session 对象
|
|
17
|
+
* @param fileId 群文件ID
|
|
18
|
+
* @returns 文件信息或null
|
|
19
|
+
*/
|
|
20
|
+
static getGroupFileInfo(session: Session, fileId: string): Promise<any | null>;
|
|
21
|
+
/**
|
|
22
|
+
* 下载群文件到内存
|
|
23
|
+
* @param session Koishi Session 对象
|
|
24
|
+
* @param fileId 群文件ID
|
|
25
|
+
* @param fileName 文件名(用于日志)
|
|
26
|
+
* @param ctx Koishi Context(用于HTTP请求)
|
|
27
|
+
* @returns 文件Buffer或null
|
|
28
|
+
*/
|
|
29
|
+
static downloadGroupFile(session: Session, fileId: string, fileName: string, ctx: any): Promise<Buffer | null>;
|
|
30
|
+
/**
|
|
31
|
+
* 保存群文件到本地
|
|
32
|
+
* @param session Koishi Session 对象
|
|
33
|
+
* @param fileId 群文件ID
|
|
34
|
+
* @param fileName 文件名
|
|
35
|
+
* @param savePath 保存路径
|
|
36
|
+
* @param ctx Koishi Context
|
|
37
|
+
* @returns 是否保存成功
|
|
38
|
+
*/
|
|
39
|
+
static saveGroupFile(session: Session, fileId: string, fileName: string, savePath: string, ctx: any): Promise<boolean>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* NapCat OneBot 协议相关的类型定义
|
|
43
|
+
*/
|
|
44
|
+
export interface NapCatFileInfo {
|
|
45
|
+
file_id: string;
|
|
46
|
+
file_name: string;
|
|
47
|
+
file_size: number;
|
|
48
|
+
busid: number;
|
|
49
|
+
upload_time: number;
|
|
50
|
+
dead_time: number;
|
|
51
|
+
modify_time: number;
|
|
52
|
+
download_times: number;
|
|
53
|
+
uploader: number;
|
|
54
|
+
uploader_name: string;
|
|
55
|
+
}
|
|
56
|
+
export interface NapCatFileUrlResponse {
|
|
57
|
+
url?: string;
|
|
58
|
+
file_url?: string;
|
|
59
|
+
data?: {
|
|
60
|
+
url?: string;
|
|
61
|
+
file_url?: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NapCatFileDownloader = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* NapCat 群文件下载工具
|
|
6
|
+
* 用于处理 NapCat OneBot 协议的群文件下载
|
|
7
|
+
*/
|
|
8
|
+
class NapCatFileDownloader {
|
|
9
|
+
/**
|
|
10
|
+
* 获取群文件下载URL
|
|
11
|
+
* @param session Koishi Session 对象
|
|
12
|
+
* @param fileId 群文件ID
|
|
13
|
+
* @returns 文件下载URL或null
|
|
14
|
+
*/
|
|
15
|
+
static async getGroupFileUrl(session, fileId) {
|
|
16
|
+
try {
|
|
17
|
+
// 检查是否为 OneBot 平台且有内部API支持
|
|
18
|
+
if (session.platform !== 'onebot' || !session.bot?.internal) {
|
|
19
|
+
console.warn('当前平台不是 OneBot 或缺少内部API支持');
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
console.log(`尝试通过 NapCat API 获取群文件URL,群号: ${session.channelId}, 文件ID: ${fileId}`);
|
|
23
|
+
// 调用 NapCat 的 get_group_file_url API
|
|
24
|
+
const response = await session.bot.internal.getGroupFileUrl(session.channelId, // 群号
|
|
25
|
+
fileId);
|
|
26
|
+
console.log('NapCat API 响应:', JSON.stringify(response, null, 2));
|
|
27
|
+
// 不同版本的 NapCat 可能返回格式不同
|
|
28
|
+
const fileUrl = response?.url ||
|
|
29
|
+
response?.data?.url ||
|
|
30
|
+
response?.file_url ||
|
|
31
|
+
response?.data?.file_url;
|
|
32
|
+
if (fileUrl) {
|
|
33
|
+
console.log(`成功获取文件URL: ${fileUrl}`);
|
|
34
|
+
return fileUrl;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.warn('API响应中未找到有效的文件URL');
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error('获取群文件URL失败:', error);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 获取群文件信息
|
|
48
|
+
* @param session Koishi Session 对象
|
|
49
|
+
* @param fileId 群文件ID
|
|
50
|
+
* @returns 文件信息或null
|
|
51
|
+
*/
|
|
52
|
+
static async getGroupFileInfo(session, fileId) {
|
|
53
|
+
try {
|
|
54
|
+
if (session.platform !== 'onebot' || !session.bot?.internal) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
// 尝试获取文件信息(如果NapCat支持)
|
|
58
|
+
const response = await session.bot.internal.getGroupFileInfo?.(session.channelId, fileId);
|
|
59
|
+
return response?.data || response || null;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.warn('获取群文件信息失败:', error);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 下载群文件到内存
|
|
68
|
+
* @param session Koishi Session 对象
|
|
69
|
+
* @param fileId 群文件ID
|
|
70
|
+
* @param fileName 文件名(用于日志)
|
|
71
|
+
* @param ctx Koishi Context(用于HTTP请求)
|
|
72
|
+
* @returns 文件Buffer或null
|
|
73
|
+
*/
|
|
74
|
+
static async downloadGroupFile(session, fileId, fileName, ctx) {
|
|
75
|
+
try {
|
|
76
|
+
// 获取文件下载URL
|
|
77
|
+
const fileUrl = await this.getGroupFileUrl(session, fileId);
|
|
78
|
+
if (!fileUrl) {
|
|
79
|
+
console.error(`无法获取文件 ${fileName} 的下载URL`);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
console.log(`开始下载文件: ${fileName}`);
|
|
83
|
+
// 下载文件
|
|
84
|
+
const response = await ctx.http.get(fileUrl, {
|
|
85
|
+
responseType: 'arraybuffer',
|
|
86
|
+
timeout: 60000, // 60秒超时
|
|
87
|
+
headers: {
|
|
88
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
const buffer = Buffer.from(response);
|
|
92
|
+
console.log(`文件下载成功: ${fileName}, 大小: ${buffer.length} 字节`);
|
|
93
|
+
return buffer;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error(`下载文件 ${fileName} 失败:`, error);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 保存群文件到本地
|
|
102
|
+
* @param session Koishi Session 对象
|
|
103
|
+
* @param fileId 群文件ID
|
|
104
|
+
* @param fileName 文件名
|
|
105
|
+
* @param savePath 保存路径
|
|
106
|
+
* @param ctx Koishi Context
|
|
107
|
+
* @returns 是否保存成功
|
|
108
|
+
*/
|
|
109
|
+
static async saveGroupFile(session, fileId, fileName, savePath, ctx) {
|
|
110
|
+
try {
|
|
111
|
+
const buffer = await this.downloadGroupFile(session, fileId, fileName, ctx);
|
|
112
|
+
if (!buffer) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
// 确保目录存在
|
|
116
|
+
const fs = require('fs');
|
|
117
|
+
const path = require('path');
|
|
118
|
+
const dir = path.dirname(savePath);
|
|
119
|
+
if (!fs.existsSync(dir)) {
|
|
120
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
121
|
+
}
|
|
122
|
+
// 保存文件
|
|
123
|
+
fs.writeFileSync(savePath, buffer);
|
|
124
|
+
console.log(`文件保存成功: ${savePath}`);
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(`保存文件失败:`, error);
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.NapCatFileDownloader = NapCatFileDownloader;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-gl-bot",
|
|
3
3
|
"description": "GleamSlime Koishi Rebot Plugins",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"contributors": [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@koishijs/client": "^5.30.11",
|
|
31
|
-
"@types/lodash
|
|
31
|
+
"@types/lodash": "^4.17.21",
|
|
32
32
|
"typescript": "^5.9.3"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"
|
|
44
|
+
"@types/ms": "^2.1.0",
|
|
45
|
+
"lodash": "^4.17.21",
|
|
45
46
|
"rcon-client": "^4.2.5",
|
|
46
47
|
"socket.io-client": "^4.8.2",
|
|
47
48
|
"ws": "^8.18.3"
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Context, Session } from 'koishi';
|
|
2
|
-
import { MCSManagerBot } from '../bot';
|
|
3
|
-
/**
|
|
4
|
-
* 服务器重启指令
|
|
5
|
-
*
|
|
6
|
-
* @example 服务器 重启 神话
|
|
7
|
-
*/
|
|
8
|
-
export declare class MCBotResetCommand {
|
|
9
|
-
private readonly bot;
|
|
10
|
-
constructor(bot: MCSManagerBot);
|
|
11
|
-
handle(session: Session<never, never, Context>, name: string): Promise<string>;
|
|
12
|
-
}
|