@sjtdev/koishi-plugin-dota2tracker 1.2.5 → 1.2.6-pre2

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/changelog.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### 1.2.6-pre
2
+ ##### (因koishi尚未更新发布pre版)
3
+ **改进&修复**:修复了`查询英雄`图片中 技能数值未被正确替换、全才英雄基础攻击力显示错误的问题,并优化了命石描述显示方式
4
+ **改进**:调整比赛战报图片样式:解析失败时显示的“第-手”改为“第?手”
5
+ **修复**:修复`查询玩家`图片中场次表现评分为0时显示为?的问题
6
+
7
+ #### pre2
8
+ **改进&修复**:彻底完善了`查询英雄`图片中所有由命石、神杖、魔晶提供或改变的数值说明,修复命石说明中技能数值为百分数时未带百分号的问题。
9
+
10
+ ### 1.2.5-fix
11
+ **修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
12
+ #### fix3
13
+ **修复**:修复日报使用时报错的问题。
14
+
1
15
  ### 1.2.5
2
16
  **改进**:优化`查询玩家`图片中近期战绩列表内未解析比赛的显示效果
3
17
  **修复**:修复`查询英雄`图片技能属性名多显示了一个冒号的问题
@@ -12,7 +26,7 @@
12
26
 
13
27
  ### 1.2.2
14
28
  **移除**:取消`查询英雄`的缓存功能,原因为valve的API返回的数据可能包含未本地化的字段(例如这次的7.36b更新后获取到的很多改动后技能说明暂时都是英文),这些数据无法根据版本判断是否需要更新缓存。
15
- **修复**:修复了`查询英雄`图片中某些命石提供技能可能被判定为先天技能的问题。(实际为API缺陷)
29
+ **修复**:修复了`查询英雄`图片中某些命石提供技能可能被判定为先天技能的问题。
16
30
 
17
31
  ### 1.2.1
18
32
  **改进**:优化比赛战报图片中,对多个同种物品(例如双护腕双挂件一类)的出装时间显示进行优化,原先都将显示为最后一件此种物品的购买时间,现在可以显示不同的时间。
package/lib/index.js CHANGED
@@ -884,24 +884,30 @@ function roundToDecimalPlaces(number, decimalPlaces) {
884
884
  }
885
885
  __name(roundToDecimalPlaces, "roundToDecimalPlaces");
