Skip to content

Commit

Permalink
Merge pull request #194 from pistachiostudio/vr-command-feature
Browse files Browse the repository at this point in the history
vr command feature
  • Loading branch information
quojama authored Jul 22, 2023
2 parents abfe8fd + fd7cafa commit 76fbc1e
Showing 1 changed file with 106 additions and 39 deletions.
145 changes: 106 additions & 39 deletions src/cogs/valorant_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,63 +16,130 @@ def __init__(self, bot: commands.Bot):
name="Valorantのプレイヤー名を入れてください。ex) 植 物、ウィングマン太郎、The Manなど",
tagline="#以降のタグを入れてください。#は不要です。",
)

# API request
# APIリクエストを送信し、エラーをチェックする関数
async def vr(self, interaction: discord.Interaction, name: str, tagline: str):
# interactionは3秒以内にレスポンスしないといけないとエラーになるのでこの処理を入れる。
await interaction.response.defer()

# API request
rank_url = f"https://api.henrikdev.xyz/valorant/v2/mmr/ap/{name}/{tagline}"

try:
async def send_request(url, name, tagline):
async with httpx.AsyncClient() as client:
res = await client.get(rank_url, timeout=10)
except httpx.HTTPError as e:
await interaction.followup.send(f"⚠ APIリクエストエラーが発生しました。時間を置いて試してみてください。: {e}")
return
res = await client.get(url, timeout=10)

json = res.json()
data = res.json()

# statusが200以外の場合はエラーを返す。
if data["status"] != 200:
embed = discord.Embed()
embed.color = discord.Color.red()
embed.title = "<:p01_pepebrim:951023068275421235>:warning: 入力が間違えているかもしれません。"
embed.description = f'**あなたの入力:** {name}#{tagline}\n**Status Code:** {data["status"]}\n\
**Error Msg:** {data["errors"][0]["message"]}'
await interaction.followup.send(embed=embed)
return None

# statusが200以外の場合はエラーを返す。
if json["status"] != 200:
embed = discord.Embed()
embed.color = discord.Color.red()
embed.title = "<:p01_pepebrim:951023068275421235>:warning: 入力が間違えているかもしれません。"
embed.description = f'**あなたの入力:** {name}#{tagline}\n**Status Code:** {json["status"]}\n\
**Error Msg:** {json["errors"][0]["message"]}'
await interaction.followup.send(embed=embed)
return

current_rank = json["data"]["current_data"]["currenttierpatched"]
rank_image_url = json["data"]["current_data"]["images"]["large"]
ranking_in_tier = json["data"]["current_data"]["ranking_in_tier"]
elo = json["data"]["current_data"]["elo"]

current_season_data = json["data"]["by_season"][current_season]
season_games = current_season_data.get("number_of_games", 0)
season_wins = current_season_data.get("wins", 0)
season_lose = season_games - season_wins
return data

# URLのエンドポイント
rank_url = f"https://api.henrikdev.xyz/valorant/v2/mmr/ap/{name}/{tagline}"
account_url = f"https://api.henrikdev.xyz/valorant/v1/account/{name}/{tagline}"
async with httpx.AsyncClient() as client:
res = await client.get(account_url)
account_json = res.json()
lifetime_matches_url = (
f"https://api.henrikdev.xyz/valorant/v1/lifetime/matches/ap/{name}/{tagline}"
)

real_name = account_json["data"]["name"]
real_tagline = account_json["data"]["tag"]
account_level = account_json["data"]["account_level"]
card_image_url = account_json["data"]["card"]["wide"]
try:
# リクエストを送信
data = await send_request(rank_url, name, tagline)
if data is None: # エラーチェック
return

account_data = await send_request(account_url, name, tagline)
if account_data is None: # エラーチェック
return

match_data = await send_request(lifetime_matches_url, name, tagline)
if match_data is None: # エラーチェック
return

