@sjtdev/koishi-plugin-dota2tracker 1.1.6-hotfix → 1.1.8-beta.1
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 +153 -168
- package/package.json +1 -2
- package/template/player/player_1.ejs +3 -3
package/lib/index.js
CHANGED
|
@@ -52,15 +52,28 @@ __export(utils_exports, {
|
|
|
52
52
|
readDirectoryFilesSync: () => readDirectoryFilesSync,
|
|
53
53
|
roundToDecimalPlaces: () => roundToDecimalPlaces,
|
|
54
54
|
sec2time: () => sec2time,
|
|
55
|
-
|
|
55
|
+
setHttp: () => setHttp,
|
|
56
56
|
winRateColor: () => winRateColor
|
|
57
57
|
});
|
|
58
|
-
var import_axios = __toESM(require("axios"));
|
|
59
58
|
var import_fs = __toESM(require("fs"));
|
|
60
59
|
var dotaconstants2 = __toESM(require("dotaconstants"));
|
|
61
60
|
var import_path = __toESM(require("path"));
|
|
62
61
|
|
|
63
62
|
// src/queries.ts
|
|
63
|
+
var queries_exports = {};
|
|
64
|
+
__export(queries_exports, {
|
|
65
|
+
ALL_ABILITIES_CHINESE_NAME: () => ALL_ABILITIES_CHINESE_NAME,
|
|
66
|
+
CURRENT_GAMEVERSION: () => CURRENT_GAMEVERSION,
|
|
67
|
+
HERO_INFO: () => HERO_INFO,
|
|
68
|
+
HERO_MATCHUP_WINRATE: () => HERO_MATCHUP_WINRATE,
|
|
69
|
+
MATCHES_FOR_DAILY: () => MATCHES_FOR_DAILY,
|
|
70
|
+
MATCH_INFO: () => MATCH_INFO,
|
|
71
|
+
PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD: () => PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD,
|
|
72
|
+
PLAYERS_LASTMATCH: () => PLAYERS_LASTMATCH,
|
|
73
|
+
PLAYER_EXTRA_INFO: () => PLAYER_EXTRA_INFO,
|
|
74
|
+
PLAYER_INFO_WITH_25_MATCHES: () => PLAYER_INFO_WITH_25_MATCHES,
|
|
75
|
+
VERIFYING_PLAYER: () => VERIFYING_PLAYER
|
|
76
|
+
});
|
|
64
77
|
var dotaconstants = __toESM(require("dotaconstants"));
|
|
65
78
|
function MATCH_INFO(matchId) {
|
|
66
79
|
return `
|
|
@@ -254,60 +267,60 @@ function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
|
|
|
254
267
|
{
|
|
255
268
|
player(steamAccountId: ${steamAccountId}) {
|
|
256
269
|
steamAccount {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
avatar
|
|
271
|
+
name
|
|
272
|
+
seasonRank
|
|
273
|
+
seasonLeaderboardRank
|
|
274
|
+
id
|
|
262
275
|
}
|
|
263
276
|
guildMember {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
277
|
+
guild {
|
|
278
|
+
tag
|
|
279
|
+
}
|
|
267
280
|
}
|
|
268
281
|
matchCount
|
|
269
282
|
winCount
|
|
270
283
|
performance {
|
|
271
|
-
|
|
284
|
+
imp
|
|
272
285
|
}
|
|
273
286
|
heroesPerformance(take: 25, request: {matchGroupOrderBy: WIN_COUNT take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
hero {
|
|
288
|
+
id
|
|
289
|
+
shortName
|
|
290
|
+
}
|
|
291
|
+
imp
|
|
292
|
+
winCount
|
|
293
|
+
matchCount
|
|
281
294
|
}
|
|
282
295
|
matches(request: {take: 25 ${heroId ? "heroIds:" + heroId : ""}}) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
296
|
+
id
|
|
297
|
+
rank
|
|
298
|
+
lobbyType
|
|
299
|
+
gameMode
|
|
300
|
+
startDateTime
|
|
301
|
+
durationSeconds
|
|
302
|
+
didRadiantWin
|
|
303
|
+
topLaneOutcome
|
|
304
|
+
midLaneOutcome
|
|
305
|
+
bottomLaneOutcome
|
|
306
|
+
radiantKills
|
|
307
|
+
direKills
|
|
308
|
+
players(steamAccountId: ${steamAccountId}) {
|
|
309
|
+
isRadiant
|
|
310
|
+
lane
|
|
311
|
+
kills
|
|
312
|
+
deaths
|
|
313
|
+
assists
|
|
314
|
+
position
|
|
315
|
+
award
|
|
316
|
+
imp
|
|
317
|
+
hero {
|
|
318
|
+
id
|
|
319
|
+
shortName
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
311
324
|
|
|
312
325
|
}
|
|
313
326
|
|
|
@@ -485,8 +498,14 @@ __name(HERO_MATCHUP_WINRATE, "HERO_MATCHUP_WINRATE");
|
|
|
485
498
|
|
|
486
499
|
// src/utils.ts
|
|
487
500
|
var CONFIGS = { STRATZ_API: { URL: "https://api.stratz.com/graphql", TOKEN: "" } };
|
|
501
|
+
var http = null;
|
|
502
|
+
function setHttp(newHttp) {
|
|
503
|
+
http = newHttp;
|
|
504
|
+
}
|
|
505
|
+
__name(setHttp, "setHttp");
|
|
488
506
|
async function query(query_str) {
|
|
489
|
-
return await
|
|
507
|
+
return await http.post(CONFIGS.STRATZ_API.URL, query_str, {
|
|
508
|
+
responseType: "json",
|
|
490
509
|
headers: {
|
|
491
510
|
"Content-Type": "application/graphql",
|
|
492
511
|
Authorization: `Bearer ${CONFIGS.STRATZ_API.TOKEN}`
|
|
@@ -494,12 +513,9 @@ async function query(query_str) {
|
|
|
494
513
|
});
|
|
495
514
|
}
|
|
496
515
|
__name(query, "query");
|
|
497
|
-
async function testGetHtml(URL) {
|
|
498
|
-
return await import_axios.default.get(URL);
|
|
499
|
-
}
|
|
500
|
-
__name(testGetHtml, "testGetHtml");
|
|
501
516
|
var ImageType = /* @__PURE__ */ ((ImageType2) => {
|
|
502
517
|
ImageType2["Icons"] = "icons";
|
|
518
|
+
ImageType2["IconsFacets"] = "icons/facets";
|
|
503
519
|
ImageType2["Heroes"] = "heroes";
|
|
504
520
|
ImageType2["HeroIcons"] = "heroes/icons";
|
|
505
521
|
ImageType2["Items"] = "items";
|
|
@@ -1108,8 +1124,8 @@ var ejs = __toESM(require("ejs"));
|
|
|
1108
1124
|
var name = "dota2tracker";
|
|
1109
1125
|
var usage = `
|
|
1110
1126
|
DOTA2Bot插件-提供自动追踪群友的最新对局的功能(需群友绑定),以及一系列查询功能。
|
|
1111
|
-
|
|
1112
|
-
var inject = ["
|
|
1127
|
+
**更多信息请进入插件主页(github本项目仓库)查看。**`;
|
|
1128
|
+
var inject = ["http", "database", "cron", "puppeteer"];
|
|
1113
1129
|
var Config = import_koishi.Schema.intersect([
|
|
1114
1130
|
import_koishi.Schema.object({
|
|
1115
1131
|
STRATZ_API_TOKEN: import_koishi.Schema.string().required().description("※必须。stratz.com的API TOKEN,可在 https://stratz.com/api 获取")
|
|
@@ -1134,6 +1150,7 @@ var pendingMatches = [];
|
|
|
1134
1150
|
var random = new import_koishi2.Random(() => Math.random());
|
|
1135
1151
|
async function apply(ctx, config) {
|
|
1136
1152
|
CONFIGS.STRATZ_API.TOKEN = config.STRATZ_API_TOKEN;
|
|
1153
|
+
setHttp(ctx.http);
|
|
1137
1154
|
ctx.command("订阅本群", "订阅后还需玩家在本群绑定SteamID").usage("订阅后还需玩家在本群绑定SteamID,BOT将订阅本群中已绑定玩家的新比赛数据,在STRATZ比赛解析完成后将比赛数据生成为图片战报发布至本群中。").action(async ({ session }) => {
|
|
1138
1155
|
if (session.guild) {
|
|
1139
1156
|
let currentGuild = (await ctx.database.get("dt_subscribed_guilds", { guildId: session.event.guild.id, platform: session.event.platform }))[0];
|
|
@@ -1233,16 +1250,21 @@ async function apply(ctx, config) {
|
|
|
1233
1250
|
if (subscribedPlayers.length <= 20) {
|
|
1234
1251
|
try {
|
|
1235
1252
|
const memberList = await session.bot.getGuildMemberList(session.event.guild.id);
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1253
|
+
async function getUsers(subscribedPlayers2, utils, queries, memberList2) {
|
|
1254
|
+
const playerSteamIds = subscribedPlayers2.map((player) => player.steamId);
|
|
1255
|
+
const queryResult = await utils.query(queries.PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD(playerSteamIds));
|
|
1256
|
+
const playersInfo = queryResult.data.players;
|
|
1257
|
+
const users2 = [];
|
|
1258
|
+
for (const subscribedPlayer of subscribedPlayers2) {
|
|
1259
|
+
const queryPlayer = playersInfo.find((player) => player.steamAccount.id == subscribedPlayer.steamId);
|
|
1260
|
+
const queryMember = memberList2.data.find((member) => member.user?.id == subscribedPlayer.userId);
|
|
1261
|
+
users2.push({ ...subscribedPlayer, ...queryPlayer, ...queryMember });
|
|
1262
|
+
}
|
|
1263
|
+
return users2;
|
|
1264
|
+
}
|
|
1265
|
+
__name(getUsers, "getUsers");
|
|
1266
|
+
const users = await getUsers(subscribedPlayers, utils_exports, queries_exports, memberList);
|
|
1267
|
+
session.send(await ctx.puppeteer.render(genImageHTML(users, "guild_member" /* GuildMember */, "guild_member" /* GuildMember */)));
|
|
1246
1268
|
} catch (error) {
|
|
1247
1269
|
ctx.logger.error(error);
|
|
1248
1270
|
session.send("查询群友失败。");
|
|
@@ -1258,10 +1280,7 @@ async function apply(ctx, config) {
|
|
|
1258
1280
|
match = queryLocal[0].data;
|
|
1259
1281
|
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1260
1282
|
} else {
|
|
1261
|
-
|
|
1262
|
-
if (queryRes.status == 200) {
|
|
1263
|
-
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1264
|
-
}
|
|
1283
|
+
match = getFormattedMatchData((await query(MATCH_INFO(matchId))).data.match);
|
|
1265
1284
|
}
|
|
1266
1285
|
if (match && (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(1, "hours")))) {
|
|
1267
1286
|
session.send(await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */)));
|
|
@@ -1309,8 +1328,7 @@ async function apply(ctx, config) {
|
|
|
1309
1328
|
let lastMatchId = 0;
|
|
1310
1329
|
try {
|
|
1311
1330
|
session.send("正在搜索对局详情,请稍后...");
|
|
1312
|
-
|
|
1313
|
-
lastMatchId = queryRes.data.data.players[0].matches[0].id;
|
|
1331
|
+
lastMatchId = (await query(PLAYERS_LASTMATCH([parseInt(flagBindedPlayer ? flagBindedPlayer.steamId : input_data)]))).data.players[0].matches[0].id;
|
|
1314
1332
|
} catch {
|
|
1315
1333
|
session.send("获取玩家最近比赛失败。");
|
|
1316
1334
|
return;
|
|
@@ -1338,46 +1356,38 @@ async function apply(ctx, config) {
|
|
|
1338
1356
|
let steamId = flagBindedPlayer?.steamId ?? input_data;
|
|
1339
1357
|
let player;
|
|
1340
1358
|
try {
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
if (b.level !== a.level) {
|
|
1374
|
-
return b.level - a.level;
|
|
1375
|
-
}
|
|
1376
|
-
return a.heroId - b.heroId;
|
|
1377
|
-
});
|
|
1378
|
-
player.heroesPerformanceTop10 = playerExtra.heroesPerformance.slice(0, 10);
|
|
1379
|
-
} else
|
|
1380
|
-
throw 0;
|
|
1359
|
+
player = (await query(PLAYER_INFO_WITH_25_MATCHES(steamId, hero?.id))).data.player;
|
|
1360
|
+
let playerExtra = (await query(PLAYER_EXTRA_INFO(steamId, player.matchCount, Object.keys(dotaconstants3.heroes).length, hero?.id))).data.player;
|
|
1361
|
+
let filteredDotaPlus = {};
|
|
1362
|
+
playerExtra.dotaPlus.forEach((item) => {
|
|
1363
|
+
if (!filteredDotaPlus[item.heroId] || filteredDotaPlus[item.heroId].level < item.level) {
|
|
1364
|
+
filteredDotaPlus[item.heroId] = {
|
|
1365
|
+
heroId: item.heroId,
|
|
1366
|
+
level: item.level
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
playerExtra.heroesPerformance.forEach((hero2) => {
|
|
1371
|
+
if (filteredDotaPlus[hero2.hero.id]) {
|
|
1372
|
+
filteredDotaPlus[hero2.hero.id].shortName = hero2.hero.shortName;
|
|
1373
|
+
filteredDotaPlus[hero2.hero.id].winCount = hero2.winCount;
|
|
1374
|
+
filteredDotaPlus[hero2.hero.id].matchCount = hero2.matchCount;
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1377
|
+
player.rank = {
|
|
1378
|
+
medal: parseInt(player.steamAccount.seasonRank?.toString().split("")[0] ?? 0),
|
|
1379
|
+
star: parseInt(player.steamAccount.seasonRank?.toString().split("")[1] ?? 0),
|
|
1380
|
+
leaderboard: player.steamAccount.seasonLeaderboardRank,
|
|
1381
|
+
inTop100: player.steamAccount.seasonLeaderboardRank ? player.steamAccount.seasonLeaderboardRank <= 10 ? "8c" : player.steamAccount.seasonLeaderboardRank <= 100 ? "8b" : void 0 : void 0
|
|
1382
|
+
};
|
|
1383
|
+
player.dotaPlus = Object.values(filteredDotaPlus);
|
|
1384
|
+
player.dotaPlus.sort((a, b) => {
|
|
1385
|
+
if (b.level !== a.level) {
|
|
1386
|
+
return b.level - a.level;
|
|
1387
|
+
}
|
|
1388
|
+
return a.heroId - b.heroId;
|
|
1389
|
+
});
|
|
1390
|
+
player.heroesPerformanceTop10 = playerExtra.heroesPerformance.slice(0, 10);
|
|
1381
1391
|
if (hero) {
|
|
1382
1392
|
const { matchCount, winCount, imp } = player.heroesPerformanceTop10[0];
|
|
1383
1393
|
player.matchCount = matchCount;
|
|
@@ -1395,37 +1405,23 @@ async function apply(ctx, config) {
|
|
|
1395
1405
|
});
|
|
1396
1406
|
ctx.command("查询英雄 <input_data>", "查询英雄技能/面板信息").usage("查询英雄的技能说明与各项数据,生成图片发布。\n参数可输入英雄ID、英雄名、英雄常用别名").example("-查询英雄 15").example("-查询英雄 雷泽").example("-查询英雄 电魂").action(async ({ session }, input_data) => {
|
|
1397
1407
|
if (input_data) {
|
|
1398
|
-
let
|
|
1399
|
-
if (!
|
|
1408
|
+
let fhero = findingHero(input_data);
|
|
1409
|
+
if (!fhero) {
|
|
1400
1410
|
session.send("未找到输入的英雄,请确认后重新输入。");
|
|
1401
1411
|
return;
|
|
1402
1412
|
}
|
|
1403
1413
|
try {
|
|
1404
1414
|
let AbilitiesConstantsCN;
|
|
1405
|
-
let
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
{ id: 1, data: AbilitiesConstantsCN, gameVersionId: queryConstants.gameVersions[0].id, gameVersionName: queryConstants.gameVersions[0].name }
|
|
1416
|
-
]);
|
|
1417
|
-
} else
|
|
1418
|
-
throw 0;
|
|
1419
|
-
}
|
|
1420
|
-
} else
|
|
1421
|
-
throw 0;
|
|
1422
|
-
let queryRes3 = await query(HERO_INFO(hero.id));
|
|
1423
|
-
if (queryRes3.status == 200) {
|
|
1424
|
-
let hero2 = queryRes3.data.data.constants.hero;
|
|
1425
|
-
hero2.talents.forEach((talent) => talent.name_cn = AbilitiesConstantsCN.data.abilities.find((item) => item.id == talent.abilityId).language.displayName);
|
|
1426
|
-
await session.send(await ctx.puppeteer.render(genImageHTML(hero2, config.template_hero, "hero" /* Hero */)));
|
|
1427
|
-
} else
|
|
1428
|
-
throw 0;
|
|
1415
|
+
let queryConstants = (await query(CURRENT_GAMEVERSION())).data.constants;
|
|
1416
|
+
AbilitiesConstantsCN = (await ctx.database.get("dt_constants_abilities_cn", [1]))[0];
|
|
1417
|
+
if (!AbilitiesConstantsCN || AbilitiesConstantsCN.gameVersionsId < queryConstants.gameVersions[0].id) {
|
|
1418
|
+
session.send("初次使用或版本更新,正在更新英雄技能数据中……");
|
|
1419
|
+
AbilitiesConstantsCN = { data: (await query(ALL_ABILITIES_CHINESE_NAME())).data.constants };
|
|
1420
|
+
await ctx.database.upsert("dt_constants_abilities_cn", (row) => [{ id: 1, data: AbilitiesConstantsCN, gameVersionId: queryConstants.gameVersions[0].id, gameVersionName: queryConstants.gameVersions[0].name }]);
|
|
1421
|
+
}
|
|
1422
|
+
let hero = (await query(HERO_INFO(fhero.id))).data.constants.hero;
|
|
1423
|
+
hero.talents.forEach((talent) => talent.name_cn = AbilitiesConstantsCN.data.abilities.find((item) => item.id == talent.abilityId).language.displayName);
|
|
1424
|
+
await session.send(await ctx.puppeteer.render(genImageHTML(hero, config.template_hero, "hero" /* Hero */)));
|
|
1429
1425
|
} catch (error) {
|
|
1430
1426
|
ctx.logger.error(error);
|
|
1431
1427
|
session.send("获取数据失败");
|
|
@@ -1443,24 +1439,21 @@ async function apply(ctx, config) {
|
|
|
1443
1439
|
return;
|
|
1444
1440
|
}
|
|
1445
1441
|
try {
|
|
1446
|
-
let
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
session.send(
|
|
1458
|
-
`你查询的英雄是${HEROES_CHINESE[heroStats.matchUp[0].heroId][0]}(ID:${heroStats.matchUp[0].heroId}),
|
|
1442
|
+
let heroStats = (await query(HERO_MATCHUP_WINRATE(hero.id))).data.heroStats;
|
|
1443
|
+
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) => {
|
|
1444
|
+
const winRate = item.winCount / item.matchCount;
|
|
1445
|
+
return { ...item, winRate: winRate.toFixed(3) };
|
|
1446
|
+
}).sort((a, b) => b.winRate - a.winRate).slice(0, Math.max(1, Math.min(Object.keys(dotaconstants3.heroes).length - 1, options.limit)));
|
|
1447
|
+
let vsBottomFive = heroStats.matchUp[0].vs.filter((item) => item.matchCount / heroStats.matchUp[0].matchCountVs > Math.max(0, Math.min(5, options.filter)) / 100).map((item) => {
|
|
1448
|
+
const winRate = item.winCount / item.matchCount;
|
|
1449
|
+
return { ...item, winRate: winRate.toFixed(3) };
|
|
1450
|
+
}).sort((a, b) => a.winRate - b.winRate).slice(0, Math.max(1, Math.min(Object.keys(dotaconstants3.heroes).length - 1, options.limit)));
|
|
1451
|
+
session.send(
|
|
1452
|
+
`你查询的英雄是${HEROES_CHINESE[heroStats.matchUp[0].heroId][0]}(ID:${heroStats.matchUp[0].heroId}),
|
|
1459
1453
|
以下是7天内传奇-万古分段比赛数据总结而来的搭档与克制关系
|
|
1460
1454
|
最佳搭档(组合胜率前${options.limit}):${withTopFive.map((item) => `${HEROES_CHINESE[item.heroId2][0]}(胜率${(item.winRate * 100).toFixed(1)}%)`).join("、")}
|
|
1461
1455
|
最佳克星(对抗胜率倒${options.limit}):${vsBottomFive.map((item) => `${HEROES_CHINESE[item.heroId2][0]}(胜率${(item.winRate * 100).toFixed(1)}%)`).join("、")}`
|
|
1462
|
-
|
|
1463
|
-
}
|
|
1456
|
+
);
|
|
1464
1457
|
} catch (error) {
|
|
1465
1458
|
ctx.logger.error(error);
|
|
1466
1459
|
session.send("获取数据失败");
|
|
@@ -1532,7 +1525,6 @@ async function apply(ctx, config) {
|
|
|
1532
1525
|
});
|
|
1533
1526
|
heroes3.push({ id: 0, data: result.remainingContent });
|
|
1534
1527
|
await ctx.database.upsert("dt_7_36", (row) => heroes3);
|
|
1535
|
-
import_fs2.default.writeFileSync("./node_modules/@sjtdev/koishi-plugin-dota2tracker/remainingContent.html", result.remainingContent);
|
|
1536
1528
|
await session.send("数据获取完成。");
|
|
1537
1529
|
await page.close();
|
|
1538
1530
|
}
|
|
@@ -1616,13 +1608,12 @@ async function apply(ctx, config) {
|
|
|
1616
1608
|
const oneDayAgo = (0, import_moment.default)().subtract(1, "days").unix();
|
|
1617
1609
|
const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
|
|
1618
1610
|
const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
|
|
1619
|
-
|
|
1611
|
+
const players = (await query(
|
|
1620
1612
|
MATCHES_FOR_DAILY(
|
|
1621
1613
|
subscribedPlayersInGuild.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index),
|
|
1622
1614
|
oneDayAgo
|
|
1623
1615
|
)
|
|
1624
|
-
);
|
|
1625
|
-
const players = queryRes.data.data.players.filter((player) => player.matches.length > 0);
|
|
1616
|
+
)).data.players.filter((player) => player.matches.length > 0);
|
|
1626
1617
|
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
1627
1618
|
for (let subPlayer of subscribedPlayersInGuild) {
|
|
1628
1619
|
let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
|
|
@@ -1687,14 +1678,12 @@ async function apply(ctx, config) {
|
|
|
1687
1678
|
const subscribedGuilds = await ctx.database.get("dt_subscribed_guilds", void 0);
|
|
1688
1679
|
const subscribedPlayersInGuild = (await ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedGuilds.some((guild) => guild.guildId == player.guildId));
|
|
1689
1680
|
if (subscribedPlayersInGuild.length > 0) {
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
})
|
|
1695
|
-
)
|
|
1681
|
+
const subscribedPlayersSteamIds = PLAYERS_LASTMATCH(
|
|
1682
|
+
subscribedPlayersInGuild.map((player) => player.steamId).filter(function(value, index, self) {
|
|
1683
|
+
return self.indexOf(value) === index;
|
|
1684
|
+
})
|
|
1696
1685
|
);
|
|
1697
|
-
const lastMatches =
|
|
1686
|
+
const lastMatches = (await query(subscribedPlayersSteamIds)).data.players.map((player) => player.matches[0]).filter((item, index, self) => index === self.findIndex((t) => t.id === item.id)).filter((match) => import_moment.default.unix(match.startDateTime).isAfter((0, import_moment.default)().subtract(1, "days"))).filter((match) => !pendingMatches.some((pendingMatch) => pendingMatch.matchId == match.id));
|
|
1698
1687
|
const sendedMatchesIds = (await ctx.database.get("dt_sended_match_id", { matchId: lastMatches.map((match) => match.id) }, ["matchId"])).map((match) => match.matchId);
|
|
1699
1688
|
lastMatches.filter((match) => !sendedMatchesIds.includes(match.id)).forEach((match) => {
|
|
1700
1689
|
const tempGuilds = [];
|
|
@@ -1722,12 +1711,8 @@ async function apply(ctx, config) {
|
|
|
1722
1711
|
if (queryLocal.length > 0) {
|
|
1723
1712
|
match = queryLocal[0].data;
|
|
1724
1713
|
ctx.database.set("dt_previous_query_results", match.id, { queryTime: /* @__PURE__ */ new Date() });
|
|
1725
|
-
} else
|
|
1726
|
-
|
|
1727
|
-
if (queryRes.status == 200) {
|
|
1728
|
-
match = getFormattedMatchData(queryRes.data.data.match);
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1714
|
+
} else
|
|
1715
|
+
match = getFormattedMatchData((await query(MATCH_INFO(pendingMatch.matchId))).data.match);
|
|
1731
1716
|
if (match.parsedDateTime || import_moment.default.unix(match.endDateTime).isBefore((0, import_moment.default)().subtract(1, "hours"))) {
|
|
1732
1717
|
pendingMatches = pendingMatches.filter((item) => item.matchId != match.id);
|
|
1733
1718
|
const img = await ctx.puppeteer.render(genImageHTML(match, config.template_match, "match" /* Match */));
|
|
@@ -1753,7 +1738,7 @@ KDA:${((player.kills + player.assists) / (player.deaths || 1)).toFixed(2)} [${
|
|
|
1753
1738
|
broadMatchMessage += broadPlayerMessage + "\n";
|
|
1754
1739
|
}
|
|
1755
1740
|
await ctx.broadcast([`${commingGuild.platform}:${commingGuild.guildId}`], broadMatchMessage + img);
|
|
1756
|
-
ctx.logger.info(
|
|
1741
|
+
ctx.logger.info(`${match.id}${match.parsedDateTime ? "已解析," : "已结束超过1小时仍未被解析,放弃解析直接"}生成图片并发布于${commingGuild.platform}:${commingGuild.guildId}。`);
|
|
1757
1742
|
}
|
|
1758
1743
|
if (match.parsedDateTime)
|
|
1759
1744
|
ctx.database.upsert("dt_previous_query_results", (row) => [{ matchId: match.id, data: match, queryTime: /* @__PURE__ */ new Date() }]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjtdev/koishi-plugin-dota2tracker",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.8-beta.1",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"dota2"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"axios": "^1.6.8",
|
|
30
29
|
"dotaconstants": "^8.5.0",
|
|
31
30
|
"ejs": "^3.1.10",
|
|
32
31
|
"moment": "^2.30.1"
|
|
@@ -385,13 +385,13 @@
|
|
|
385
385
|
|
|
386
386
|
player.positionPerformance=[];
|
|
387
387
|
// 瞎j8定义的各位置代表物品,以后看情况调整
|
|
388
|
-
const
|
|
388
|
+
const positionIcons = ["damage","nuke","armor","speed","healing"];
|
|
389
389
|
for (let index = 0; index < 5; index++) {
|
|
390
390
|
let currentPositionMatches = player.matches.filter(match=>match.players[0].position == ("POSITION_"+(index+1)))
|
|
391
391
|
let winCount = currentPositionMatches.filter(match=>match.didRadiantWin == match.players[0].isRadiant).length;
|
|
392
392
|
player.positionPerformance.push({
|
|
393
393
|
position : (index + 1),
|
|
394
|
-
icon :
|
|
394
|
+
icon : positionIcons[index],
|
|
395
395
|
matchCount : currentPositionMatches.length,
|
|
396
396
|
winCount : winCount,
|
|
397
397
|
loseCount : currentPositionMatches.length - winCount,
|
|
@@ -468,7 +468,7 @@
|
|
|
468
468
|
<span class="tip lose_count" style="justify-self: start; margin-left: 2px">败场</span>
|
|
469
469
|
<%- player.positionPerformance
|
|
470
470
|
.map((position) => `
|
|
471
|
-
<span><img src="${utils.getImageUrl(position.icon,ImageType.
|
|
471
|
+
<span><img src="${utils.getImageUrl(position.icon,ImageType.IconsFacets)}"></span>
|
|
472
472
|
<span class="count">${position.matchCount}</span>
|
|
473
473
|
<span class="win_rate">${position.matchCount>0?(((position.winCount / position.matchCount) * 100).toFixed(0)):"-"}%</span>
|
|
474
474
|
<span class="imp">${(position.imp > 0 ? "+" : "") + position.imp}</span>
|