886
886
  function formatHeroDesc(template, special_values, type = "normal" /* Normal */) {
887
- return template.replace(/%%|%([^%]+)%/g, (match, p1) => {
887
+ return template.replace(/%%|%([^%]+)%|\{([^}]+)\}/g, (match, p1, p2) => {
888
+ const field = p1 || p2;
888
889
  if (match === "%%") {
889
890
  return "%";
890
891
  } else {
892
+ const fieldName = field.replace(/^s:/, "").replace(/^shard_/, "").toLowerCase();
891
893
  const specialValue = special_values.find((sv) => {
892
- const match2 = /bonus_(.*)/.exec(p1);
893
- return sv.name === p1 || sv.name === match2?.[1];
894
+ const nameLower = sv.name.toLowerCase();
895
+ return nameLower === fieldName || nameLower === `bonus_${fieldName}` || nameLower === `shard_${fieldName}` || `bonus_${nameLower}` === fieldName || `shard_${nameLower}` === fieldName;
894
896
  });
895
897
  if (specialValue) {
896
898
  let valuesToUse = "";
897
- if (type == "facet" /* Facet */) {
898
- valuesToUse = specialValue.facet_bonus.name ? specialValue.facet_bonus.values.join(" / ") : specialValue.values_float.join(" / ");
899
- } else if (type == "scepter" /* Scepter */) {
900
- valuesToUse = specialValue.values_scepter.length ? specialValue.values_scepter.join(" / ") : specialValue.values_float.join(" / ");
901
- } else if (type == "shard" /* Shard */) {
902
- valuesToUse = specialValue.values_shard.length ? specialValue.values_shard.join(" / ") : specialValue.values_float.join(" / ");
903
- } else {
904
- valuesToUse = specialValue.values_float.join(" / ");
899
+ switch (type) {
900
+ case "facet" /* Facet */:
901
+ valuesToUse = specialValue.facet_bonus.name ? specialValue.facet_bonus.values.join(" / ") : specialValue.values_float.join(" / ");
902
+ break;
903
+ case "scepter" /* Scepter */:
904
+ valuesToUse = specialValue.values_scepter.length ? specialValue.values_scepter.join(" / ") : specialValue.values_float.join(" / ");
905
+ break;
906
+ case "shard" /* Shard */:
907
+ valuesToUse = specialValue.values_shard.length ? specialValue.values_shard.join(" / ") : specialValue.values_float.join(" / ");
908
+ break;
909
+ default:
910
+ valuesToUse = specialValue.values_float.join(" / ");
905
911
  }
906
912
  return `<span class="value">${valuesToUse}</span>`;
907
913
  } else {
@@ -1503,19 +1509,20 @@ async function apply(ctx, config) {
1503
1509
  if (facet) {
1504
1510
  if (!hero.facets[i].abilities)
1505
1511
  hero.facets[i].abilities = [];
1506
- hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(facet, all_special_values, "facet" /* Facet */), attributes: [] });
1512
+ hero.facets[i].abilities.push({ id: ab.id, name: ab.name, name_loc: ab.name_loc, description_ability_loc: formatHeroDesc(facet, ab.special_values, "facet" /* Facet */), attributes: [] });
1507
1513
  }
1508
1514
  });
1509
1515
  hero.facets.forEach((facet) => {
1510
1516
  const svs = ab.special_values.filter((sv) => sv.facet_bonus.name === facet.name);
1511
1517
  svs.forEach((sv) => {
1512
1518
  if (sv.heading_loc) {
1513
- facet.abilities.find((ability) => ab.id == ability.id)?.attributes.push({ heading_loc: sv.heading_loc, values: [...sv.facet_bonus.values] });
1519
+ facet.abilities.find((ability) => ab.id == ability.id)?.attributes.push({ heading_loc: sv.heading_loc, values: [...sv.facet_bonus.values], is_percentage: sv.is_percentage });
1514
1520
  }
1515
1521
  });
1522
+ facet.description_loc = formatHeroDesc(facet.description_loc, svs, "facet" /* Facet */);
1516
1523
  });
1517
- ab.desc_loc = formatHeroDesc(ab.desc_loc, all_special_values);
1518
- ab.notes_loc = ab.notes_loc.map((note) => formatHeroDesc(note, all_special_values));
1524
+ ab.desc_loc = formatHeroDesc(ab.desc_loc, ab.special_values, ab.ability_is_facet ? "facet" /* Facet */ : void 0);
1525
+ ab.notes_loc = ab.notes_loc.map((note) => formatHeroDesc(note, ab.special_values));
1519
1526
  if (ab.ability_has_scepter)
1520
1527
  ab.scepter_loc = formatHeroDesc(ab.scepter_loc, ab.special_values, "scepter" /* Scepter */);
1521
1528
  if (ab.ability_has_shard)
@@ -1690,17 +1697,23 @@ async function apply(ctx, config) {
1690
1697
  }
1691
1698
  });
1692
1699
  const combinations = Array.from(combinationsMap.values());
1693
- await ctx.broadcast(
1694
- [`${guild.platform}:${guild.guildId}`],
1695
- `昨日总结:
1696
- ${currentsubscribedPlayers.map(
1697
- (player) => `${player.name}: ${player.winCount}胜${player.loseCount}负 胜率${Math.round(player.winCount / player.matches.length * 100)}%,平均KDA: [${player.avgKills}/${player.avgDeaths}/${player.avgAssists}](${player.avgKDA}),平均表现: ${player.avgImp > 0 ? "+" : ""}${player.avgImp}`
1698
- ).join("\n")}
1699
- ${combinations.map((combi) => `组合[${combi.name}]: ${combi.winCount}胜${combi.matches.length - combi.winCount}负 胜率${Math.round(combi.winCount / combi.matches.length * 100)}%`).join("\n")}`.replace(
1700
- /\s*\n\s*/g,
1701
- "\n"
1702
- )
1703
- );
1700
+ try {
1701
+ await sendMessageToChannel(
1702
+ ctx,
1703
+ guild,
1704
+ // [`${guild.platform}:${guild.guildId}`],
1705
+ `昨日总结:
1706
+ ${currentsubscribedPlayers.map(
1707
+ (player) => `${player.name}: ${player.winCount}胜${player.loseCount}负 胜率${Math.round(player.winCount / player.matches.length * 100)}%,平均KDA: [${player.avgKills}/${player.avgDeaths}/${player.avgAssists}](${player.avgKDA}),平均表现: ${player.avgImp > 0 ? "+" : ""}${player.avgImp}`
1708
+ ).join("\n")}
1709
+ ${combinations.map((combi) => `组合[${combi.name}]: ${combi.winCount}胜${combi.matches.length - combi.winCount}负 胜率${Math.round(combi.winCount / combi.matches.length * 100)}%`).join("\n")}`.replace(
1710
+ /\s*\n\s*/g,
1711
+ "\n"
1712
+ )
1713
+ );
1714
+ } catch (error) {
1715
+ ctx.logger.error(error);
1716
+ }
1704
1717
  }
1705
1718
  }
