@sjtdev/koishi-plugin-dota2tracker 1.2.6 → 1.2.7-beta.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/changelog.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### 1.2.7-beta
2
+ **新增**:可在配置页设置发布战报时附带stratz比赛链接、查询玩家信息时附带stratz玩家页面链接,这些选项均默认关闭。
3
+ **修复**:(beta测试中) 尝试修复当同一个steamId在多个已订阅群组中绑定时,仅会向最早绑定的群组发送战报的问题。
4
+ **修复**:现在若所有玩家某项属性都为0时不会错误地将对应称号赋予玩家1,而是取消此称号赋予。(此版本前例如所有玩家治疗量都为0,玩家1会获得“奶”称号,而现在将不会有玩家获得“奶”称号)
5
+
1
6
  ### 1.2.6
2
7
  因koishi更新至4.17.10修复了主动发送消息的函数,本插件的发送消息方式也换回之前的方案以避免可能的代码问题。(功能使用上与1.2.6-pre3版本一致)
3
8
 
@@ -12,7 +17,7 @@
12
17
 
13
18
  #### pre3
14
19
  **改进&修复**:继续优化`查询英雄`代码结构使由命石、神杖、魔晶改变的技能属性更直观;修复某些技能数据中有旧天赋加成数据留存、导致的天赋数值未被正确填充。
15
- **改进**:为`艾欧`添加别名:["艾欧", "小精灵"] → ["艾欧", "小精灵", "精灵", "IO"]
20
+ **改进**:为英雄`艾欧`添加别名:["艾欧", "小精灵"] → ["艾欧", "小精灵", "精灵", "IO"]
16
21
 
17
22
  ### 1.2.5-fix
18
23
  **修复**:使用临时替代方案修复由koishi-4.17.9的bug引起的无法主动发送消息(播报战报等),待koishi更新修复后回滚此改动。
package/lib/index.js CHANGED
@@ -770,7 +770,7 @@ function getFormattedMatchData(match) {
770
770
  ComparisonMode2["Min"] = "min";
771
771
  })(ComparisonMode || (ComparisonMode = {}));
