@sjtdev/koishi-plugin-dota2tracker 2.5.3 → 2.5.4
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 +10 -0
- package/lib/index.js +98 -34
- package/package.json +1 -1
package/changelog.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
### [2.5.4](https://github.com/sjtdev/koishi-plugin-dota2tracker/compare/v2.5.3...v2.5.4) (2026-02-26)
|
|
4
|
+
|
|
5
|
+
### 🚀 功能优化
|
|
6
|
+
|
|
7
|
+
* **database:** 增加缓存群友列表机制,加入对拉取有效群友时的检测,每小时更新缓存 ([1ac1df9](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/1ac1df9513a883b17031fdc3e912fccc0af8a3e2)), closes [#17](https://github.com/sjtdev/koishi-plugin-dota2tracker/issues/17)
|
|
8
|
+
|
|
9
|
+
### 🐛 Bug 修复
|
|
10
|
+
|
|
11
|
+
* **match-watcher:** 修复无有效群友时还会发送查询请求 ([a8d1e8c](https://github.com/sjtdev/koishi-plugin-dota2tracker/commit/a8d1e8c173d71b850516912729e398943d3ea391))
|
|
12
|
+
|
|
3
13
|
### [2.5.3](https://github.com/sjtdev/koishi-plugin-dota2tracker/compare/v2.5.2...v2.5.3) (2026-02-23)
|
|
4
14
|
|
|
5
15
|
### 🎨 样式
|
package/lib/index.js
CHANGED
|
@@ -2313,13 +2313,13 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2313
2313
|
}
|
|
2314
2314
|
constructor(ctx) {
|
|
2315
2315
|
super(ctx, "dota2tracker.database", true);
|
|
2316
|
-
ctx.model.extend("dt_subscribed_guilds", { id: "unsigned",
|
|
2316
|
+
ctx.model.extend("dt_subscribed_guilds", { id: "unsigned", channelId: { type: "string", legacy: ["guildId"] }, platform: "string" }, { autoInc: true });
|
|
2317
2317
|
ctx.model.extend(
|
|
2318
2318
|
"dt_subscribed_players",
|
|
2319
2319
|
{
|
|
2320
2320
|
id: "unsigned",
|
|
2321
2321
|
userId: "string",
|
|
2322
|
-
|
|
2322
|
+
channelId: { type: "string", legacy: ["guildId"] },
|
|
2323
2323
|
platform: "string",
|
|
2324
2324
|
steamId: "integer",
|
|
2325
2325
|
nickName: "string",
|
|
@@ -2328,6 +2328,62 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2328
2328
|
{ autoInc: true }
|
|
2329
2329
|
);
|
|
2330
2330
|
ctx.model.extend("dt_match_extension", { matchId: "string", startTime: "timestamp", data: "json" }, { autoInc: false, primary: ["matchId"] });
|
|
2331
|
+
ctx.cron("0 * * * *", async () => {
|
|
2332
|
+
await this.refreshAllGuildMemberCaches();
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
/** 群成员列表内存缓存: Map<"platform:channelId", Set<userId>> */
|
|
2336
|
+
guildMemberCache = /* @__PURE__ */ new Map();
|
|
2337
|
+
/**
|
|
2338
|
+
* 刷新指定频道的群成员缓存。
|
|
2339
|
+
* 通过 channel 表获取 assignee(bot selfId),再调用 bot.getGuildMemberList。
|
|
2340
|
+
* 失败时记录 warn 并清除该 key(保守策略)。
|
|
2341
|
+
*/
|
|
2342
|
+
async refreshGuildMemberCache(platform, channelId) {
|
|
2343
|
+
const cacheKey = `${platform}:${channelId}`;
|
|
2344
|
+
try {
|
|
2345
|
+
const channelRow = (await this.ctx.database.get("channel", { id: channelId })).at(0);
|
|
2346
|
+
const selfId = channelRow?.assignee;
|
|
2347
|
+
const guildId = channelRow?.guildId ?? channelId;
|
|
2348
|
+
if (!selfId) {
|
|
2349
|
+
this.guildMemberCache.delete(cacheKey);
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
const bot = this.ctx.bots[`${platform}:${selfId}`];
|
|
2353
|
+
if (!bot) {
|
|
2354
|
+
this.guildMemberCache.delete(cacheKey);
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
const members = await bot.getGuildMemberList(guildId);
|
|
2358
|
+
const userIds = new Set(members.data.map((m) => m.user.id));
|
|
2359
|
+
this.guildMemberCache.set(cacheKey, userIds);
|
|
2360
|
+
} catch (error) {
|
|
2361
|
+
this.logger.warn(`获取频道 ${cacheKey} 成员列表失败,已清除对应缓存:` + error);
|
|
2362
|
+
this.guildMemberCache.delete(cacheKey);
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
/** 全量刷新所有已订阅频道的群成员缓存(每小时 cron 调用) */
|
|
2366
|
+
async refreshAllGuildMemberCaches() {
|
|
2367
|
+
const subscribedChannels = await this.ctx.database.get("dt_subscribed_guilds", void 0);
|
|
2368
|
+
await Promise.allSettled(subscribedChannels.map((ch) => this.refreshGuildMemberCache(ch.platform, ch.channelId)));
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2371
|
+
* 判断玩家是否仍在群组中。
|
|
2372
|
+
* 缓存未命中(冷启动阶段)时保守放行,返回 true。
|
|
2373
|
+
*/
|
|
2374
|
+
isPlayerInGuild(platform, channelId, userId) {
|
|
2375
|
+
const cached = this.guildMemberCache.get(`${platform}:${channelId}`);
|
|
2376
|
+
if (!cached) return true;
|
|
2377
|
+
return cached.has(userId);
|
|
2378
|
+
}
|
|
2379
|
+
/** 删除指定频道的群成员缓存(取消订阅时内部调用) */
|
|
2380
|
+
deleteGuildMemberCache(platform, channelId) {
|
|
2381
|
+
this.guildMemberCache.delete(`${platform}:${channelId}`);
|
|
2382
|
+
}
|
|
2383
|
+
/** 从缓存中移除单个用户(取消绑定时内部调用,保留频道内其他成员的缓存)*/
|
|
2384
|
+
removeUserFromGuildMemberCache(platform, channelId, userId) {
|
|
2385
|
+
const cached = this.guildMemberCache.get(`${platform}:${channelId}`);
|
|
2386
|
+
if (cached) cached.delete(userId);
|
|
2331
2387
|
}
|
|
2332
2388
|
async insertMatchExtension(matchId, startTime, data) {
|
|
2333
2389
|
return this.ctx.database.upsert("dt_match_extension", [{ matchId: String(matchId), startTime, data }]);
|
|
@@ -2345,9 +2401,8 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2345
2401
|
return this.ctx.database.set("dt_subscribed_players", playerId, { rank });
|
|
2346
2402
|
}
|
|
2347
2403
|
async getActiveSubscribedPlayers() {
|
|
2348
|
-
const
|
|
2349
|
-
|
|
2350
|
-
return subscribedPlayersInGuild;
|
|
2404
|
+
const subscribedChannels = await this.ctx.database.get("dt_subscribed_guilds", void 0);
|
|
2405
|
+
return (await this.ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedChannels.some((ch) => ch.channelId == player.channelId)).filter((player) => this.isPlayerInGuild(player.platform, player.channelId, player.userId));
|
|
2351
2406
|
}
|
|
2352
2407
|
async isUserBinded(session) {
|
|
2353
2408
|
const subscribedPlayer = await this.ctx.database.get("dt_subscribed_players", this.getUserQuery(session));
|
|
@@ -2358,23 +2413,32 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2358
2413
|
return subscribedPlayer.length > 0 ? subscribedPlayer[0] : null;
|
|
2359
2414
|
}
|
|
2360
2415
|
async bindUser(session, steamId, nickName) {
|
|
2361
|
-
|
|
2416
|
+
const result = await this.ctx.database.create("dt_subscribed_players", {
|
|
2362
2417
|
...this.getUserQuery(session),
|
|
2363
2418
|
steamId: Number(steamId),
|
|
2364
2419
|
nickName: nickName || ""
|
|
2365
2420
|
});
|
|
2421
|
+
this.refreshGuildMemberCache(session.event.platform, session.event.channel.id);
|
|
2422
|
+
return result;
|
|
2366
2423
|
}
|
|
2367
2424
|
async unbindUser(session) {
|
|
2425
|
+
this.removeUserFromGuildMemberCache(session.event.platform, session.event.channel.id, session.event.user.id);
|
|
2368
2426
|
return this.ctx.database.remove("dt_subscribed_players", this.getUserQuery(session));
|
|
2369
2427
|
}
|
|
2428
|
+
async renamePlayer(playerId, nickName) {
|
|
2429
|
+
return this.ctx.database.set("dt_subscribed_players", playerId, { nickName });
|
|
2430
|
+
}
|
|
2370
2431
|
async isChannelSubscribed(session) {
|
|
2371
2432
|
const subscribedChannels = await this.ctx.database.get("dt_subscribed_guilds", this.getChannelQuery(session));
|
|
2372
2433
|
return subscribedChannels.length > 0;
|
|
2373
2434
|
}
|
|
2374
2435
|
async subscribeChannel(session) {
|
|
2375
|
-
|
|
2436
|
+
const result = await this.ctx.database.create("dt_subscribed_guilds", this.getChannelQuery(session));
|
|
2437
|
+
this.refreshGuildMemberCache(session.event.platform, session.event.channel.id);
|
|
2438
|
+
return result;
|
|
2376
2439
|
}
|
|
2377
2440
|
async unSubscribeChannel(session) {
|
|
2441
|
+
this.deleteGuildMemberCache(session.event.platform, session.event.channel.id);
|
|
2378
2442
|
return this.ctx.database.remove("dt_subscribed_guilds", this.getChannelQuery(session));
|
|
2379
2443
|
}
|
|
2380
2444
|
async getSubscribedMembersInChannel(session) {
|
|
@@ -2385,13 +2449,13 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2385
2449
|
*/
|
|
2386
2450
|
getChannelQuery(session) {
|
|
2387
2451
|
return {
|
|
2388
|
-
|
|
2452
|
+
channelId: session.event.channel.id,
|
|
2389
2453
|
platform: session.event.platform
|
|
2390
2454
|
};
|
|
2391
2455
|
}
|
|
2392
2456
|
getUserQuery(session) {
|
|
2393
2457
|
return {
|
|
2394
|
-
|
|
2458
|
+
channelId: session.event.channel.id,
|
|
2395
2459
|
platform: session.event.platform,
|
|
2396
2460
|
userId: session.event.user.id
|
|
2397
2461
|
};
|
|
@@ -2399,14 +2463,14 @@ var DatabaseService = class extends import_koishi7.Service {
|
|
|
2399
2463
|
/** 从已订阅玩家中查找玩家返回SteamId,不需要以昵称匹配时仅需传入Session */
|
|
2400
2464
|
async getSubscribedPlayerByNickNameOrSession(session, nickName) {
|
|
2401
2465
|
const player = (await this.ctx.database.get("dt_subscribed_players", {
|
|
2402
|
-
|
|
2466
|
+
channelId: session.event.channel.id,
|
|
2403
2467
|
platform: session.event.platform,
|
|
2404
2468
|
...nickName ? { nickName } : { userId: session.event.user.id }
|
|
2405
2469
|
}))?.[0];
|
|
2406
2470
|
return player;
|
|
2407
2471
|
}
|
|
2408
|
-
getChannelInfo({ platform,
|
|
2409
|
-
return `${platform}:${
|
|
2472
|
+
getChannelInfo({ platform, channelId }) {
|
|
2473
|
+
return `${platform}:${channelId}`;
|
|
2410
2474
|
}
|
|
2411
2475
|
};
|
|
2412
2476
|
|
|
@@ -3301,6 +3365,7 @@ var MatchWatcherTask = class extends import_koishi13.Service {
|
|
|
3301
3365
|
async discovery() {
|
|
3302
3366
|
try {
|
|
3303
3367
|
const activePlayers = await this.ctx.dota2tracker.database.getActiveSubscribedPlayers();
|
|
3368
|
+
if (activePlayers.length === 0) return;
|
|
3304
3369
|
const uniqueSteamIds = activePlayers.map((player) => player.steamId).filter((steamId, index, self) => self.indexOf(steamId) === index);
|
|
3305
3370
|
const playersData = (await this.ctx.dota2tracker.stratzAPI.queryPlayersLastMatchRankInfo({ steamAccountIds: uniqueSteamIds })).players;
|
|
3306
3371
|
await this.discoverNewMatches(playersData, activePlayers);
|
|
@@ -3320,10 +3385,10 @@ var MatchWatcherTask = class extends import_koishi13.Service {
|
|
|
3320
3385
|
}
|
|
3321
3386
|
const playersByGuild = /* @__PURE__ */ new Map();
|
|
3322
3387
|
for (const player of relevantActivePlayers) {
|
|
3323
|
-
const guildKey = `${player.platform}:${player.
|
|
3388
|
+
const guildKey = `${player.platform}:${player.channelId}`;
|
|
3324
3389
|
if (!playersByGuild.has(guildKey)) {
|
|
3325
3390
|
playersByGuild.set(guildKey, {
|
|
3326
|
-
guildInfo: { platform: player.platform, channelId: player.
|
|
3391
|
+
guildInfo: { platform: player.platform, channelId: player.channelId },
|
|
3327
3392
|
players: []
|
|
3328
3393
|
});
|
|
3329
3394
|
}
|
|
@@ -3344,7 +3409,7 @@ var MatchWatcherTask = class extends import_koishi13.Service {
|
|
|
3344
3409
|
});
|
|
3345
3410
|
messageToLogger.push({
|
|
3346
3411
|
platform: guildInfo.platform,
|
|
3347
|
-
guildId: guildInfo.
|
|
3412
|
+
guildId: guildInfo.channelId,
|
|
3348
3413
|
players
|
|
3349
3414
|
});
|
|
3350
3415
|
subscribers.push(subscriber);
|
|
@@ -3381,12 +3446,12 @@ var MatchWatcherTask = class extends import_koishi13.Service {
|
|
|
3381
3446
|
if (prevRank.medal !== currRank.medal || prevRank.star !== currRank.star && this.config.rankBroadStar || prevRank.leader !== currRank.leader && this.config.rankBroadLeader) {
|
|
3382
3447
|
let guildMember;
|
|
3383
3448
|
try {
|
|
3384
|
-
guildMember = await this.ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember?.(subPlayer.
|
|
3449
|
+
guildMember = await this.ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember?.(subPlayer.channelId, subPlayer.userId);
|
|
3385
3450
|
} catch (error) {
|
|
3386
3451
|
this.logger.warn(this.ctx.dota2tracker.i18n.gt("dota2tracker.logger.fetch_guilds_failed") + error);
|
|
3387
3452
|
}
|
|
3388
3453
|
const name2 = subPlayer.nickName ?? guildMember?.nick ?? playersData.find((player) => player.steamAccount.id == subPlayer.steamId)?.steamAccount.name ?? String(subPlayer.steamId);
|
|
3389
|
-
const languageTag = await this.ctx.dota2tracker.i18n.getLanguageTag({ channelId: subPlayer.
|
|
3454
|
+
const languageTag = await this.ctx.dota2tracker.i18n.getLanguageTag({ channelId: subPlayer.channelId });
|
|
3390
3455
|
if (this.config.rankBroadFun === true) {
|
|
3391
3456
|
const img = await this.ctx.dota2tracker.view.renderToImageByFile(
|
|
3392
3457
|
{
|
|
@@ -3401,13 +3466,13 @@ var MatchWatcherTask = class extends import_koishi13.Service {
|
|
|
3401
3466
|
"rank" /* Rank */,
|
|
3402
3467
|
languageTag
|
|
3403
3468
|
);
|
|
3404
|
-
await this.ctx.broadcast([`${subPlayer.platform}:${subPlayer.
|
|
3469
|
+
await this.ctx.broadcast([`${subPlayer.platform}:${subPlayer.channelId}`], img);
|
|
3405
3470
|
} else {
|
|
3406
3471
|
const message = this.ctx.dota2tracker.messageBuilder.buildRankChangedMessage(languageTag, name2, prevRank, currRank);
|
|
3407
|
-
await this.ctx.broadcast([`${subPlayer.platform}:${subPlayer.
|
|
3472
|
+
await this.ctx.broadcast([`${subPlayer.platform}:${subPlayer.channelId}`], message);
|
|
3408
3473
|
}
|
|
3409
3474
|
this.ctx.dota2tracker.database.setPlayerRank(subPlayer.id, rankMap.get(subPlayer.steamId));
|
|
3410
|
-
this.logger.info(this.ctx.dota2tracker.i18n.gt("dota2tracker.logger.rank_sent", { platform: subPlayer.platform, guildId: subPlayer.
|
|
3475
|
+
this.logger.info(this.ctx.dota2tracker.i18n.gt("dota2tracker.logger.rank_sent", { platform: subPlayer.platform, guildId: subPlayer.channelId, player: { nickName: subPlayer.nickName, steamId: subPlayer.steamId } }));
|
|
3411
3476
|
}
|
|
3412
3477
|
} else {
|
|
3413
3478
|
this.ctx.dota2tracker.database.setPlayerRank(subPlayer.id, rankMap.get(subPlayer.steamId));
|
|
@@ -3451,8 +3516,7 @@ var ParsePollingTask = class extends import_koishi14.Service {
|
|
|
3451
3516
|
source: "AUTOMATIC",
|
|
3452
3517
|
type: "CHANNEL",
|
|
3453
3518
|
platform: target.platform,
|
|
3454
|
-
channelId: target.channelId
|
|
3455
|
-
guildId: target.guildId
|
|
3519
|
+
channelId: target.channelId
|
|
3456
3520
|
};
|
|
3457
3521
|
}
|
|
3458
3522
|
add(matchId, subscribers) {
|
|
@@ -3591,12 +3655,12 @@ var DailyReportTask = class extends import_koishi15.Service {
|
|
|
3591
3655
|
}
|
|
3592
3656
|
}
|
|
3593
3657
|
async report_legacy(timeAgo, titleKey, showCombi) {
|
|
3594
|
-
const
|
|
3595
|
-
const
|
|
3596
|
-
const steamIds =
|
|
3658
|
+
const subscribedChannels = await this.ctx.database.get("dt_subscribed_guilds", void 0);
|
|
3659
|
+
const subscribedPlayersInChannel = (await this.ctx.database.get("dt_subscribed_players", void 0)).filter((player) => subscribedChannels.some((ch) => ch.channelId == player.channelId));
|
|
3660
|
+
const steamIds = subscribedPlayersInChannel.map((player) => player.steamId).filter((value, index, self) => self.indexOf(value) === index);
|
|
3597
3661
|
const players = (await this.ctx.dota2tracker.stratzAPI.queryPlayersMatchesForDaily_legacy(steamIds, timeAgo)).players.filter((player) => player.matches?.length > 0);
|
|
3598
3662
|
const matches = players.map((player) => player.matches.map((match) => match)).flat().filter((item, index, self) => index === self.findIndex((t) => t.id === item.id));
|
|
3599
|
-
for (let subPlayer of
|
|
3663
|
+
for (let subPlayer of subscribedPlayersInChannel) {
|
|
3600
3664
|
let player = players.find((player2) => subPlayer.steamId == player2.steamAccount.id);
|
|
3601
3665
|
if (!player) continue;
|
|
3602
3666
|
let guildMember;
|
|
@@ -3615,8 +3679,8 @@ var DailyReportTask = class extends import_koishi15.Service {
|
|
|
3615
3679
|
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);
|
|
3616
3680
|
subPlayer = Object.assign(subPlayer, player);
|
|
3617
3681
|
}
|
|
3618
|
-
for (let
|
|
3619
|
-
const currentsubscribedPlayers =
|
|
3682
|
+
for (let channel of subscribedChannels) {
|
|
3683
|
+
const currentsubscribedPlayers = subscribedPlayersInChannel.filter((player) => player.platform == channel.platform && player.channelId == channel.channelId && player.matches?.length);
|
|
3620
3684
|
if (currentsubscribedPlayers.length) {
|
|
3621
3685
|
const currentsubscribedPlayersIds = currentsubscribedPlayers.map((player) => player.steamId);
|
|
3622
3686
|
const combinationsMap = /* @__PURE__ */ new Map();
|
|
@@ -3642,9 +3706,9 @@ var DailyReportTask = class extends import_koishi15.Service {
|
|
|
3642
3706
|
});
|
|
3643
3707
|
const combinations = Array.from(combinationsMap.values());
|
|
3644
3708
|
try {
|
|
3645
|
-
const languageTag = await this.ctx.dota2tracker.i18n.getLanguageTag({ channelId:
|
|
3709
|
+
const languageTag = await this.ctx.dota2tracker.i18n.getLanguageTag({ channelId: channel.channelId });
|
|
3646
3710
|
await this.ctx.broadcast(
|
|
3647
|
-
[`${
|
|
3711
|
+
[`${channel.platform}:${channel.channelId}`],
|
|
3648
3712
|
await this.ctx.dota2tracker.view.renderToImageByFile(
|
|
3649
3713
|
{
|
|
3650
3714
|
title: this.ctx.dota2tracker.i18n.$t(languageTag, titleKey),
|
|
@@ -3661,7 +3725,7 @@ var DailyReportTask = class extends import_koishi15.Service {
|
|
|
3661
3725
|
languageTag
|
|
3662
3726
|
)
|
|
3663
3727
|
);
|
|
3664
|
-
this.logger.info(this.ctx.dota2tracker.i18n.gt("dota2tracker.logger.report_sent", { title: this.ctx.dota2tracker.i18n.$t(languageTag, titleKey), guildId:
|
|
3728
|
+
this.logger.info(this.ctx.dota2tracker.i18n.gt("dota2tracker.logger.report_sent", { title: this.ctx.dota2tracker.i18n.$t(languageTag, titleKey), guildId: channel.channelId, platform: channel.platform }));
|
|
3665
3729
|
} catch (error) {
|
|
3666
3730
|
this.logger.error(error);
|
|
3667
3731
|
}
|
|
@@ -4025,7 +4089,7 @@ function registerUserCommand(ctx) {
|
|
|
4025
4089
|
if (!session.isDirect) {
|
|
4026
4090
|
const sessionPlayer = await ctx.dota2tracker.database.getBindedUser(session);
|
|
4027
4091
|
if (sessionPlayer) {
|
|
4028
|
-
|
|
4092
|
+
ctx.dota2tracker.database.unbindUser(session);
|
|
4029
4093
|
return session.text(".unbind_success");
|
|
4030
4094
|
} else {
|
|
4031
4095
|
return session.text(".not_binded");
|
|
@@ -4045,7 +4109,7 @@ function registerUserCommand(ctx) {
|
|
|
4045
4109
|
if (nick_name === sessionPlayer.nickName) {
|
|
4046
4110
|
return session.text(".nick_name_same");
|
|
4047
4111
|
}
|
|
4048
|
-
await ctx.database.
|
|
4112
|
+
await ctx.dota2tracker.database.renamePlayer(sessionPlayer.id, nick_name);
|
|
4049
4113
|
return session.text(".rename_success", { nick_name });
|
|
4050
4114
|
} else {
|
|
4051
4115
|
return session.text(".not_binded");
|
|
@@ -4683,7 +4747,7 @@ var DailyReportService = class _DailyReportService extends import_koishi18.Servi
|
|
|
4683
4747
|
static groupUsersByChannel(users) {
|
|
4684
4748
|
const groups = /* @__PURE__ */ new Map();
|
|
4685
4749
|
for (const user of users) {
|
|
4686
|
-
const key = `${user.platform}:${user.
|
|
4750
|
+
const key = `${user.platform}:${user.channelId}`;
|
|
4687
4751
|
if (!groups.has(key)) groups.set(key, []);
|
|
4688
4752
|
groups.get(key).push(user);
|
|
4689
4753
|
}
|
package/package.json
CHANGED