1706
1719
  });
@@ -1766,7 +1779,7 @@ async function apply(ctx, config) {
1766
1779
  KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${player.kills}/${player.deaths}/${player.assists}],GPM/XPM:${player.goldPerMinute}/${player.experiencePerMinute},补刀数:${player.numLastHits}/${player.numDenies},伤害/塔伤:${player.heroDamage}/${player.towerDamage},参战/参葬率:${(player.killContribution * 100).toFixed(2)}%/${(player.deathContribution * 100).toFixed(2)}%`;
1767
1780
  broadMatchMessage += broadPlayerMessage + "\n";
1768
1781
  }
1769
- await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + img);
1782
+ await sendMessageToChannel(ctx, commingGuild, broadMatchMessage + img);
1770
1783
  ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
1771
1784
  }
1772
1785
  if (match.parsedDateTime)
@@ -1807,6 +1820,22 @@ function genImageHTML(data, template, type) {
1807
1820
  return result;
1808
1821
  }
1809
1822
  __name(genImageHTML, "genImageHTML");
1823
+ async function sendMessageToChannel(ctx, guild, broadMessage) {
1824
+ const targetChannels = await ctx.database.get("channel", { id: guild.guildId, platform: guild.platform });
1825
+ if (targetChannels.length === 1) {
1826
+ const bot = ctx.bots.find((bot2) => bot2.userId === targetChannels[0].assignee);
1827
+ if (bot) {
1828
+ await bot.sendMessage(guild.guildId, broadMessage);
1829
+ } else {
1830
+ throw new Error("指定的bot未找到。");
1831
+ }
1832
+ } else if (targetChannels.length > 1) {
1833
+ throw new Error("有复数个bot存在于该群组/频道,请移除多余bot。");
1834
+ } else {
1835
+ throw new Error("未找到目标群组/频道。");
1836
+ }
1837
+ }
1838
+ __name(sendMessageToChannel, "sendMessageToChannel");
1810
1839
  // Annotate the CommonJS export names for ESM import in node:
1811
1840
  0 && (module.exports = {
1812
1841
  Config,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sjtdev/koishi-plugin-dota2tracker",
3
3
  "description": "koishi插件-追踪群友的DOTA2对局",
4
- "version": "1.2.5",
4
+ "version": "1.2.6-pre2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -421,7 +421,7 @@
421
421
  padding-left: 0;
422
422
  }
423
423
 
424
- .skill .value{
424
+ .skill .value {
425
425
  color: #fff;
426
426
  }
427
427
 
@@ -458,6 +458,11 @@
458
458
  background-color: #263945;
459
459
  }
460
460
 
461
+ .skill .attributes {
462
+ line-height: 1.2em;
463
+ margin-bottom: 12px;
464
+ }
465
+
461
466
  .skill .attributes .item {
462
467
  color: #546780;
463
468
  }
@@ -470,12 +475,30 @@
470
475
  width: 16px;
471
476
  }
472
477
 
473
- .skill .attributes {
474
- margin-bottom: 12px;
478
+ .skill .attributes .facet {
479
+ display: inline-flex;
480
+ font-size: 1em;
481
+ align-items: center;
482
+ line-height: 1.2em;
483
+ position: unset;
484
+ color: #fff;
485
+ }
486
+
487
+ .skill .attributes .facet span {
488
+ height: auto;
489
+ width: auto;
490
+ position: unset;
491
+ padding: 0 2px;
492
+ }
493
+
494
+ .skill .attributes .facet img {
495
+ width: auto;
496
+ height: 1em;
497
+ padding-right: 0.2em;
475
498
  }
476
499
 
477
- .skill .mana_cost {
478
- padding-left: 12px;
500
+ .skill .cooldown {
501
+ padding-right: 12px;
479
502
  }
480
503
 
481
504
  .skill .cooldown::before,
@@ -515,6 +538,11 @@
515
538
  </head>
516
539
  <body>
517
540
  <% let hero = data; %>
541
+ <% if (hero.primary_attr==3) {
542
+ const base_damage = Math.floor((hero.str_base+hero.agi_base+hero.int_base)*0.7);
543
+ hero.damage_max+=base_damage;
544
+ hero.damage_min+=base_damage;
545
+ } %>
518
546
  <div class="wrapper">
519
547
  <%- `
