如何通过Discord Bot获取用户的游戏时长?
优化Discord游戏时长追踪的实现方案
嘿,你的思路其实完全没问题——通过presenceUpdate事件对比新旧状态来捕捉用户结束游戏的时刻,是追踪游戏时长的核心逻辑,但确实可以让代码更简洁高效一些。我来分享几个优化方向:
1. 简化activityDiff函数,提升效率
你原来的实现用indexOf查找活动ID,在活动数量多的时候效率会偏低。可以用Set来存储新活动的ID,利用Set.has()的O(1)查找速度来优化,同时用数组的filter方法替代forEach,让代码更简洁:
activityDiff(oldPresence, newPresence) { if (!oldPresence) return []; const newActivityIds = new Set(newPresence.activities.map(a => a.id)); return oldPresence.activities.filter(activity => activity.type === "PLAYING" && !newActivityIds.has(activity.id) ); }
2. 简化时长计算逻辑
计算时长的部分可以更紧凑,同时用Math.floor替代parseInt(效果一致,但语义更清晰):
const finishedActivities = this.activityDiff(oldPresence, newPresence); for (const activity of finishedActivities) { const durationSeconds = Math.floor((Date.now() - activity.createdTimestamp) / 1000); // 这里可以把时长数据存入数据库或进行其他处理 }
额外注意点
- 如果你使用的是较新版本的Discord.js,活动对象里的
timestamps.start和activity.createdTimestamp是等价的,用哪个都可以;不过用户主动退出游戏时,timestamps.end通常不会被Discord返回,所以还是用Date.now()作为结束时间更可靠。 - 要考虑用户中途切换游戏的场景:此时旧游戏的活动会被移除,新游戏的活动会加入,你的代码已经能正确捕捉到旧游戏的结束事件,这部分逻辑是没问题的。
- 偶尔可能会遇到Discord推送重复presence更新的情况,可以考虑给每个结束的活动加个去重判断(比如记录已处理过的活动ID),避免重复统计时长。
有没有更“简便”的方法?其实核心逻辑绕不开对比新旧presence——毕竟Discord没有直接提供“用户结束游戏”的专属事件,所以优化现有代码就是最直接的简便方案啦。
内容的提问来源于stack exchange,提问作者clzola
相关产品推荐
相关产品推荐

