koishi-plugin-cfmrmod 1.0.6 → 1.0.8

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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # koishi-plugin-cfmrmod
2
2
 
3
3
  Koishi 插件:搜索 CurseForge / Modrinth / MCMod,并渲染图片卡片。
4
+ 哥给个star吧
5
+ Star就是我维护的动力🤤
4
6
 
5
7
  ## 使用方法
6
8
 
@@ -1893,6 +1893,28 @@ async function fetchCurseForgeDetail(id, apiKey, timeout, cfUrl = null) {
1893
1893
  }
1894
1894
  // 搜索入口 (MR)
1895
1895
  async function searchModrinth(query, type, timeout) {
1896
+ // 先尝试直接通过ID/slug获取项目详情
1897
+ try {
1898
+ const project = await fetchJson(`${MR_BASE}/project/${encodeURIComponent(query)}`, {}, timeout);
1899
+ if (project && project.slug) {
1900
+ // 成功获取到项目,返回单个结果
1901
+ return [{
1902
+ platform: 'Modrinth',
1903
+ id: project.slug,
1904
+ name: project.title,
1905
+ author: project.author || 'Unknown',
1906
+ summary: project.description,
1907
+ type,
1908
+ icon: project.icon_url,
1909
+ downloads: project.downloads || 0,
1910
+ updated: new Date(project.updated || project.published).toLocaleDateString()
1911
+ }];
1912
+ }
1913
+ }
1914
+ catch (e) {
1915
+ // ID/slug获取失败,继续使用搜索API
1916
+ }
1917
+ // 使用搜索API
1896
1918
  const facet = MR_FACET_MAP[type];
1897
1919
  const url = `${MR_BASE}/search?query=${encodeURIComponent(query)}&facets=[["${facet}"]]&limit=20`;
1898
1920
  const json = await fetchJson(url, {}, timeout);
@@ -2029,8 +2051,10 @@ function apply(ctx, config) {
2029
2051
  '\n请输入序号查看详情 (p/n 翻页)';
2030
2052
  };
2031
2053
  const handleSearch = async (session, platform, type, keyword) => {
2032
- if (!keyword)
2033
- return session.send('请输入关键词');
2054
+ if (!keyword) {
2055
+ await session.send('请输入关键词');
2056
+ return;
2057
+ }
2034
2058
  let results = [];
2035
2059
  try {
2036
2060
  if (platform === 'mr')
@@ -2039,10 +2063,13 @@ function apply(ctx, config) {
2039
2063
  results = await searchCurseForge(keyword, type, config.curseforgeApiKey, config.requestTimeout, config.curseforgeGameId);
2040
2064
  }
2041
2065
  catch (e) {
2042
- return session.send(`搜索出错: ${e.message}`);
2066
+ await session.send(`搜索出错: ${e.message}`);
2067
+ return;
2068
+ }
2069
+ if (!results.length) {
2070
+ await session.send('未找到结果');
2071
+ return;
2043
2072
  }
2044
- if (!results.length)
2045
- return session.send('未找到结果');
2046
2073
  if (results.length === 1) {
2047
2074
  const item = results[0];
2048
2075
  try {
@@ -564,7 +564,7 @@ async function drawModCard(url) {
564
564
  versions.forEach(v => {
565
565
  dummy.font = `14px "${font}"`;
566
566
  const lw = dummy.measureText(v.l).width + 10;
567
- const lines = wrapText(dummy, v.v, 0, 0, contentW - lw, 20, 100, false) / 20;
567
+ const lines = wrapText(dummy, v.v, 0, 0, contentW - lw, 20, 500, false) / 20;
568
568
  extraH += lines * 20 + 10;
569
569
  });
570
570
  }
@@ -578,7 +578,7 @@ async function drawModCard(url) {
578
578
  const isHeader = node.tag === 'h';
579
579
  dummy.font = `${isHeader ? 'bold' : ''} ${isHeader ? 22 : 16}px "${font}"`;
580
580
  const lh = isHeader ? 32 : 26;
581
- const lines = wrapText(dummy, node.val, 0, 0, contentW, lh, 100, false) / lh;
581
+ const lines = wrapText(dummy, node.val, 0, 0, contentW, lh, 5000, false) / lh;
582
582
  descH += lines * lh + (isHeader ? 15 : 10);
583
583
  }
584
584
  else if (node.type === 'i') {
@@ -2653,7 +2653,7 @@ function apply(ctx, config) {
2653
2653
  const sentMessageIds = await session.send(listText);
2654
2654
  searchStates.set(session.cid, {
2655
2655
  results,
2656
- page: 0,
2656
+ pageIndex: 0,
2657
2657
  type: 'mod',
2658
2658
  messageIds: Array.isArray(sentMessageIds) ? sentMessageIds : [sentMessageIds],
2659
2659
  timer: setTimeout(() => {
@@ -2686,6 +2686,7 @@ function apply(ctx, config) {
2686
2686
  if (input === 'p' || input === 'n') {
2687
2687
  // 加入队列处理翻页,防止并发
2688
2688
  enqueue(session, 'page-turn', async () => {
2689
+ var _a, _b;
2689
2690
  // 重新获取状态,防止排队期间状态丢失
2690
2691
  const currentState = searchStates.get(session.cid);
2691
2692
  if (!currentState)
@@ -2693,10 +2694,11 @@ function apply(ctx, config) {
2693
2694
  clearTimeout(currentState.timer);
2694
2695
  currentState.timer = setTimeout(() => searchStates.delete(session.cid), TIMEOUT_MS);
2695
2696
  const total = Math.ceil(currentState.results.length / PAGE_SIZE);
2696
- let newIndex = currentState.pageIndex;
2697
- if (input === 'n' && currentState.pageIndex < total - 1)
2697
+ const currentPage = Number((_b = (_a = currentState.pageIndex) !== null && _a !== void 0 ? _a : currentState.page) !== null && _b !== void 0 ? _b : 0) || 0;
2698
+ let newIndex = currentPage;
2699
+ if (input === 'n' && currentPage < total - 1)
2698
2700
  newIndex++;
2699
- else if (input === 'p' && currentState.pageIndex > 0)
2701
+ else if (input === 'p' && currentPage > 0)
2700
2702
  newIndex--;
2701
2703
  else {
2702
2704
  await session.send('没有更多页面了。');
@@ -2705,8 +2707,8 @@ function apply(ctx, config) {
2705
2707
  // 撤回旧列表(可选,为了整洁)
2706
2708
  await tryWithdraw(session, currentState.messageIds);
2707
2709
  currentState.pageIndex = newIndex;
2708
- const newMsgIds = await session.send(formatListPage(currentState.results, currentState.pageIndex, currentState.type));
2709
- currentState.messageIds = newMsgIds;
2710
+ const newMsgIds = await session.send(formatListPage(currentState.results, newIndex, currentState.type));
2711
+ currentState.messageIds = Array.isArray(newMsgIds) ? newMsgIds : [newMsgIds];
2710
2712
  });
2711
2713
  return;
2712
2714
  }
@@ -2715,12 +2717,13 @@ function apply(ctx, config) {
2715
2717
  if (!isNaN(choice) && choice >= 1) {
2716
2718
  // 加入队列处理生成卡片
2717
2719
  enqueue(session, 'select-item', async () => {
2718
- var _a;
2720
+ var _a, _b, _c;
2719
2721
  const currentState = searchStates.get(session.cid);
2720
2722
  if (!currentState)
2721
2723
  return; // 状态可能已过期
2722
2724
  const idx = choice - 1;
2723
- const pageStart = currentState.pageIndex * PAGE_SIZE;
2725
+ const currentPage = Number((_b = (_a = currentState.pageIndex) !== null && _a !== void 0 ? _a : currentState.page) !== null && _b !== void 0 ? _b : 0) || 0;
2726
+ const pageStart = currentPage * PAGE_SIZE;
2724
2727
  const pageEnd = Math.min(pageStart + PAGE_SIZE, currentState.results.length);
2725
2728
  if (choice < pageStart + 1 || choice > pageEnd) {
2726
2729
  // 如果序号不在当前页,忽略或提示
@@ -2738,7 +2741,7 @@ function apply(ctx, config) {
2738
2741
  if (currentState.type === 'author')
2739
2742
  img = await drawAuthorCard(item.link);
2740
2743
  else if (currentState.type === 'user') {
2741
- const uid = ((_a = item.link.match(/\/(\d+)(?:\.html|\/)?$/)) === null || _a === void 0 ? void 0 : _a[1]) || '0';
2744
+ const uid = ((_c = item.link.match(/\/(\d+)(?:\.html|\/)?$/)) === null || _c === void 0 ? void 0 : _c[1]) || '0';
2742
2745
  img = await drawCenterCardImpl(uid, logger);
2743
2746
  }
2744
2747
  else if (currentState.type === 'mod' || currentState.type === 'pack')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-cfmrmod",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Koishi 插件:搜索 CurseForge/Modrinth/MCMod 并渲染图片卡片",
5
5
  "main": "dist/index.js",
6
6
  "files": [