@sjtdev/koishi-plugin-dota2tracker 1.1.2-hotfix.2 → 1.1.3

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 CHANGED
@@ -50,6 +50,7 @@ __export(utils_exports, {
50
50
  playerisValid: () => playerisValid,
51
51
  query: () => query,
52
52
  readDirectoryFilesSync: () => readDirectoryFilesSync,
53
+ roundToDecimalPlaces: () => roundToDecimalPlaces,
53
54
  sec2time: () => sec2time,
54
55
  winRateColor: () => winRateColor
55
56
  });
@@ -189,6 +190,32 @@ function MATCH_INFO(matchId) {
189
190
  `;
190
191
  }
191
192
  __name(MATCH_INFO, "MATCH_INFO");
193
+ function MATCHES_FOR_DAILY(steamAccountIds, seconds) {
194
+ return `
195
+ {
196
+ players(steamAccountIds:${JSON.stringify(steamAccountIds)}) {
197
+ steamAccount{id name}
198
+ matches(request:{startDateTime:${seconds} take:50}){
199
+ id
200
+ didRadiantWin
201
+ parsedDateTime
202
+ startDateTime
203
+ players {
204
+ kills
205
+ deaths
206
+ assists
207
+ imp
208
+ isRadiant
209
+ steamAccount {
210
+ id
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ `;
217
+ }
218
+ __name(MATCHES_FOR_DAILY, "MATCHES_FOR_DAILY");
192
219
  function VERIFYING_PLAYER(steamAccountId) {
193
220
  return `
194
221
  {
@@ -221,7 +248,7 @@ function PLAYERS_LASTMATCH(steamAccountIds) {
221
248
  `;
222
249
  }
223
250
  __name(PLAYERS_LASTMATCH, "PLAYERS_LASTMATCH");
224
- function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
251
+ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
225
252
  return `
226
253
  {
227
254
  player(steamAccountId: ${steamAccountId}) {
@@ -242,7 +269,7 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
242
269
  performance {
243
270
  imp
244
271
  }
245
- heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT, take: 25}) {
272
+ heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
246
273
  hero {
247
274
  id
248
275
  shortName
@@ -251,7 +278,7 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
251
278
  winCount
252
279
  matchCount
253
280
  }
254
- matches(request: {take: 25}) {
281
+ matches(request: {take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
255
282
  id
256
283
  rank
257
284
  lobbyType
@@ -286,10 +313,10 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId) {
286
313
  `;
287
314
  }
288
315
  __name(PLAYER_INFO_WITH_25_MATCHES, "PLAYER_INFO_WITH_25_MATCHES");
289
- function PLAYER_EXTRA_INFO(steamAccountId, matchCount, totalHeroCount) {
316
+ function PLAYER_EXTRA_INFO(steamAccountId, matchCount, totalHeroCount, heroId) {
290
317
  return `{
291
318
  player(steamAccountId: ${steamAccountId}) {
292
- heroesPerformance(take: ${totalHeroCount}, request: {matchGroupOrderBy: MATCH_COUNT, take: ${matchCount}}) {
319
+ heroesPerformance(take: ${totalHeroCount}, request: {matchGroupOrderBy: MATCH_COUNT, take: ${matchCount} ${heroId ? "heroIds:" + heroId : ""}}) {
293
320
  hero {
294
321
  id
295
322
  shortName
@@ -778,6 +805,11 @@ async function playerisValid(steamAccountId) {
778
805
  }
779
806
  }
780
807
  __name(playerisValid, "playerisValid");
808
+ function roundToDecimalPlaces(number, decimalPlaces) {
809
+ const factor = Math.pow(10, decimalPlaces);
810
+ return Math.round(number * factor) / factor;
811
+ }
812
+ __name(roundToDecimalPlaces, "roundToDecimalPlaces");
781
813
 
782
814
  // src/index.ts
783
815
  var import_fs2 = __toESM(require("fs"));
@@ -1055,12 +1087,24 @@ var dotaconstants_add_default = {
1055
1087
  var import_koishi2 = require("koishi");
1056
1088
  var ejs = __toESM(require("ejs"));
1057
1089
  var name = "dota2tracker";
1058
- var usage = "DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。";
1090
+ var usage = `
1091
+ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。
1092
+ **更多信息请进入插件主页查看。**`;
1059
1093
  var inject = ["database", "puppeteer", "cron"];
1060
1094
  var Config = import_koishi.Schema.intersect([
1061
1095
  import_koishi.Schema.object({
1062
1096
  STRATZ_API_TOKEN: import_koishi.Schema.string().required().description("※必须。stratz.com的API TOKEN,可在 https://stratz.com/api 获取")
1063
1097
  }).description("基础设置"),
1098
+ import_koishi.Schema.object({
1099
+ dailyReportSwitch: import_koishi.Schema.boolean().default(false).description("日报功能").experimental()
1100
+ }),
1101
+ import_koishi.Schema.union([
1102
+ import_koishi.Schema.object({
1103
+ dailyReportSwitch: import_koishi.Schema.const(true).required(),
1104
+ dailyReportHours: import_koishi.Schema.number().min(0).max(23).default(6).description("日报时间小时")
1105
+ }),
1106
+ import_koishi.Schema.object({})
1107
+ ]),
1064
1108
  import_koishi.Schema.object({
1065
1109
  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 有模板展示。"),
1066
1110
  template_player: import_koishi.Schema.union([...readDirectoryFilesSync(`./node_modules/@sjtdev/koishi-plugin-${name}/template/player`)]).default("player_1").description("生成玩家信息图片使用的模板。(目前仅有一张模板)"),
@@ -1254,7 +1298,7 @@ async function apply(ctx, config) {
1254
1298
  queryAndDisplayMatch(session, lastMatchId);
1255
1299
  }
1256
1300
  });
1257
- ctx.command("查询玩家 <input_data>", "查询玩家信息").usage("查询指定玩家的个人信息与最近战绩,生成图片发布。\n参数可输入该玩家的SteamID或已在本群绑定玩家的别名,无参数时尝试查询调用指令玩家的SteamID").example("-查询玩家 123456789").example("-查询玩家 张三").action(async ({ session }, input_data) => {
1301
+ 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) => {
1258
1302
  if (session.guild) {
1259
1303
  let sessionPlayer;
1260
1304
  if (!input_data) {
@@ -1270,15 +1314,16 @@ async function apply(ctx, config) {
1270
1314
  return;
1271
1315
  }
1272
1316
  session.send("正在获取玩家数据,请稍后...");
1317
+ let hero = findingHero(options.hero);
1273
1318
  let steamId = flagBindedPlayer?.steamId ?? input_data;
1274
1319
  let player;
1275
1320
  try {
1276
- let queryRes = await query(PLAYER_INFO_WITH_25_MATCHES(steamId));
1321
+ let queryRes = await query(PLAYER_INFO_WITH_25_MATCHES(steamId, hero.id));
1277
1322
  if (queryRes.status == 200) {
1278
1323
  player = queryRes.data.data.player;
1279
1324
  } else
1280
1325
  throw 0;
1281
- let queryRes2 = await query(PLAYER_EXTRA_INFO(steamId, player.matchCount, Object.keys(dotaconstants3.heroes).length));
1326
+ let queryRes2 = await query(PLAYER_EXTRA_INFO(steamId, player.matchCount, Object.keys(dotaconstants3.heroes).length, hero.id));
1282
1327
  if (queryRes2.status == 200) {
1283
1328
  let playerExtra = queryRes2.data.data.player;
1284
1329
  let filteredDotaPlus = {};
@@ -1290,11 +1335,11 @@ async function apply(ctx, config) {
1290
1335
  };
1291
1336
  }
1292
1337
  });
1293
- playerExtra.heroesPerformance.forEach((hero) => {
1294
- if (filteredDotaPlus[hero.hero.id]) {
1295
- filteredDotaPlus[hero.hero.id].shortName = hero.hero.shortName;
1296
- filteredDotaPlus[hero.hero.id].winCount = hero.winCount;
1297
- filteredDotaPlus[hero.hero.id].matchCount = hero.matchCount;
1338
+ playerExtra.heroesPerformance.forEach((hero2) => {
1339
+ if (filteredDotaPlus[hero2.hero.id]) {
1340
+ filteredDotaPlus[hero2.hero.id].shortName = hero2.hero.shortName;
1341
+ filteredDotaPlus[hero2.hero.id].winCount = hero2.winCount;
1342
+ filteredDotaPlus[hero2.hero.id].matchCount = hero2.matchCount;
1298
1343
  }
1299
1344
  });
1300
1345
  player.dotaPlus = Object.values(filteredDotaPlus);
@@ -1307,6 +1352,7 @@ async function apply(ctx, config) {
1307
1352
  player.heroesPerformanceTop10 = playerExtra.heroesPerformance.slice(0, 10);
1308
1353
  } else
1309
1354
  throw 0;
1355
+ player.genHero = hero ? true : false;
1310
1356
  session.send(await ctx.puppeteer.render(genImageHTML(player, config.template_player, "player" /* Player */)));
1311
1357
  } catch (error) {
1312
1358
  ctx.logger.error(error);
@@ -1316,24 +1362,8 @@ async function apply(ctx, config) {
1316
1362
  });
1317
1363
  ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").example("-查询英雄 15").example("-查询英雄 雷泽").example("-查询英雄 电魂").action(async ({ session }, input_data) => {
1318
1364
  if (input_data) {
1319
- let dc_heroes = Object.values(dotaconstants3.heroes).map((hero) => ({ id: hero["id"], name: hero["name"], shortName: hero["name"].match(/^npc_dota_hero_(.+)$/)[1] }));
1320
- let cn_heroes = Object.keys(HEROES_CHINESE).map((key) => ({
1321
- id: parseInt(key),
1322
- names_cn: HEROES_CHINESE[key]
1323
- }));
1324
- const mergedMap = /* @__PURE__ */ new Map();
1325
- [dc_heroes, cn_heroes].forEach((array) => {
1326
- array.forEach((item) => {
1327
- const existingItem = mergedMap.get(item.id);
1328
- if (existingItem)
1329
- mergedMap.set(item.id, { ...existingItem, ...item });
1330
- else
1331
- mergedMap.set(item.id, item);
1332
- });
1333
- });
1334
- let heroes3 = Array.from(mergedMap.values());
1335
- let findingHero = heroes3.find((hero) => hero.names_cn.includes(input_data) || hero.shortName === input_data.toLowerCase() || hero.id == input_data);
1336
- if (!findingHero) {
1365
+ let hero = findingHero(input_data);
1366
+ if (!hero) {
1337
1367
  session.send("未找到输入的英雄,请确认后重新输入。");
1338
1368
  return;
1339
1369
  }
@@ -1356,11 +1386,11 @@ async function apply(ctx, config) {
1356
1386
  }
1357
1387
  } else
1358
1388
  throw 0;
1359
- let queryRes3 = await query(HERO_INFO(findingHero.id));
1389
+ let queryRes3 = await query(HERO_INFO(hero.id));
1360
1390
  if (queryRes3.status == 200) {
1361
- let hero = queryRes3.data.data.constants.hero;
1362
- hero.talents.forEach((talent) => talent.name_cn = AbilitiesConstantsCN.data.abilities.find((item) => item.id == talent.abilityId).language.displayName);
1363
- await session.send(await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */)));
1391
+ let hero2 = queryRes3.data.data.constants.hero;
1392
+ hero2.talents.forEach((talent) => talent.name_cn = AbilitiesConstantsCN.data.abilities.find((item) => item.id == talent.abilityId).language.displayName);
1393
+ await session.send(await ctx.puppeteer.render(genImageHTML(hero2, config.template_hero, "hero" /* Hero */)));
1364
1394
  } else
1365
1395
  throw 0;
1366
1396
  } catch (error) {
@@ -1374,29 +1404,13 @@ async function apply(ctx, config) {
1374
1404
  });
1375
1405
  ctx.command("查询英雄对战 <input_data:string>", "查询英雄近一周的最佳搭档与最佳克星英雄").usage("根据输入英雄查询最近一周比赛数据(传奇~万古分段)中与该英雄组合胜率最高英雄和与该英雄对抗胜率最低英雄。\n参数可输入英雄ID、英雄名、英雄常用别名").option("limit", "-l <value:number> 返回英雄个数(默认值 5)", { fallback: 5 }).option("filter", "-f <value:number> 过滤场数过低的组合(单位:%,默认值0.75)", { fallback: 0.5 }).example("-查询英雄对战 敌法师 (无额外参数默认返回5个英雄,过滤舍弃场次占比0.75%以下)").example("-查询英雄对战 敌法师 -l=10 -f=1 (返回10个英雄,过滤舍弃场次占比1%以下)").example("-查询英雄对战 敌法师 -l 10 -f 1 (等同于上例,参数接空格也可使用)").action(async ({ session, options }, input_data) => {
1376
1406
  if (input_data) {
1377
- let dc_heroes = Object.values(dotaconstants3.heroes).map((hero) => ({ id: hero["id"], name: hero["name"], shortName: hero["name"].match(/^npc_dota_hero_(.+)$/)[1] }));
1378
- let cn_heroes = Object.keys(HEROES_CHINESE).map((key) => ({
1379
- id: parseInt(key),
1380
- names_cn: HEROES_CHINESE[key]
1381
- }));
1382
- const mergedMap = /* @__PURE__ */ new Map();
1383
- [dc_heroes, cn_heroes].forEach((array) => {
1384
- array.forEach((item) => {
1385
- const existingItem = mergedMap.get(item.id);
1386
- if (existingItem)
1387
- mergedMap.set(item.id, { ...existingItem, ...item });
1388
- else
1389
- mergedMap.set(item.id, item);
1390
- });
1391
- });
1392
- let heroes3 = Array.from(mergedMap.values());
1393
- let findingHero = heroes3.find((hero) => hero.names_cn.includes(input_data) || hero.shortName === input_data.toLowerCase() || hero.id == input_data);
1394
- if (!findingHero) {
1407
+ let hero = findingHero(input_data);
1408
+ if (!hero) {
1395
1409
  session.send("未找到输入的英雄,请确认后重新输入。");
1396
1410
  return;
1397
1411
  }
1398
1412
  try {
1399
- let queryRes = await query(HERO_MATCHUP_WINRATE(findingHero.id));
1413
+ let queryRes = await query(HERO_MATCHUP_WINRATE(hero.id));
1400
1414
  if (queryRes.status == 200) {
1401
1415
  let heroStats = queryRes.data.data.heroStats;
1402
1416
  let withTopFive = heroStats.matchUp[0].with.filter((item) => item.matchCount / heroStats.matchUp[0].matchCountWith > Math.max(0, Math.min(5, options.filter)) / 100).map((item) => {
@@ -1421,6 +1435,28 @@ async function apply(ctx, config) {
1421
1435
  }
1422
1436
  }
1423
1437
  });
1438
+ function findingHero(input) {
1439
+ if (!input)
1440
+ return;
1441
+ let dc_heroes = Object.values(dotaconstants3.heroes).map((hero) => ({ id: hero["id"], name: hero["name"], shortName: hero["name"].match(/^npc_dota_hero_(.+)$/)[1] }));
1442
+ let cn_heroes = Object.keys(HEROES_CHINESE).map((key) => ({
1443
+ id: parseInt(key),
1444
+ names_cn: HEROES_CHINESE[key]
1445
+ }));
1446
+ const mergedMap = /* @__PURE__ */ new Map();
1447
+ [dc_heroes, cn_heroes].forEach((array) => {
1448
+ array.forEach((item) => {
1449
+ const existingItem = mergedMap.get(item.id);
1450
+ if (existingItem)
1451
+ mergedMap.set(item.id, { ...existingItem, ...item });
1452
+ else
1453
+ mergedMap.set(item.id, item);
1454
+ });
1455
+ });
1456
+ let heroes3 = Array.from(mergedMap.values());
1457
+ return heroes3.find((hero) => hero.names_cn.includes(input) || hero.shortName === input.toLowerCase() || hero.id == input);
1458
+ }
1459
+ __name(findingHero, "findingHero");
1424
1460
  ctx.on("ready", async () => {
1425
1461
  const tables = await ctx.database.tables;
1426
1462
  if (!("dt_subscribed_guilds" in tables)) {
@@ -1443,6 +1479,78 @@ async function apply(ctx, config) {
1443
1479
  ctx.database.remove("dt_sended_match_id", { sendTime: { $lt: oneMonthAgo } });
1444
1480
  ctx.database.remove("dt_previous_query_results", { queryTime: { $lt: oneMonthAgo } });
1445
1481
  });
1482
+ if (config.dailyReportSwitch) {
1483
+ ctx.cron(`0 ${config.dailyReportHours} * * *`, async function() {
1484
+ const oneDayAgo = (0, import_moment.default)().subtract(1, "days").unix();
1485
+ const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
1486
+ const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
1487
+ let queryRes = await query(
1488
+ MATCHES_FOR_DAILY(
1489
+ subscribedPlayersInGuild.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index),
1490
+ oneDayAgo
1491
+ )
1492
+ );
1493
+ const players = queryRes.data.data.players.filter((player) => player.matches.length > 0);
1494
+ const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
1495
+ for (let subPlayer of subscribedPlayersInGuild) {
1496
+ let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
1497
+ if (!player)
1498
+ continue;
1499
+ const guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember(subPlayer.guildId, subPlayer.userId);
1500
+ subPlayer.name = subPlayer.nickName || (guildMember?.nick ?? players.find((player2) => player2.steamAccount.id == subPlayer.steamId)?.steamAccount.name);
1501
+ player.winCount = player.matches.filter((match) => match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).isRadiant).length;
1502
+ player.loseCount = player.matches.length - player.winCount;
1503
+ player.avgKills = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).kills, 0) / player.matches.length, 2);
1504
+ player.avgDeaths = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).deaths, 0) / player.matches.length, 2);
1505
+ player.avgAssists = roundToDecimalPlaces(
1506
+ player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).assists, 0) / player.matches.length,
1507
+ 2
1508
+ );
1509
+ player.avgKDA = roundToDecimalPlaces((player.avgKills + player.avgAssists) / (player.avgDeaths || 1), 2);
1510
+ player.avgImp = roundToDecimalPlaces(player.matches.reduce((acc, match) => acc + match.players.find((innerPlayer) => innerPlayer.steamAccount.id == player.steamAccount.id).imp, 0) / player.matches.length, 0);
1511
+ subPlayer = Object.assign(subPlayer, player);
1512
+ }
1513
+ for (let guild of subscribedGuilds) {
1514
+ const currentsubscribedPlayers = subscribedPlayersInGuild.filter((player) => player.platform == guild.platform && player.guildId == guild.guildId && player.matches?.length);
1515
+ if (currentsubscribedPlayers.length) {
1516
+ const currentsubscribedPlayersIds = currentsubscribedPlayers.map((player) => player.steamId);
1517
+ const combinationsMap = /* @__PURE__ */ new Map();
1518
+ matches.forEach((match) => {
1519
+ const sortedPlayerIds = match.players.map((player) => player.steamAccount.id).filter((id) => currentsubscribedPlayersIds.includes(id)).sort((a, b) => a.steamId - b.steamId);
1520
+ const key = sortedPlayerIds.join(",");
1521
+ if (!combinationsMap.has(key)) {
1522
+ const players2 = currentsubscribedPlayers.filter((subPlayer) => sortedPlayerIds.includes(subPlayer.steamId));
1523
+ if (players2.length > 0) {
1524
+ const name2 = players2.map((subPlayer) => subPlayer.name).join("/");
1525
+ combinationsMap.set(key, {
1526
+ players: players2,
1527
+ name: name2,
1528
+ winCount: match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == players2[0].steamId).isRadiant ? 1 : 0,
1529
+ matches: [match]
1530
+ });
1531
+ }
1532
+ } else {
1533
+ const combi = combinationsMap.get(key);
1534
+ combi.matches.push(match);
1535
+ combi.winCount += match.didRadiantWin == match.players.find((innerPlayer) => innerPlayer.steamAccount.id == combi.players[0].steamId).isRadiant ? 1 : 0;
1536
+ }
1537
+ });
1538
+ const combinations = Array.from(combinationsMap.values());
1539
+ await ctx.broadcast(
1540
+ [`${guild.platform}:${guild.guildId}`],
1541
+ `昨日总结:
1542
+ ${currentsubscribedPlayers.map(
1543
+ (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}`
1544
+ ).join("\n")}
1545
+ ${combinations.map((combi) => `组合[${combi.name}]: ${combi.winCount}胜${combi.matches.length - combi.winCount}负 胜率${Math.round(combi.winCount / combi.matches.length * 100)}%`).join("\n")}`.replace(
1546
+ /\s*\n\s*/g,
1547
+ "\n"
1548
+ )
1549
+ );
1550
+ }
1551
+ }
1552
+ });
1553
+ }
1446
1554
  ctx.cron("* * * * *", async function() {
1447
1555
  const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
1448
1556
  const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sjtdev/koishi-plugin-dota2tracker",
3
3
  "description": "",
4
- "version": "1.1.2-hotfix.2",
4
+ "version": "1.1.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -11,7 +11,8 @@
11
11
  "template"
12
12
  ],
13
13
  "contributors": [
14
- "sjtdev <sh1j1n9ta0@foxmail.com>"
14
+ "sjtdev <sh1j1n9ta0@foxmail.com>",
15
+ "sjtdev"
15
16
  ],
16
17
  "homepage": "https://github.com/sjtdev/koishi-plugin-dota2tracker",
17
18
  "repository": {
package/readme.md CHANGED
@@ -8,10 +8,10 @@ DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑
8
8
 
9
9
  ### 使用
10
10
  需在插件配置页填入STRATZ API TOKEN,否则无法使用。(配置中提供了API的获取链接)
11
- 在希望推送战报信息的群组使用指令【-订阅本群】,玩家可使用指令【-绑定】来将自身账号与Steam账号绑定,bot会尝试追踪已订阅群组中的绑定玩家的最新对局信息。
11
+ 在希望推送战报信息的群组使用指令`订阅本群`,玩家可使用指令`绑定`来将自身账号与Steam账号绑定,bot会尝试追踪已订阅群组中的绑定玩家的最新对局信息。
12
12
  其他查询功能见下方指令说明。
13
- **直接调用help指令可获取更详细的说明,调用【指令 -h】还会有用法示例。(例如:订阅本群 -h)**
14
- **更新日志见[changelog](changelog.md)
13
+ **直接调用help指令可获取更详细的说明,调用【指令 -h】还会有用法示例。(例如:订阅本群 -h)**
14
+ **更新日志见[changelog](changelog.md)**
15
15
 
16
16
  ### 指令
17
17
  指令 <必填参数> [可选参数]
@@ -530,13 +530,14 @@
530
530
  </tbody>
531
531
  </table>
532
532
  <div class="plus">
533
- <%- player.dotaPlus.map((hero) => `
533
+ <%- !player.genHero?
534
+ player.dotaPlus.map((hero) => `
534
535
  <div class="hero">
535
536
  <img src="${utils.getImageUrl(hero.shortName, ImageType.Heroes)}" alt="" />
536
537
  <div class="level"><img src="${utils.getImageUrl("hero_badge_" + Math.ceil((hero.level + 1) / 6))}" alt="" /><span>${hero.level}</span></div>
537
538
  <span>${((hero.winCount / hero.matchCount) * 100).toFixed(2)}%</span>
538
539
  <span>${hero.matchCount}</span>
539
- </div>`).join("") %>
540
+ </div>`).join(""):"" %>
540
541
  </div>
541
542
  </div>
542
543
  </body>