772
772
  function findMaxByProperty(primaryProperty, secondaryProperty = null, players = match.players, primaryMode = "max" /* Max */, secondaryMode = "max" /* Max */) {
773
- return players.reduce((result, player) => {
773
+ let maxPlayer = players.reduce((result, player) => {
774
774
  const primaryComparison = primaryMode === "max" /* Max */ ? player[primaryProperty] > result[primaryProperty] : player[primaryProperty] < result[primaryProperty];
775
775
  const secondaryComparison = secondaryMode === "max" /* Max */ ? player[secondaryProperty] > result[secondaryProperty] : player[secondaryProperty] < result[secondaryProperty];
776
776
  if (primaryComparison) {
@@ -780,20 +780,21 @@ function getFormattedMatchData(match) {
780
780
  }
781
781
  return result;
782
782
  });
783
+ return maxPlayer[primaryProperty] > 0 ? maxPlayer : null;
783
784
  }
784
785
  __name(findMaxByProperty, "findMaxByProperty");
785
786
  findMaxByProperty(
786
787
  "mvpScore",
787
788
  void 0,
788
789
  match.players.filter((player) => match.didRadiantWin == player.isRadiant)
789
- ).titles.push({ name: "MVP", color: "#FFA500" });
790
+ )?.titles.push({ name: "MVP", color: "#FFA500" });
790
791
  findMaxByProperty(
791
792
  "mvpScore",
792
793
  void 0,
793
794
  match.players.filter((player) => match.didRadiantWin != player.isRadiant)
794
- ).titles.push({ name: "魂", color: "#6cf" });
795
- findMaxByProperty("networth").titles.push({ name: "富", color: "#FFD700" });
796
- findMaxByProperty("experiencePerMinute").titles.push({ name: "睿", color: "#8888FF" });
795
+ )?.titles.push({ name: "魂", color: "#6cf" });
796
+ findMaxByProperty("networth")?.titles.push({ name: "富", color: "#FFD700" });
797
+ findMaxByProperty("experiencePerMinute")?.titles.push({ name: "睿", color: "#8888FF" });
797
798
  if (match.parsedDateTime) {
798
799
  match.players.reduce(
799
800
  (max, player) => player.stats.heroDamageReport.dealtTotal.stunDuration + player.stats.heroDamageReport.dealtTotal.disableDuration / 2 + player.stats.heroDamageReport.dealtTotal.slowDuration / 4 > max.stats.heroDamageReport.dealtTotal.stunDuration + max.stats.heroDamageReport.dealtTotal.disableDuration / 2 + max.stats.heroDamageReport.dealtTotal.slowDuration / 4 ? player : max
@@ -802,12 +803,12 @@ function getFormattedMatchData(match) {
802
803
  (max, player) => player.stats.heroDamageReport.receivedTotal.physicalDamage + player.stats.heroDamageReport.receivedTotal.magicalDamage + player.stats.heroDamageReport.receivedTotal.pureDamage > max.stats.heroDamageReport.receivedTotal.physicalDamage + max.stats.heroDamageReport.receivedTotal.magicalDamage + max.stats.heroDamageReport.receivedTotal.pureDamage ? player : max
803
804
  ).titles.push({ name: "耐", color: "#84A1C7" });
804
805
  }
805
- findMaxByProperty("heroDamage").titles.push({ name: "爆", color: "#CC0088" });
806
- findMaxByProperty("kills", "heroDamage").titles.push({ name: "破", color: "#DD0000" });
807
- findMaxByProperty("deaths", "networth", void 0, void 0, "min" /* Min */).titles.push({ name: "鬼", color: "#CCCCCC" });
808
- findMaxByProperty("assists", "heroDamage").titles.push({ name: "助", color: "#006400" });
809
- findMaxByProperty("towerDamage", "heroDamage").titles.push({ name: "拆", color: "#FEDCBA" });
810
- findMaxByProperty("heroHealing").titles.push({ name: "奶", color: "#00FF00" });
806
+ findMaxByProperty("heroDamage")?.titles.push({ name: "爆", color: "#CC0088" });
807
+ findMaxByProperty("kills", "heroDamage")?.titles.push({ name: "破", color: "#DD0000" });
808
+ findMaxByProperty("deaths", "networth", void 0, void 0, "min" /* Min */)?.titles.push({ name: "鬼", color: "#CCCCCC" });
809
+ findMaxByProperty("assists", "heroDamage")?.titles.push({ name: "助", color: "#006400" });
810
+ findMaxByProperty("towerDamage", "heroDamage")?.titles.push({ name: "拆", color: "#FEDCBA" });
811
+ findMaxByProperty("heroHealing")?.titles.push({ name: "奶", color: "#00FF00" });
811
812
  match.players.reduce((lowest, player) => {
812
813
  const currentContribution = (player.kills + player.assists) / match[player.team].killsCount;
813
814
  const lowestContribution = (lowest.kills + lowest.assists) / match[lowest.team].killsCount;
@@ -1213,6 +1214,11 @@ var Config = import_koishi.Schema.intersect([
1213
1214
  }),
1214
1215
  import_koishi.Schema.object({})
1215
1216
  ]),
1217
+ import_koishi.Schema.object({
1218
+ urlInMessageType: import_koishi.Schema.array(
1219
+ import_koishi.Schema.union([import_koishi.Schema.const("match").description("在查询比赛与战报消息中附带stratz比赛链接"), import_koishi.Schema.const("player").description("在查询玩家信息消息中附带stratz玩家链接"), import_koishi.Schema.const("hero").description("---").disabled()])
1220
+ ).role("checkbox").description("在消息中附带链接,<br/>请选择消息类型:")
1221
+ }),
1216
1222
  import_koishi.Schema.object({
1217
1223
  template_match: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/match`)]).default("match_1").description("生成比赛信息图片使用的模板,见 https://github.com/sjtdev/koishi-plugin-dota2tracker/wiki 有模板展示。"),
1218
1224
  template_player: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/player`)]).default("player_1").description("生成玩家信息图片使用的模板。(目前仅有一张模板)"),
@@ -1345,7 +1351,7 @@ async function apply(ctx, config) {
1345
1351
  }
1346
1352
  }
1347
1353
  });