except httpx.HTTPError as e:
await interaction.followup.send(f"⚠ APIリクエストエラーが発生しました。時間を置いて試してみてください。: {e}")

# APIから必要な基本情報の値を取得
currenttierpatched = data["data"]["current_data"]["currenttierpatched"]
ranking_in_tier = data["data"]["current_data"]["ranking_in_tier"]
name = data["data"]["name"]
tag = data["data"]["tag"]
rank_image_url = data["data"]["current_data"]["images"]["small"]
account_level = account_data["data"]["account_level"]
card_image_url = account_data["data"]["card"]["wide"]

# 新シーズンになって1試合もやってない場合は
# アクトごとのレスポンス部分はKeyErrorが発生するのでその判定を行う
try:
current_season_data = data["data"]["by_season"][current_season]
final_rank_patched = current_season_data.get("final_rank_patched", "Unrated")
number_of_games: int = current_season_data.get("number_of_games", 0)
# 正確なwinsを取得するために変更
wins: int = len(data["data"]["by_season"][current_season]["act_rank_wins"])
loses: int = number_of_games - wins
except KeyError:
wins = 0
loses = 0
final_rank_patched = "Unrated"

# ランクがUnratedの場合はELOなども一旦0にする。
# Unratedではなくランクがついている場合は通常の処理。
if final_rank_patched == "Unrated":
currenttierpatched = "Unrated"
ranking_in_tier = 0
rank_image_url = "https://media.valorant-api.com/competitivetiers/564d8e28-c226-3180-6285-e48a390db8b1/0/smallicon.png"
else:
pass

# これまでのランクすべてのWLを取得
total_act_rank_wins = 0
total_number_of_games = 0
season_data = data["data"]["by_season"]

for season, info in season_data.items():
if "act_rank_wins" in info:
total_act_rank_wins += len(info["act_rank_wins"])
if "number_of_games" in info:
total_number_of_games += info["number_of_games"]
total_act_rank_loses = total_number_of_games - total_act_rank_wins

# これまでの全試合のhead率を取得
total_head, total_body, total_leg = 0, 0, 0

for match in match_data["data"]:
shots = match["stats"]["shots"]
total_head += shots["head"]
total_body += shots["body"]
total_leg += shots["leg"]

total_shots = total_head + total_body + total_leg
head_rate = round((total_head / total_shots) * 100, 2)

# embed書き込み処理
embed = discord.Embed()
embed.title = f"{real_name} `#{real_tagline}`"
embed.title = f"{name} `#{tag}`"
embed.color = discord.Color.magenta()
embed.description = f"{season_txt} competitive results"
embed.set_thumbnail(url=rank_image_url)
embed.add_field(name="W/L", value=f"```{season_wins}W/{season_lose}L```")

embed.add_field(
name="Current rank", value=f"```{current_rank} (+{ranking_in_tier} RR)```"
name="Current Rank", value=f"```{currenttierpatched} (+{ranking_in_tier})```"
)
embed.add_field(name="ELO", value=f"```{elo}```")
embed.add_field(name="Current Act W/L", value=f"```{wins}W/{loses}L```")
embed.add_field(
name="Lifetime W/L", value=f"```{total_act_rank_wins}W/{total_act_rank_loses}L```"
)
embed.add_field(name="Lifetime HS Rate", value=f"```{head_rate}%```")
embed.add_field(name="Account Level", value=f"```{account_level}```")
embed.set_footer(
text="※ WLはランクのみの集計です。\n※ 引き分けは負けとしてカウントされます。\n※ ヘッショ率は過去100試合くらいのアンレやコンペすべての試合から算出しています。\n※ またキルしたショットではなく敵に当たった弾すべてでカウントしています。" # noqa E501
)
embed.set_image(url=card_image_url)

# interaction.response.deferを使ったのでここはfollowup.sendが必要
Expand Down

0 comments on commit 76fbc1e

Please sign in to comment.