520
548
  <div class="hero" id="${hero.id}">
@@ -620,7 +648,7 @@
620
648
  <span>${facet.title_loc}</span>
621
649
  </p>
622
650
  <div class="content">
623
- ${facet.description_loc ?`<p class="description">${facet.description_loc}</p>`:""}
651
+ ${facet.description_loc && !facet.abilities?.some(ability => ability.description_ability_loc === facet.description_loc) ?`<p class="description">${facet.description_loc}</p>`:""}
624
652
  ${facet.abilities?facet.abilities.map(ability=>
625
653
  `<div class="ability">
626
654
  <div class="name">
@@ -630,7 +658,7 @@
630
658
  ${ability.description_ability_loc?`<div class="description">${ability.description_ability_loc}</div>`:""}
631
659
  ${ability.attributes&&ability.attributes?.length ? ability.attributes.map(attr=>
632
660
  `<div class="attributes">
633
- <p><span class="item">${attr.heading_loc}</span><span class="values">${attr.values.join(" / ")}</span></p>
661
+ <p><span class="item">${attr.heading_loc}</span><span class="values">${attr.values.map(value => value + (attr.is_percentage ? "%" : "")).join(" / ")}</span></p>
634
662
  </div>`).join(""):""}
635
663
  </div>`).join("")
636
664
  :""}
@@ -705,7 +733,23 @@
705
733
  <div class="attributes">
