koishi-plugin-ll-mc 3.1.13 → 3.1.15

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.
Binary file
package/lib/index.js CHANGED
@@ -61,8 +61,8 @@ var usage = `## 📝 使用说明
61
61
  详细选项请发送 \`help messageCounter\` 查看。`;
62
62
  var logger = new import_koishi.Logger("messageCounter");
63
63
  var FONT_OPTIONS = {
64
- TITLE: "HarmonyOS_Sans_Medium",
65
- NICKNAME: "HarmonyOS_Sans_Medium"
64
+ TITLE: "Microsoft YaHei",
65
+ NICKNAME: "Microsoft YaHei"
66
66
  };
67
67
  var Config = import_koishi.Schema.intersect([
68
68
  // --- 核心功能 ---
@@ -283,7 +283,7 @@ async function apply(ctx, config) {
283
283
  } catch (error) {
284
284
  logger.warn("无法加载 fallbackBase64.json,将使用空的回退头像。", error);
285
285
  }
286
- const fontFiles = ["HarmonyOS_Sans_Medium.ttf", "NotoEmoji.ttf"];
286
+ const fontFiles = ["NotoEmoji.woff2"];
287
287
  for (const fontFile of fontFiles) {
288
288
  await copyAssetIfNotExists(
289
289
  import_path.default.join(assetsDir, "fonts"),
@@ -291,29 +291,41 @@ async function apply(ctx, config) {
291
291
  fontFile
292
292
  );
293
293
  }
294
- // 官机补丁:强制覆盖 NotoEmoji 字体(纯 emoji 版),
295
- // 防止旧版本(带数字字形)缓存在 data/messageCounter/fonts/ 里导致数字被加宽
294
+ // 官机补丁:强制覆盖 emoji 字体,并清掉旧版本残留(NotoEmoji.ttf / patched / 坏掉的 HarmonyOS)
296
295
  try {
297
- const emojiSrc = import_path.default.join(assetsDir, "fonts", "NotoEmoji.ttf");
298
- const emojiDest = import_path.default.join(fontsPath, "NotoEmoji.ttf");
296
+ const emojiSrc = import_path.default.join(assetsDir, "fonts", "NotoEmoji.woff2");
297
+ const emojiDest = import_path.default.join(fontsPath, "NotoEmoji.woff2");
299
298
  await fs.copyFile(emojiSrc, emojiDest);
300
- // 删除旧版补丁字体(避免旧版带数字字形的 patched 文件被继续加载、家族名冲突)
301
- const patched = import_path.default.join(fontsPath, "NotoEmoji-patched.ttf");
302
- await fs.rm(patched, { force: true });
303
- logger.info("[ll-mc] 已强制更新 NotoEmoji 字体为纯 emoji 版,并清理旧补丁字体。");
299
+ for (const stale of [
300
+ "NotoEmoji.ttf",
301
+ "NotoEmoji-patched.ttf",
302
+ "NotoSans-Regular.ttf",
303
+ "HarmonyOS_Sans_Medium.ttf"
304
+ ]) {
305
+ await fs.rm(import_path.default.join(fontsPath, stale), { force: true });
306
+ }
307
+ logger.info("[ll-mc] 已更新内置 emoji 字体(woff2)并清理旧字体残留。");
304
308
  } catch (error) {
305
- logger.warn("[ll-mc] 强制更新 NotoEmoji 字体失败:", error?.message);
309
+ logger.warn("[ll-mc] 更新内置 emoji 字体失败:", error?.message);
306
310
  }
307
- // 官机补丁(HTML 模板):系统装了 emoji 字体(如 font-noto-emoji)时,emoji 字体自带 0-9 字形
308
- // (给 keycap 用)且字宽很宽,会导致所有数字被撑成 "2 9 1 7"
309
- // 这里内嵌一个只含 0-9 的极小正常字体(约 3KB),用 unicode-range 把数字锁死在它上面;
310
- // base64 data URI 内嵌(而非相对路径),因为 file:// 页面加载 @font-face 本地文件不可靠。
311
- let digitsFontFaceCss = "";
311
+ // 官机补丁(HTML 模板):系统装了 emoji 字体(如 font-noto-emoji)后,emoji 字体自带 0-9 与空格字形
312
+ // (给 keycap 用)且字宽极宽,会把数字撑成 "2 9 1 7"、把空格撑近一个字宽。
313
+ // 1) 内嵌一个只含【空格 + 0-9】的极小正常字体(约 3KB),用 unicode-range 把这些字符锁死在它上面;
314
+ // 2) emoji 本身也内嵌(woff2,约 1.9MB),因为系统 emoji 字体两侧各留约 0.19em 空白,
315
+ // 正是"emoji 两边像有空格"的来源,而内置这个墨迹几乎填满字身。
316
+ // 全部用 base64 data URI 内嵌,不依赖 file:// 相对路径,goto/setContent 两条路径都生效。
317
+ let embeddedFontFacesCss = "";
312
318
  try {
313
- const digitsBuf = await fs.readFile(import_path.default.join(assetsDir, "fonts", "digits.ttf"));
314
- digitsFontFaceCss = `@font-face { font-family: 'LLMCDigits'; src: url("data:font/ttf;base64,${digitsBuf.toString("base64")}") format('truetype'); unicode-range: U+0030-0039; }`;
319
+ const lockBuf = await fs.readFile(import_path.default.join(assetsDir, "fonts", "lock.ttf"));
320
+ embeddedFontFacesCss += `@font-face { font-family: 'LLMCDigits'; src: url("data:font/ttf;base64,${lockBuf.toString("base64")}") format('truetype'); unicode-range: U+0020, U+0030-0039; }\n`;
315
321
  } catch (error) {
316
- logger.warn("[ll-mc] 加载 digits.ttf 失败,模板数字可能被 emoji 字体撑宽:", error?.message);
322
+ logger.warn("[ll-mc] 加载 lock.ttf 失败,模板数字/空格可能被 emoji 字体撑宽:", error?.message);
323
+ }
324
+ try {
325
+ const emojiBuf = await fs.readFile(import_path.default.join(assetsDir, "fonts", "NotoEmoji.woff2"));
326
+ embeddedFontFacesCss += `@font-face { font-family: 'LLMCEmoji'; src: url("data:font/woff2;base64,${emojiBuf.toString("base64")}") format('woff2'); }`;
327
+ } catch (error) {
328
+ logger.warn("[ll-mc] 加载 NotoEmoji.woff2 失败,模板 emoji 将回退到系统字体:", error?.message);
317
329
  }
318
330
  const avatarCache = /* @__PURE__ */ new Map();
319
331
  let iconCache = [];
@@ -1793,7 +1805,7 @@ ${targetUserRecord[0].username}
1793
1805
  let context = canvas.getContext('2d');
1794
1806
 
1795
1807
  // 根据最大计数的文本宽度动态调整画布宽度,以防数字溢出
1796
- context.font = \`30px "\${config.chartNicknameFont}", HarmonyOS_Sans_Medium, "Microsoft YaHei", sans-serif, "NotoEmoji"\`;
1808
+ context.font = \`30px "\${config.chartNicknameFont}", "Microsoft YaHei", sans-serif, "NotoEmoji"\`;
1797
1809
  // 找到拥有最大发言数的条目,因为它的文本通常最长
1798
1810
  const maxCountData = rankingData.find(d => d.count === maxCount) || rankingData[0] || { count: 1, percentage: 0 };
1799
1811
  let maxCountText = maxCount.toString();
@@ -1877,7 +1889,7 @@ ${targetUserRecord[0].username}
1877
1889
 
1878
1890
  async function drawTextAndIcons(context, data, index, avgColor, barX, barY, barWidth, barHeight) {
1879
1891
  // 字体栈包含了用户选择的字体、插件内置字体和通用字体,以确保兼容性。
1880
- context.font = \`30px "\${config.chartNicknameFont}", HarmonyOS_Sans_Medium, "Microsoft YaHei", sans-serif, "NotoEmoji"\`;
1892
+ context.font = \`30px "\${config.chartNicknameFont}", "Microsoft YaHei", sans-serif, "NotoEmoji"\`;
1881
1893
  const textY = barY + barHeight / 2 + 10.5;
1882
1894
 
1883
1895
 
@@ -2482,12 +2494,10 @@ ${targetUserRecord[0].username}
2482
2494
  <meta charset="UTF-8">
2483
2495
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
2484
2496
  <style>
2485
- /* 数字:内嵌极小(约3KB)的纯 0-9 字体并锁死,避免被系统 emoji 字体(自带 0-9 且字宽极宽)撑成 "2 9 1 7"。
2486
- base64 内嵌,保证 setContent 回退路径下也生效。 */
2487
- ${digitsFontFaceCss}
2488
- /* emoji:用内置的紧身 emoji 字体(墨迹几乎填满字身),而系统 emoji 字体两侧各留约 0.19em 空白,
2489
- 那正是"emoji 两边像有空格"的来源。相对路径 fonts/ 由 file:// 页面解析(模板已写入该目录)。 */
2490
- @font-face { font-family: 'LLMCEmoji'; src: url("fonts/NotoEmoji.ttf") format('truetype'); }
2497
+ /* 两个字体都以 base64 内嵌( embeddedFontFacesCss)
2498
+ - LLMCDigits:只含【空格 + 0-9】,用 unicode-range 把这两个易被 emoji 字体抢走、且字宽被撑宽的字符锁回正常文本字体;
2499
+ - LLMCEmoji :内置 emoji 字体,墨迹几乎填满字身(系统 emoji 字体两侧各留约 0.19em 空白,即"emoji 两边像有空格")。 */
2500
+ ${embeddedFontFacesCss}
2491
2501
  * { box-sizing: border-box; margin: 0; padding: 0; }
2492
2502
  html, body {
2493
2503
  width: 900px;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ll-mc",
3
3
  "description": "消息数量统计插件(基于 koishi-plugin-message-counter 重做,官方QQ机器人兼容)",
4
- "version": "3.1.13",
4
+ "version": "3.1.15",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
Binary file