1348
- async function queryAndDisplayMatch(session, matchId) {
1354
+ async function queryMatchAndSend(session, matchId) {
1349
1355
  try {
1350
1356
  let match;
1351
1357
  let queryLocal = await ctx.database.get("dt_previous_query_results", matchId, ["data"]);
@@ -1356,7 +1362,7 @@ async function apply(ctx, config) {
1356
1362
  match = getFormattedMatchData((await query(MATCH_INFO(matchId))).data.match);
1357
1363
  }
1358
1364
  if (match && (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(config.dataParsingTimeoutMinutes, "minutes")))) {
1359
- session.send(await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
1365
+ session.send((ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + matchId : "") + await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
1360
1366
  if (match.parsedDateTime)
1361
1367
  ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
1362
1368
  } else {
@@ -1369,7 +1375,7 @@ async function apply(ctx, config) {
1369
1375
  ctx.database.remove("dt_previous_query_results", { matchId: parseInt(matchId) });
1370
1376
  }
1371
1377
  }
1372
- __name(queryAndDisplayMatch, "queryAndDisplayMatch");
1378
+ __name(queryMatchAndSend, "queryMatchAndSend");
1373
1379
  ctx.command("查询比赛 <match_id>", "查询比赛ID").usage("查询指定比赛ID的比赛数据,生成图片发布。").example("查询比赛 1234567890").action(async ({ session }, match_id) => {
1374
1380
  if (!match_id) {
1375
1381
  session.send("请输入比赛ID。");
@@ -1381,7 +1387,7 @@ async function apply(ctx, config) {
1381
1387
  return;
1382
1388
  }
1383
1389
  session.send("正在搜索对局详情,请稍后...");
1384
- queryAndDisplayMatch(session, match_id);
1390
+ queryMatchAndSend(session, match_id);
1385
1391
  });
1386
1392
  ctx.command("查询最近比赛 [input_data]", "查询玩家的最近比赛").usage("查询指定玩家的最近一场比赛的比赛数据,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").example("查询最近比赛 123456789").example("查询最近比赛 张三").action(async ({ session }, input_data) => {
1387
1393
  if (session.guild) {
@@ -1406,7 +1412,7 @@ async function apply(ctx, config) {
1406
1412
  session.send("获取玩家最近比赛失败。");
1407
1413
  return;
1408
1414
  }
1409
- queryAndDisplayMatch(session, lastMatchId);
1415
+ queryMatchAndSend(session, lastMatchId);
1410
1416
  }
1411
1417
  });
1412
1418
  ctx.command("查询玩家 <input_data>", "查询玩家信息,可指定英雄").usage("查询指定玩家的个人信息与最近战绩,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").option("hero", "-o <value:string> 查询玩家指定英雄使用情况(同其他英雄查询,可用简称与ID)").example("查询玩家 123456789").example("查询玩家 张三").example("查询玩家 张三 hero 敌法师").action(async ({ session, options }, input_data) => {
@@ -1469,7 +1475,9 @@ async function apply(ctx, config) {
1469
1475
  player.dotaPlus = player.dotaPlus.filter((dpHero) => dpHero.heroId == hero.id);
1470
1476
  }
1471
1477
  player.genHero = hero;
1472
- session.send(await ctx.puppeteer.render(genImageHTML(player, config.template_player, "player" /* Player */)));
1478
+ session.send(
1479
+ (ctx.config.urlInMessageType.some((type) => type == "player") ? "https://stratz.com/players/" + player.steamAccount.id : "") + await ctx.puppeteer.render(genImageHTML(player, config.template_player, "player" /* Player */))
1480
+ );
1473
1481
  } catch (error) {
1474
1482
  ctx.logger.error(error);
1475
1483
  session.send("获取玩家信息失败。");
@@ -1657,7 +1665,12 @@ async function apply(ctx, config) {
1657
1665
  let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
1658
1666
  if (!player)
1659
1667
  continue;
1660
- const guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember(subPlayer.guildId, subPlayer.userId);
1668
+ let guildMember;
1669
+ try {
1670
+ guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember(subPlayer.guildId, subPlayer.userId);
1671
+ } catch (error) {
1672
+ ctx.logger.error("获取群组信息失败。Error:" + error);
1673
+ }
1661
1674
  subPlayer.name = subPlayer.nickName || (guildMember?.nick ?? players.find((player2) => player2.steamAccount.id == subPlayer.steamId)?.steamAccount.name);
1662
1675
  player.winCount = player.matches.filter((match) => match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).isRadiant).length;
1663
1676
  player.loseCount = player.matches.length - player.winCount;
@@ -1728,14 +1741,15 @@ async function apply(ctx, config) {
1728
1741
  lastMatches.filter((match) => !sendedMatchesIds.includes(match.id)).forEach((match) => {
1729
1742
  const tempGuilds = [];
1730
1743
  match.players.forEach((player) => {
1731
- const subscribedPlayer = subscribedPlayersInGuild.find((subscribedPlayer2) => subscribedPlayer2.steamId === player.steamAccount.id);
1732
- if (subscribedPlayer) {
1733
- const tempGuild = tempGuilds.find((guild) => guild.guildId == subscribedPlayer.guildId && guild.platform == subscribedPlayer.platform);
1734
- if (tempGuild)
1735
- tempGuild.players.push(subscribedPlayer);
1736
- else
1737
- tempGuilds.push({ guildId: subscribedPlayer.guildId, platform: subscribedPlayer.platform, players: [subscribedPlayer] });
1738
- }
1744
+ subscribedPlayersInGuild.filter((subscribedPlayer) => subscribedPlayer.steamId === player.steamAccount.id).forEach((subscribedPlayer) => {
1745
+ if (subscribedPlayer) {
1746
+ const tempGuild = tempGuilds.find((guild) => guild.guildId == subscribedPlayer.guildId && guild.platform == subscribedPlayer.platform);
1747
+ if (tempGuild)
1748
+ tempGuild.players.push(subscribedPlayer);
1749
+ else
1750
+ tempGuilds.push({ guildId: subscribedPlayer.guildId, platform: subscribedPlayer.platform, players: [subscribedPlayer] });
1751
+ }
1752
+ });
1739
1753
  });
1740
1754
  pendingMatches.push({ matchId: match.id, guilds: tempGuilds });
1741
1755
  ctx.logger.info(
@@ -1777,7 +1791,7 @@ async function apply(ctx, config) {
1777
1791
  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)}%`;
1778
1792
  broadMatchMessage += broadPlayerMessage + "\n";
1779
1793
  }
1780
- await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + img);
1794
+ await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + (ctx.config.urlInMessageType.some((type) => type == "match") ? "https://stratz.com/matches/" + match.id : "") + img);
1781
1795
  ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
1782
1796
  }
1783
1797
  if (match.parsedDateTime)
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.6",
4
+ "version": "1.2.7-beta.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [