feat: Add streak tracking and notifications for friends' match results

This commit is contained in:
Ching L 2025-03-13 16:30:40 +08:00
parent 2bc72ad3b3
commit 49843ba4d2
2 changed files with 91 additions and 1 deletions

View File

@ -42,13 +42,26 @@ async def send_message(channel):
try:
matches = dota.get_friends_recent_matches()
except:
# 获取连胜连败消息
streak_notifications = dota.check_streaks()
except Exception as e:
logger.error(f"Error in send_message task: {e}")
return
for match_ in matches:
data = await dota.serialize_match_for_discord(match_)
logger.info(f"sending match {match_['match_id']}, {data}")
try:
# 发送比赛结果
await channel.send(content=data['content'], embeds=[discord.Embed.from_dict(embed) for embed in data['embeds']])
# 如果有连胜连败消息,一并发送
if streak_notifications:
for notification in streak_notifications:
await channel.send(content=notification)
# 发送后清空通知列表,避免重复发送
streak_notifications = []
except Exception as e:
logger.error(f"send match error {e}")

77
dota.py
View File

@ -91,6 +91,9 @@ class Friend(BaseModel):
name = peewee.CharField()
active = peewee.BooleanField(default=True)
rank_tier = peewee.IntegerField(null=True)
win_streak = peewee.IntegerField(default=0) # 连胜计数
loss_streak = peewee.IntegerField(default=0) # 连败计数
last_match_id = peewee.IntegerField(null=True) # 上一场比赛ID用于避免重复计算
def get_recent_matches(self, limit=1):
try:
@ -214,9 +217,45 @@ class Friend(BaseModel):
return data
def update_streak(self, match_id, win):
"""更新连胜连败计数"""
# 避免重复计算同一场比赛
if self.last_match_id == match_id:
return None
old_win_streak = self.win_streak
old_loss_streak = self.loss_streak
if win:
self.win_streak += 1
self.loss_streak = 0 # 重置连败
else:
self.loss_streak += 1
self.win_streak = 0 # 重置连胜
self.last_match_id = match_id
self.save()
# 返回连胜连败状态变化信息
result = {
'name': self.name,
'win': win,
'win_streak': self.win_streak,
'loss_streak': self.loss_streak,
'win_streak_broken': not win and old_win_streak >= 3,
'loss_streak_broken': win and old_loss_streak >= 3,
'old_win_streak': old_win_streak,
'old_loss_streak': old_loss_streak
}
return result
def get_friends_recent_matches():
matches = []
global streak_updates # 使用全局变量存储连胜连败更新
streak_updates = []
for friend in Friend.filter(active=True):
for match_ in friend.get_recent_matches():
if not Match.select().where(Match.match_id == match_.match_id).exists():
@ -228,7 +267,17 @@ def get_friends_recent_matches():
radiant_win=match_.radiant_win,
party_size=match_.party_size,
)
# 判断玩家是否获胜
player_won = match_.radiant_win == (match_.player_slot < 128)
# 更新连胜连败
streak_info = friend.update_streak(match_.match_id, player_won)
if streak_info:
streak_updates.append(streak_info)
matches.append(match_obj.serialize_match())
return matches
@ -421,3 +470,31 @@ def check_rank_changes_for_discord():
})
return data
def check_streaks():
"""检查连胜连败并返回通知消息"""
global streak_updates
notifications = []
for update in streak_updates:
# 连胜达到3场或以上
if update['win_streak'] >= 3:
notifications.append(f"🔥 **{update['name']}** 正在**{update['win_streak']}连胜**")
# 连败达到3场或以上
if update['loss_streak'] >= 3:
notifications.append(f"💔 **{update['name']}** 正在**{update['loss_streak']}连败**")
# 连胜被终结
if update['win_streak_broken'] and update['old_win_streak'] >= 3:
notifications.append(f"⚡ **{update['name']}** 的**{update['old_win_streak']}连胜**被终结了!")
# 连败被终结
if update['loss_streak_broken'] and update['old_loss_streak'] >= 3:
notifications.append(f"🌈 **{update['name']}** 终于结束了**{update['old_loss_streak']}连败**")
# 清空更新列表,避免重复通知
streak_updates = []
return notifications