koishi-plugin-cfmrmod 1.0.1 → 1.0.2
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/cfmr/index.js +38 -17
- package/dist/index.js +2 -3
- package/dist/mcmod/index.js +38 -7
- package/package.json +6 -3
package/dist/cfmr/index.js
CHANGED
|
@@ -3,11 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Config = exports.name = void 0;
|
|
4
4
|
exports.apply = apply;
|
|
5
5
|
const { Schema, h } = require('koishi');
|
|
6
|
-
// 【修复】这里添加了 Path2D 的引入
|
|
7
|
-
const { createCanvas, loadImage, Path2D, GlobalFonts } = require('@napi-rs/canvas');
|
|
8
6
|
const fetch = require('node-fetch');
|
|
9
7
|
const cheerio = require('cheerio');
|
|
10
8
|
const { marked } = require('marked');
|
|
9
|
+
let createCanvas;
|
|
10
|
+
let loadImage;
|
|
11
|
+
let Path2DRef;
|
|
12
|
+
let registerFont;
|
|
13
|
+
async function toImageSrc(input) {
|
|
14
|
+
const value = (input && typeof input.then === 'function') ? await input : input;
|
|
15
|
+
if (!value)
|
|
16
|
+
return '';
|
|
17
|
+
if (typeof value === 'string')
|
|
18
|
+
return value;
|
|
19
|
+
const buf = Buffer.isBuffer(value) ? value : (value instanceof Uint8Array ? Buffer.from(value) : null);
|
|
20
|
+
if (buf)
|
|
21
|
+
return `data:image/png;base64,${buf.toString('base64')}`;
|
|
22
|
+
return String(value);
|
|
23
|
+
}
|
|
11
24
|
const CF_LOADER_MAP = {
|
|
12
25
|
1: 'Forge',
|
|
13
26
|
2: 'Cauldron',
|
|
@@ -560,6 +573,8 @@ async function drawProjectCard(data) {
|
|
|
560
573
|
// Stats & Tags Row
|
|
561
574
|
// Downloads Icon
|
|
562
575
|
const drawIcon = (path, x, y) => {
|
|
576
|
+
if (!Path2DRef)
|
|
577
|
+
return;
|
|
563
578
|
ctx.save();
|
|
564
579
|
ctx.translate(x, y);
|
|
565
580
|
ctx.scale(0.8, 0.8);
|
|
@@ -567,8 +582,7 @@ async function drawProjectCard(data) {
|
|
|
567
582
|
ctx.lineWidth = 2;
|
|
568
583
|
ctx.lineCap = 'round';
|
|
569
584
|
ctx.lineJoin = 'round';
|
|
570
|
-
|
|
571
|
-
const p = new Path2D(path);
|
|
585
|
+
const p = new Path2DRef(path);
|
|
572
586
|
ctx.stroke(p);
|
|
573
587
|
ctx.restore();
|
|
574
588
|
};
|
|
@@ -1488,18 +1502,25 @@ async function searchCurseForge(query, type, apiKey, timeout, gameId = 432) {
|
|
|
1488
1502
|
function apply(ctx, config) {
|
|
1489
1503
|
var _a, _b;
|
|
1490
1504
|
const logger = ctx.logger('mc-search');
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
if (ok)
|
|
1495
|
-
GLOBAL_FONT_FAMILY = 'KoishiFont';
|
|
1496
|
-
else
|
|
1497
|
-
logger.warn('字体加载失败: registerFromPath 返回 false');
|
|
1498
|
-
}
|
|
1499
|
-
catch (e) {
|
|
1500
|
-
logger.warn('字体加载失败: ' + e.message);
|
|
1501
|
-
}
|
|
1505
|
+
const skia = ctx.skia;
|
|
1506
|
+
if (!(skia === null || skia === void 0 ? void 0 : skia.Canvas) || !(skia === null || skia === void 0 ? void 0 : skia.loadImage)) {
|
|
1507
|
+
throw new Error('缺少 skia 服务,请先启用 @ltxhhz/koishi-plugin-skia-canvas');
|
|
1502
1508
|
}
|
|
1509
|
+
createCanvas = (w, h) => {
|
|
1510
|
+
const c = new skia.Canvas(w || 0, h || 0);
|
|
1511
|
+
if (!c || typeof c.getContext !== 'function') {
|
|
1512
|
+
throw new Error('skia 服务异常:Canvas 无效,请确认使用 @ltxhhz/koishi-plugin-skia-canvas');
|
|
1513
|
+
}
|
|
1514
|
+
return c;
|
|
1515
|
+
};
|
|
1516
|
+
loadImage = skia.loadImage;
|
|
1517
|
+
registerFont = (path, options) => {
|
|
1518
|
+
var _a;
|
|
1519
|
+
if ((_a = skia.FontLibrary) === null || _a === void 0 ? void 0 : _a.use)
|
|
1520
|
+
skia.FontLibrary.use(path, options === null || options === void 0 ? void 0 : options.family);
|
|
1521
|
+
};
|
|
1522
|
+
Path2DRef = skia.Path2D || globalThis.Path2D;
|
|
1523
|
+
// 取消自定义字体配置,使用 skia 默认字体
|
|
1503
1524
|
const states = new Map();
|
|
1504
1525
|
const normalizeMessageIds = (res) => {
|
|
1505
1526
|
if (!res)
|
|
@@ -1564,7 +1585,7 @@ function apply(ctx, config) {
|
|
|
1564
1585
|
maxCanvasHeight: config.maxCanvasHeight || 8000
|
|
1565
1586
|
});
|
|
1566
1587
|
for (const buf of imgBufs) {
|
|
1567
|
-
await session.send(h.image(buf
|
|
1588
|
+
await session.send(h.image(await toImageSrc(buf)));
|
|
1568
1589
|
}
|
|
1569
1590
|
if (config.sendLink)
|
|
1570
1591
|
await session.send(`链接: ${detailData.url}`);
|
|
@@ -1625,7 +1646,7 @@ function apply(ctx, config) {
|
|
|
1625
1646
|
maxCanvasHeight: config.maxCanvasHeight || 8000
|
|
1626
1647
|
});
|
|
1627
1648
|
for (const buf of imgBufs) {
|
|
1628
|
-
await session.send(h.image(buf
|
|
1649
|
+
await session.send(h.image(await toImageSrc(buf)));
|
|
1629
1650
|
}
|
|
1630
1651
|
if (config.sendLink)
|
|
1631
1652
|
await session.send(`链接: ${detailData.url}`);
|
package/dist/index.js
CHANGED
|
@@ -33,19 +33,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.Config = exports.name = void 0;
|
|
36
|
+
exports.Config = exports.inject = exports.name = void 0;
|
|
37
37
|
exports.apply = apply;
|
|
38
38
|
const koishi_1 = require("koishi");
|
|
39
39
|
const cfmr = __importStar(require("./plugins/cfmr"));
|
|
40
40
|
const mcmod = __importStar(require("./plugins/mcmod"));
|
|
41
41
|
exports.name = 'minecraft-search';
|
|
42
|
+
exports.inject = ['skia'];
|
|
42
43
|
exports.Config = koishi_1.Schema.object({
|
|
43
44
|
prefixes: koishi_1.Schema.object({
|
|
44
45
|
cf: koishi_1.Schema.string().default('cf'),
|
|
45
46
|
mr: koishi_1.Schema.string().default('mr'),
|
|
46
47
|
cnmc: koishi_1.Schema.string().default('cnmc'),
|
|
47
48
|
}).description('指令前缀设置'),
|
|
48
|
-
fontPath: koishi_1.Schema.string().role('path').description('中文字体路径 (建议使用含中文和Emoji的字体)'),
|
|
49
49
|
timeouts: koishi_1.Schema.number().default(60000).description('搜索会话超时时间(ms)'),
|
|
50
50
|
debug: koishi_1.Schema.boolean().default(false).description('开启调试日志'),
|
|
51
51
|
cfmr: cfmr.Config.description('CurseForge/Modrinth 搜索与图片卡片'),
|
|
@@ -55,7 +55,6 @@ function apply(ctx, config) {
|
|
|
55
55
|
const prefixes = (config === null || config === void 0 ? void 0 : config.prefixes) || {};
|
|
56
56
|
const shared = {
|
|
57
57
|
prefixes,
|
|
58
|
-
fontPath: config === null || config === void 0 ? void 0 : config.fontPath,
|
|
59
58
|
timeouts: config === null || config === void 0 ? void 0 : config.timeouts,
|
|
60
59
|
debug: config === null || config === void 0 ? void 0 : config.debug,
|
|
61
60
|
};
|
package/dist/mcmod/index.js
CHANGED
|
@@ -6,8 +6,21 @@ const fetch = require('node-fetch');
|
|
|
6
6
|
const cheerio = require('cheerio');
|
|
7
7
|
const fs = require('fs');
|
|
8
8
|
const path = require('path');
|
|
9
|
-
const { createCanvas, loadImage, registerFont, GlobalFonts } = require('@napi-rs/canvas');
|
|
10
9
|
const { h, Schema } = require('koishi');
|
|
10
|
+
let createCanvas;
|
|
11
|
+
let loadImage;
|
|
12
|
+
let registerFont;
|
|
13
|
+
async function toImageSrc(input) {
|
|
14
|
+
const value = (input && typeof input.then === 'function') ? await input : input;
|
|
15
|
+
if (!value)
|
|
16
|
+
return '';
|
|
17
|
+
if (typeof value === 'string')
|
|
18
|
+
return value;
|
|
19
|
+
const buf = Buffer.isBuffer(value) ? value : (value instanceof Uint8Array ? Buffer.from(value) : null);
|
|
20
|
+
if (buf)
|
|
21
|
+
return `data:image/png;base64,${buf.toString('base64')}`;
|
|
22
|
+
return String(value);
|
|
23
|
+
}
|
|
11
24
|
// Cookie 管理器
|
|
12
25
|
let cookieManager = null;
|
|
13
26
|
try {
|
|
@@ -139,13 +152,14 @@ function wrapText(ctx, text, x, y, maxWidth, lineHeight, maxLines = 1000, draw =
|
|
|
139
152
|
return currentY + lineHeight;
|
|
140
153
|
}
|
|
141
154
|
// ================= 字体注册 =================
|
|
142
|
-
function initFont(preferredPath, logger) {
|
|
155
|
+
function initFont(preferredPath, logger, registerFontFn) {
|
|
143
156
|
const fontName = 'MCModFont';
|
|
144
157
|
const tryRegister = (filePath, source) => {
|
|
145
158
|
if (!fs.existsSync(filePath))
|
|
146
159
|
return false;
|
|
147
160
|
try {
|
|
148
|
-
if (
|
|
161
|
+
if (registerFontFn) {
|
|
162
|
+
registerFontFn(filePath, { family: fontName });
|
|
149
163
|
GLOBAL_FONT_FAMILY = fontName;
|
|
150
164
|
logger.info(`[Font] 成功加载${source}: ${filePath}`);
|
|
151
165
|
return true;
|
|
@@ -2433,7 +2447,24 @@ exports.Config = Schema.object({
|
|
|
2433
2447
|
function apply(ctx, config) {
|
|
2434
2448
|
var _a;
|
|
2435
2449
|
const logger = ctx.logger('mcmod');
|
|
2436
|
-
|
|
2450
|
+
const skia = ctx.skia;
|
|
2451
|
+
if (!(skia === null || skia === void 0 ? void 0 : skia.Canvas) || !(skia === null || skia === void 0 ? void 0 : skia.loadImage)) {
|
|
2452
|
+
throw new Error('缺少 skia 服务,请先启用 @ltxhhz/koishi-plugin-skia-canvas');
|
|
2453
|
+
}
|
|
2454
|
+
createCanvas = (w, h) => {
|
|
2455
|
+
const c = new skia.Canvas(w || 0, h || 0);
|
|
2456
|
+
if (!c || typeof c.getContext !== 'function') {
|
|
2457
|
+
throw new Error('skia 服务异常:Canvas 无效,请确认使用 @ltxhhz/koishi-plugin-skia-canvas');
|
|
2458
|
+
}
|
|
2459
|
+
return c;
|
|
2460
|
+
};
|
|
2461
|
+
loadImage = skia.loadImage;
|
|
2462
|
+
registerFont = (path, options) => {
|
|
2463
|
+
var _a;
|
|
2464
|
+
if ((_a = skia.FontLibrary) === null || _a === void 0 ? void 0 : _a.use)
|
|
2465
|
+
skia.FontLibrary.use(path, options === null || options === void 0 ? void 0 : options.family);
|
|
2466
|
+
};
|
|
2467
|
+
// 取消自定义字体配置,使用 skia 默认字体
|
|
2437
2468
|
// 初始化 Cookie
|
|
2438
2469
|
if (config.cookie) {
|
|
2439
2470
|
globalCookie = config.cookie;
|
|
@@ -2563,7 +2594,7 @@ function apply(ctx, config) {
|
|
|
2563
2594
|
img = await drawTutorialCard(item.link);
|
|
2564
2595
|
else
|
|
2565
2596
|
img = await createInfoCard(item.link, type);
|
|
2566
|
-
await session.send(h.image(img
|
|
2597
|
+
await session.send(h.image(await toImageSrc(img)));
|
|
2567
2598
|
if (config.sendLink)
|
|
2568
2599
|
await session.send(`链接: ${item.link}`);
|
|
2569
2600
|
return;
|
|
@@ -2612,7 +2643,7 @@ function apply(ctx, config) {
|
|
|
2612
2643
|
const item = results[0];
|
|
2613
2644
|
await ensureValidCookie();
|
|
2614
2645
|
const img = await drawModCard(item.link);
|
|
2615
|
-
await session.send(h.image(img
|
|
2646
|
+
await session.send(h.image(await toImageSrc(img)));
|
|
2616
2647
|
if (config.sendLink)
|
|
2617
2648
|
await session.send(`链接: ${item.link}`);
|
|
2618
2649
|
return;
|
|
@@ -2716,7 +2747,7 @@ function apply(ctx, config) {
|
|
|
2716
2747
|
img = await drawTutorialCard(item.link);
|
|
2717
2748
|
else
|
|
2718
2749
|
img = await createInfoCard(item.link, currentState.type);
|
|
2719
|
-
await session.send(h.image(img
|
|
2750
|
+
await session.send(h.image(await toImageSrc(img)));
|
|
2720
2751
|
if (config.sendLink)
|
|
2721
2752
|
await session.send(`链接: ${item.link}`);
|
|
2722
2753
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-cfmrmod",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Koishi 插件:搜索 CurseForge/Modrinth/MCMod 并渲染图片卡片",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"pub": "npm run build && npm publish --access public"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"koishi": "^4.0.0"
|
|
42
|
+
"koishi": "^4.0.0",
|
|
43
|
+
"@ltxhhz/koishi-plugin-skia-canvas": "^0.0.10"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@napi-rs/canvas": "^0.1.55",
|
|
46
46
|
"cheerio": "^1.0.0-rc.12",
|
|
47
47
|
"marked": "^9.1.5",
|
|
48
48
|
"node-fetch": "^2.6.12"
|
|
@@ -53,6 +53,9 @@
|
|
|
53
53
|
"koishi": {
|
|
54
54
|
"description": {
|
|
55
55
|
"zh": "从 CurseForge/Modrinth/MCMod 搜索模组/整合包/光影等内容,并生成图片卡片。"
|
|
56
|
+
},
|
|
57
|
+
"service": {
|
|
58
|
+
"required": ["skia"]
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
}
|