feat(bot.py, dota.py, utils.py): 增加查询某人战绩的命令
增加查询某人战绩的命令 Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
parent
233fa91b5b
commit
cd1fc45044
@ -40,6 +40,18 @@ async def send_message(channel):
|
|||||||
logger.info(f"sending match {match_['match_id']}, {data}")
|
logger.info(f"sending match {match_['match_id']}, {data}")
|
||||||
await channel.send(content=data['content'], embeds=[discord.Embed.from_dict(embed) for embed in data['embeds']])
|
await channel.send(content=data['content'], embeds=[discord.Embed.from_dict(embed) for embed in data['embeds']])
|
||||||
|
|
||||||
|
@bot.command(description="获取最近战绩", name='recent_matches') # this decorator makes a slash command
|
||||||
|
async def get_friends_recent_matches(ctx, name, match_count=5): # a slash command will be created with the name "ping"
|
||||||
|
logger.info(f"get_friends_recent_matches {name} {match_count}")
|
||||||
|
friends = dota.Friend.filter(name=name)
|
||||||
|
match_count = int(match_count)
|
||||||
|
if friends.count() == 0:
|
||||||
|
await ctx.respond(content=f'找不到 {name} 的信息')
|
||||||
|
return
|
||||||
|
data = dota.Friend.serialize_recent_matches_for_discord(friends, match_count)
|
||||||
|
await ctx.respond(content=data['content'], embeds=[discord.Embed.from_dict(embed) for embed in data['embeds']])
|
||||||
|
|
||||||
|
|
||||||
@tasks.loop(minutes=1)
|
@tasks.loop(minutes=1)
|
||||||
async def heartbeat():
|
async def heartbeat():
|
||||||
utils.heartbeat()
|
utils.heartbeat()
|
||||||
|
|||||||
81
dota.py
81
dota.py
@ -75,13 +75,77 @@ class Friend(BaseModel):
|
|||||||
steam_id = peewee.IntegerField(primary_key=True)
|
steam_id = peewee.IntegerField(primary_key=True)
|
||||||
name = peewee.CharField()
|
name = peewee.CharField()
|
||||||
|
|
||||||
def get_recent_matches(self):
|
def get_recent_matches(self, limit=1):
|
||||||
try:
|
try:
|
||||||
return player_client.get_players_by_account_id_select_matches(self.steam_id, limit=1)
|
return player_client.get_players_by_account_id_select_matches(self.steam_id, limit=limit)
|
||||||
except:
|
except:
|
||||||
logger.error('fail to get player %s recent matches' % self.steam_id)
|
logger.error('fail to get player %s recent matches' % self.steam_id)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def serialize_recent_matches(self, limit=1):
|
||||||
|
matches = self.get_recent_matches(limit=limit)
|
||||||
|
data = []
|
||||||
|
for match_ in matches:
|
||||||
|
data.append({
|
||||||
|
'match_id': match_.match_id,
|
||||||
|
'win': match_.radiant_win == (match_.player_slot < 128),
|
||||||
|
'is_radiant': match_.player_slot < 128,
|
||||||
|
'kills': match_.kills,
|
||||||
|
'deaths': match_.deaths,
|
||||||
|
'assists': match_.assists,
|
||||||
|
'party_size': match_.party_size,
|
||||||
|
'start_time': match_.start_time,
|
||||||
|
'duration': match_.duration,
|
||||||
|
'average_rank': utils.get_ranking(match_.average_rank),
|
||||||
|
'hero_id': match_.hero_id,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def serialize_recent_matches_for_discord(cls, friends, limit=5):
|
||||||
|
# {
|
||||||
|
# "content": "## 水哥的战报\n",
|
||||||
|
# "embeds": [
|
||||||
|
# {
|
||||||
|
# "description": "3黑 00:34:23",
|
||||||
|
# "fields": [],
|
||||||
|
# "title": "2 杀 5 死 3 助 ",
|
||||||
|
# "color": 6732650,
|
||||||
|
# "url": "https://www.opendota.com/matches/7335993790",
|
||||||
|
# "timestamp": "2023-09-12T16:00:00.000Z"
|
||||||
|
# }
|
||||||
|
# ],
|
||||||
|
# }
|
||||||
|
matches = []
|
||||||
|
if limit > 10:
|
||||||
|
limit = 10
|
||||||
|
for friend in friends:
|
||||||
|
matches.extend(friend.serialize_recent_matches(limit=limit))
|
||||||
|
# sort matches by start_time from latest to oldest
|
||||||
|
matches.sort(key=lambda x: x['start_time'], reverse=True)
|
||||||
|
name = friends[0].name
|
||||||
|
data = {
|
||||||
|
'content': f'## {name}的战报',
|
||||||
|
'embeds': [],
|
||||||
|
}
|
||||||
|
for match_ in matches[:limit]:
|
||||||
|
duration = '%d:%02d:%02d' % utils.convert_seconds_to_hms(match_['duration'])
|
||||||
|
if match_['party_size'] > 1:
|
||||||
|
summary = f"{match_['party_size']}黑 {duration}"
|
||||||
|
else:
|
||||||
|
summary = f"单排 {duration}"
|
||||||
|
start_time = datetime.datetime.fromtimestamp(match_['start_time']).strftime('%Y-%m-%dT%H:%M:%S.000+08:00')
|
||||||
|
hero_name = Hero.get(hero_id=match_['hero_id']).localized_name
|
||||||
|
data['embeds'].append({
|
||||||
|
'title': f"{hero_name} {match_['kills']} 杀 {match_['deaths']} 死 {match_['assists']} 助 ",
|
||||||
|
'description': summary + '\n' + match_['average_rank'],
|
||||||
|
'color': 6732650 if match_['win'] else 16724787, # 66bb6a or FF3333
|
||||||
|
'fields': [],
|
||||||
|
'timestamp': start_time,
|
||||||
|
'url': f"https://www.opendota.com/matches/{match_['match_id']}",
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_friends_recent_matches():
|
def get_friends_recent_matches():
|
||||||
matches = []
|
matches = []
|
||||||
@ -98,17 +162,6 @@ def get_friends_recent_matches():
|
|||||||
matches.append(match_obj.serialize_match())
|
matches.append(match_obj.serialize_match())
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
def shorten_digits(num):
|
|
||||||
# if num like 12345, return 1.2w
|
|
||||||
# if num like 1234, return 1.2k
|
|
||||||
# if num < 1000, return num
|
|
||||||
# if result ends with 0, remove it
|
|
||||||
if num >= 10000:
|
|
||||||
return '%.1fw' % (num / 10000)
|
|
||||||
elif num >= 1000:
|
|
||||||
return '%.1fk' % (num / 1000)
|
|
||||||
else:
|
|
||||||
return str(num)
|
|
||||||
|
|
||||||
def serialize_match_for_discord(match_):
|
def serialize_match_for_discord(match_):
|
||||||
# {
|
# {
|
||||||
@ -171,7 +224,7 @@ def serialize_match_for_discord(match_):
|
|||||||
dire_highest_damage_idx = 0
|
dire_highest_damage_idx = 0
|
||||||
|
|
||||||
for player in match_['players']:
|
for player in match_['players']:
|
||||||
desc = f"{player['nickname'] or player['personaname']}(Lv.**{player['level']}** {player['hero']}): **{player['kills']}** 杀 **{player['deaths']}** 死 **{player['assists']}** 助 | **{shorten_digits(player['total_gold'])}** 经济 | **{shorten_digits(player['hero_damage'])}** 伤害 "
|
desc = f"{player['nickname'] or player['personaname']}(Lv.**{player['level']}** {player['hero']}): **{player['kills']}** 杀 **{player['deaths']}** 死 **{player['assists']}** 助 | **{utils.shorten_digits(player['total_gold'])}** 经济 | **{utils.shorten_digits(player['hero_damage'])}** 伤害 "
|
||||||
|
|
||||||
if player['is_radiant']:
|
if player['is_radiant']:
|
||||||
radiant.append(desc)
|
radiant.append(desc)
|
||||||
|
|||||||
36
utils.py
36
utils.py
@ -30,3 +30,39 @@ def heartbeat():
|
|||||||
except:
|
except:
|
||||||
logger.error('fail to heartbeat, resp status: %s' % resp.status_code)
|
logger.error('fail to heartbeat, resp status: %s' % resp.status_code)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_ranking(ranking_int):
|
||||||
|
# (10-15: Herald, 20-25: Guardian, 30-35: Crusader, 40-45: Archon, 50-55: Legend, 60-65: Ancient, 70-75: Divine, 80-85: Immortal).
|
||||||
|
stars = ranking_int % 10
|
||||||
|
if ranking_int < 20:
|
||||||
|
return '先锋 %s' % stars
|
||||||
|
elif ranking_int < 30:
|
||||||
|
return '卫士 %s' % stars
|
||||||
|
elif ranking_int < 40:
|
||||||
|
return '中军 %s' % stars
|
||||||
|
elif ranking_int < 50:
|
||||||
|
return '统帅 %s' % stars
|
||||||
|
elif ranking_int < 60:
|
||||||
|
return '传奇 %s' % stars
|
||||||
|
elif ranking_int < 70:
|
||||||
|
return '万古流芳 %s' % stars
|
||||||
|
elif ranking_int < 80:
|
||||||
|
return '超凡入圣 %s' % stars
|
||||||
|
elif ranking_int < 90:
|
||||||
|
return '不朽 %s' % stars
|
||||||
|
else:
|
||||||
|
return 'Unknown %s' % stars
|
||||||
|
|
||||||
|
|
||||||
|
def shorten_digits(num):
|
||||||
|
# if num like 12345, return 1.2w
|
||||||
|
# if num like 1234, return 1.2k
|
||||||
|
# if num < 1000, return num
|
||||||
|
# if result ends with 0, remove it
|
||||||
|
if num >= 10000:
|
||||||
|
return '%.1fw' % (num / 10000)
|
||||||
|
elif num >= 1000:
|
||||||
|
return '%.1fk' % (num / 1000)
|
||||||
|
else:
|
||||||
|
return str(num)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user