koishi-plugin-ll-mc 3.1.5 → 3.1.7
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/index.js +25 -8
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -357,6 +357,7 @@ async function apply(ctx, config) {
|
|
|
357
357
|
const fontsPath = import_path.default.join(messageCounterRoot, "fonts");
|
|
358
358
|
const avatarsPath = import_path.default.join(messageCounterRoot, "avatars");
|
|
359
359
|
const emptyHtmlPath = import_path.default.join(messageCounterRoot, "emptyHtml.html").replace(/\\/g, "/");
|
|
360
|
+
const templateHtmlPath = import_path.default.join(messageCounterRoot, "leaderboard-template.html").replace(/\\/g, "/");
|
|
360
361
|
const oldIconsPath = import_path.default.join(dataRoot, "messageCounterIcons");
|
|
361
362
|
const oldBarBgImgsPath = import_path.default.join(dataRoot, "messageCounterBarBgImgs");
|
|
362
363
|
await fs.mkdir(fontsPath, { recursive: true });
|
|
@@ -2559,7 +2560,7 @@ ${targetUserRecord[0].username}
|
|
|
2559
2560
|
</div>`;
|
|
2560
2561
|
}
|
|
2561
2562
|
__name(buildLeaderboardRow, "buildLeaderboardRow");
|
|
2562
|
-
function buildLeaderboardHtml(title, date, items, backgroundCss) {
|
|
2563
|
+
function buildLeaderboardHtml(title, date, items, backgroundCss, fontFaces) {
|
|
2563
2564
|
const maxCount = Math.max(1, ...items.map((item) => item.count || 0));
|
|
2564
2565
|
const rows = items.map((item, index) => buildLeaderboardRow(item, index, maxCount)).join("\n");
|
|
2565
2566
|
return `<!DOCTYPE html>
|
|
@@ -2568,6 +2569,7 @@ ${targetUserRecord[0].username}
|
|
|
2568
2569
|
<meta charset="UTF-8">
|
|
2569
2570
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2570
2571
|
<style>
|
|
2572
|
+
${fontFaces || ""}
|
|
2571
2573
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2572
2574
|
html, body {
|
|
2573
2575
|
width: 900px;
|
|
@@ -2576,7 +2578,7 @@ ${targetUserRecord[0].username}
|
|
|
2576
2578
|
background-color: #F5F7FA;
|
|
2577
2579
|
}
|
|
2578
2580
|
body {
|
|
2579
|
-
font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
2581
|
+
font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "NotoEmoji", "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
|
|
2580
2582
|
-webkit-font-smoothing: antialiased;
|
|
2581
2583
|
}
|
|
2582
2584
|
.card {
|
|
@@ -2592,8 +2594,7 @@ ${targetUserRecord[0].username}
|
|
|
2592
2594
|
.row { display: flex; align-items: center; gap: 12px; width: 100%; }
|
|
2593
2595
|
.avatar { width: 40px; height: 40px; flex-shrink: 0; }
|
|
2594
2596
|
.avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; box-shadow: 0 1px 2px rgba(0,0,0,0.08); background: #fff; padding: 2px; }
|
|
2595
|
-
.bar { position: relative; flex-grow: 1; height: 40px; border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; background:
|
|
2596
|
-
.bar::after { content: ''; position: absolute; inset: 0; background-image: linear-gradient(to right, transparent 99%, rgba(255,255,255,0.2) 100%); background-size: 10% 100%; pointer-events: none; }
|
|
2597
|
+
.bar { position: relative; flex-grow: 1; height: 40px; border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; background: transparent; }
|
|
2597
2598
|
.fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 8px 0 0 8px; z-index: 0; }
|
|
2598
2599
|
.bar-content { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; width: 100%; }
|
|
2599
2600
|
.row-name { font-size: 16px; font-weight: 700; display: flex; align-items: center; gap: 5px; max-width: 78%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -2621,14 +2622,30 @@ ${rows}
|
|
|
2621
2622
|
if (typeof ctx.puppeteer?.page !== "function") return null;
|
|
2622
2623
|
let page;
|
|
2623
2624
|
try {
|
|
2624
|
-
|
|
2625
|
+
// 复用图表的内置字体(含纯 emoji 的 NotoEmoji),以相对路径 fonts/<file> 加载,
|
|
2626
|
+
// 所以必须把模板写到 data/messageCounter/ 目录里再用 file:// 访问,相对路径才能解析。
|
|
2627
|
+
const fontFaces = generateFontFacesCSS(["HarmonyOS_Sans_Medium.ttf", "NotoEmoji.ttf"]);
|
|
2628
|
+
const html = buildLeaderboardHtml(title, date, items, backgroundCss, fontFaces);
|
|
2625
2629
|
page = await ctx.puppeteer.page();
|
|
2626
2630
|
await page.setViewport({ width: 900, height: 400, deviceScaleFactor: 2 });
|
|
2631
|
+
const pageUrl = templateHtmlPath.includes(":") ? `file:///${templateHtmlPath}` : `file://${templateHtmlPath}`;
|
|
2627
2632
|
try {
|
|
2628
|
-
await
|
|
2629
|
-
} catch (
|
|
2630
|
-
logger.warn("
|
|
2633
|
+
await fs.writeFile(templateHtmlPath, html);
|
|
2634
|
+
} catch (writeError) {
|
|
2635
|
+
logger.warn("无法写入排行榜模板文件,改用 setContent:", writeError?.message);
|
|
2631
2636
|
}
|
|
2637
|
+
if (typeof page.goto === "function") {
|
|
2638
|
+
try {
|
|
2639
|
+
await page.goto(pageUrl, { waitUntil: "load", timeout: 20000 });
|
|
2640
|
+
} catch (e) {
|
|
2641
|
+
logger.warn("Leaderboard template goto failed, using setContent:", e?.message);
|
|
2642
|
+
await page.setContent(html, { waitUntil: "networkidle0", timeout: 20000 }).catch(() => {});
|
|
2643
|
+
}
|
|
2644
|
+
} else {
|
|
2645
|
+
await page.setContent(html, { waitUntil: "networkidle0", timeout: 20000 }).catch(() => {});
|
|
2646
|
+
}
|
|
2647
|
+
// 确保 emoji 字体就绪再截图
|
|
2648
|
+
await page.evaluate(() => document.fonts.ready).catch(() => {});
|
|
2632
2649
|
await page.waitForSelector(".card").catch(() => {});
|
|
2633
2650
|
// 背景(自定义 CSS/API 背景)是加在 html 上的,必须截整页才能把卡片外的背景一起截进来;
|
|
2634
2651
|
// body 高度由内容撑开(无 min-height),所以 fullPage 不会产生多余空白。
|