706
734
  ${item.special_values
707
735
  .filter(sv => sv.heading_loc)
708
- .map((sv) => `<p><span class="item">${sv.heading_loc}</span><span class="values">${sv.values_float.map(value=>value+(sv.is_percentage?"%":"")).join(" / ")}${sv.bonuses.map(bonus=>` (<img src="${utils.getImageUrl("talents","icons","svg")}"/>${(bonus.value>0?"+":"")+bonus.value+(sv.is_percentage?"%":"")})`).join(" ")}</span></p>`)
736
+ .map((sv) =>
737
+ `<p>
738
+ <span class="item">${sv.heading_loc}</span>
739
+ <span class="values">
740
+ ${(!(((sv.values_float.length == 1 && sv.values_float[0] == 0) || sv.values_float.length == 0) && (sv.values_scepter.length || sv.values_shard.length || sv.facet_bonus.name))
741
+ ? (sv.values_float.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ")) : "")}
742
+ ${sv.values_scepter && sv.values_scepter.length
743
+ ? (sv.values_float.length == 0 || (sv.values_float.length == 1 && sv.values_float[0] == 0) ? `<img src="${utils.getImageUrl("scepter")}"/>${sv.values_scepter.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ")}` : ` (<img src="${utils.getImageUrl("scepter")}"/>${sv.values_scepter.map(value => (value > 0 ? "+" : "") + value + (sv.is_percentage ? "%" : "")).join(" / ")})`) : "" }
744
+ ${sv.values_shard && sv.values_shard.length
745
+ ? (sv.values_float.length == 0 || (sv.values_float.length == 1 && sv.values_float[0] == 0) ? `<img src="${utils.getImageUrl("shard")}"/>${sv.values_shard.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ")}` : ` (<img src="${utils.getImageUrl("shard")}"/>${sv.values_shard.map(value => (value > 0 ? "+" : "") + value + (sv.is_percentage ? "%" : "")).join(" / ")})`) : "" }
746
+ ${sv.facet_bonus.name
747
+ ? (sv.values_float.length == 0 || (sv.values_float.length == 1 && sv.values_float[0] == 0) ? `<span class="facet"><span class="name_back type_${hero.facets.find(facet=>facet.name==sv.facet_bonus.name).color}"><img src="${utils.getImageUrl(hero.facets.find(facet=>facet.name==sv.facet_bonus.name).icon, ImageType.IconsFacets)}" /><span>${sv.facet_bonus.values.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ")}</span></span></span>` : `(<span class="facet"><span class="name_back type_${hero.facets.find(facet=>facet.name==sv.facet_bonus.name).color}"><img src="${utils.getImageUrl(hero.facets.find(facet=>facet.name==sv.facet_bonus.name).icon, ImageType.IconsFacets)}" /><span>${sv.facet_bonus.values.map(value => (value > 0 ? "+" : "") + value + (sv.is_percentage ? "%" : "")).join(" / ")}</span></span></span>)` ) : ""}
748
+
749
+
750
+ ${sv.bonuses.map(bonus=>` (<img src="${utils.getImageUrl("talents","icons","svg")}"/>${(bonus.value>0?"+":"")+bonus.value+(sv.is_percentage?"%":"")})`).join(" ")}
751
+ </span>
752
+ </p>`)
709
753
  .join("")}
710
754
  </div>
711
755
  <p>
@@ -718,7 +718,7 @@
718
718
  <img alt="" src="${utils.getImageUrl(player.hero.shortName, ImageType.Heroes)}" />
719
719
  <p class="party_line${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
720
720
  <p class="party_mark${player.partyId != null ? " party_" + match.party[player.partyId] : ""}"></p>
721
- <p class="position p${Math.floor(player.order / 4) + 1}">${player.isRandom ? "随机" : `第<span>${player.order == null ? "-" : player.order + 1}</span>手`}<br/>${d2a.position[player.position?.slice(-1)]??""}</p>
721
+ <p class="position p${Math.floor(player.order / 4) + 1}">${player.isRandom ? "随机" : `第<span>${player.order == null ? "?" : player.order + 1}</span>手`}<br/>${d2a.position[player.position?.slice(-1)]??""}</p>
722
722
  <p class="level">${player.level}</p>
723
723
  </div>
724
724
  <div class="player_info">
@@ -491,7 +491,7 @@
491
491
  <span class="rank">${`[${d2a.rank[player.rank.medal]}${player.rank.star||""}]`}</span>
492
492
  <span class="name">${player.steamAccount.name}</span>
493
493
  </div>
494
- <p class="pick">${player.isRandom?'随机':`第${player.order == null ? "-" : player.order + 1}手`} ${d2a.position[player.position?.slice(-1)]??''}</p>
494
+ <p class="pick">${player.isRandom?'随机':`第${player.order == null ? "?" : player.order + 1}手`} ${d2a.position[player.position?.slice(-1)]??''}</p>
495
495
  <p class="networth">
496
496
  <span class="gold">${utils.formatNumber(player.networth)}</span>
497
497
  (${(player.heroDamage / player.networth)?.toFixed(2)})
@@ -521,7 +521,7 @@
521
521
  <td><div class="player_lane ${match.laneResult}">${laneSVG[match.laneResult]}</div></td>
522
522
  <td style="line-height: 20px">${moment(new Date(match.startDateTime * 1000)).format("YYYY-MM-DD HH:mm:ss").slice(2)}</td>
523
523
  <td>${utils.sec2time(match.durationSeconds)}</td>
524
- <td>${innerPlayer.imp ? ((innerPlayer.imp > 0 ? "+" : "") + innerPlayer.imp) : "?"}</td>
524
+ <td>${innerPlayer.imp != null ? ((innerPlayer.imp >= 0 ? "+" : "") + innerPlayer.imp) : "?"}</td>
525
525
  <td><img class="medal" src="${utils.getImageUrl("medal_" + match.rank?.toString().split("")[0])}" style="width: 100%" /></td>
526
526
  </tr>`}).join("")%>
527
527
  </tbody>