koishi-plugin-cfmrmod 1.0.9 → 1.1.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/dist/notify.js +50 -5
- package/package.json +1 -1
package/dist/notify.js
CHANGED
|
@@ -11,6 +11,7 @@ const cfmr_1 = require("./cfmr");
|
|
|
11
11
|
const fetch = require('node-fetch');
|
|
12
12
|
const MR_BASE = 'https://api.modrinth.com/v2';
|
|
13
13
|
const CF_MIRROR_BASE = 'https://api.curse.tools/v1/cf';
|
|
14
|
+
const CF_OFFICIAL_BASE = 'https://api.curseforge.com/v1';
|
|
14
15
|
function normalizePlatform(platform) {
|
|
15
16
|
if (platform === 'mr' || platform === 'cf')
|
|
16
17
|
return platform;
|
|
@@ -388,9 +389,53 @@ function apply(ctx, config, options) {
|
|
|
388
389
|
};
|
|
389
390
|
}
|
|
390
391
|
async function getLatestCurseForge(projectId, timeout) {
|
|
391
|
-
var _a;
|
|
392
|
-
|
|
393
|
-
const
|
|
392
|
+
var _a, _b, _c;
|
|
393
|
+
// 优先使用官方 API(如果配置了 API Key),否则回退到镜像
|
|
394
|
+
const apiKey = (_a = options === null || options === void 0 ? void 0 : options.cfmr) === null || _a === void 0 ? void 0 : _a.curseforgeApiKey;
|
|
395
|
+
if (apiKey && String(apiKey).trim()) {
|
|
396
|
+
// 使用官方 API
|
|
397
|
+
try {
|
|
398
|
+
const controller = new AbortController();
|
|
399
|
+
const id = setTimeout(() => controller.abort(), timeout);
|
|
400
|
+
try {
|
|
401
|
+
// 官方 API 可以使用分页参数
|
|
402
|
+
const res = await fetch(`${CF_OFFICIAL_BASE}/mods/${projectId}/files?index=0&pageSize=1`, {
|
|
403
|
+
headers: {
|
|
404
|
+
'Accept': 'application/json',
|
|
405
|
+
'x-api-key': String(apiKey).trim(),
|
|
406
|
+
},
|
|
407
|
+
signal: controller.signal,
|
|
408
|
+
});
|
|
409
|
+
if (!res.ok)
|
|
410
|
+
throw new Error(`HTTP ${res.status}`);
|
|
411
|
+
const files = await res.json();
|
|
412
|
+
const latest = (_b = files === null || files === void 0 ? void 0 : files.data) === null || _b === void 0 ? void 0 : _b[0];
|
|
413
|
+
if (!latest)
|
|
414
|
+
return null;
|
|
415
|
+
return {
|
|
416
|
+
versionId: String(latest.id),
|
|
417
|
+
version: latest.displayName || latest.fileName || String(latest.id),
|
|
418
|
+
changelog: latest.changelog || '',
|
|
419
|
+
downloads: latest.downloadCount,
|
|
420
|
+
datePublished: latest.fileDate || null,
|
|
421
|
+
releaseType: latest.releaseType,
|
|
422
|
+
loaders: Array.isArray(latest.gameVersions) ? latest.gameVersions.filter((v) => /forge|fabric|quilt|neoforge/i.test(String(v))) : [],
|
|
423
|
+
gameVersions: Array.isArray(latest.gameVersions) ? latest.gameVersions.filter((v) => /\d/.test(String(v))) : [],
|
|
424
|
+
fileName: latest.fileName || '',
|
|
425
|
+
fileSize: latest.fileLength || 0,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
finally {
|
|
429
|
+
clearTimeout(id);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch (e) {
|
|
433
|
+
logger.warn(`[getLatestCurseForge] 官方 API 请求失败,回退到镜像: ${e.message}`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// 回退到镜像 API - 不使用分页参数,避免缓存问题
|
|
437
|
+
const files = await fetchJson(`${CF_MIRROR_BASE}/mods/${projectId}/files`, timeout);
|
|
438
|
+
const latest = (_c = files === null || files === void 0 ? void 0 : files.data) === null || _c === void 0 ? void 0 : _c[0];
|
|
394
439
|
if (!latest)
|
|
395
440
|
return null;
|
|
396
441
|
return {
|
|
@@ -422,7 +467,6 @@ function apply(ctx, config, options) {
|
|
|
422
467
|
const src = await toImageSrc(buf);
|
|
423
468
|
await sendToChannel(channelId, koishi_1.h.image(src));
|
|
424
469
|
}
|
|
425
|
-
// 仅发送卡片,不发送文字
|
|
426
470
|
}
|
|
427
471
|
catch (e) {
|
|
428
472
|
logger.warn(`发送通知失败(${platform}:${projectId}): ${e.message}`);
|
|
@@ -439,7 +483,8 @@ function apply(ctx, config, options) {
|
|
|
439
483
|
try {
|
|
440
484
|
const key = `${sub.channelId}|${sub.platform}|${sub.projectId}`;
|
|
441
485
|
const lastCheck = lastCheckMap.get(key) || 0;
|
|
442
|
-
|
|
486
|
+
const elapsed = Date.now() - lastCheck;
|
|
487
|
+
if (!force && elapsed < sub.interval) {
|
|
443
488
|
stats.skipped += 1;
|
|
444
489
|
continue;
|
|
445
490
|
}
|