- hexi core: message handling, rate limiting, cooldown, plugin manager - Custom plugins: BF stats, daily check-in, quotes, persona cards, etc. - Community plugins vendored under hexi/plugins with local fixes - Web admin frontends (learning-chat, persona-admin), unified hexi/web - Tests for rate_limit/cooldown/memes/persona; poetry.lock Co-Authored-By: Claude <noreply@anthropic.com>
272 lines
12 KiB
Python
272 lines
12 KiB
Python
from nonebot import logger
|
|
import json
|
|
|
|
# from bf6_data import *
|
|
import requests
|
|
from curl_cffi import AsyncSession, CurlError
|
|
from nonebot import logger
|
|
|
|
from .bf6_data import *
|
|
|
|
url_search = "https://api.tracker.gg/api/v2/bf6/standard/search?platform={platform}&query={name}&autocomplete=true"
|
|
url_overview = "https://api.tracker.gg/api/v2/bf6/standard/profile/ign/{param}"
|
|
|
|
|
|
async def format_data(response, search_type):
|
|
status = ""
|
|
|
|
platform_info = response['data']['platformInfo']
|
|
segments = response['data']['segments']
|
|
|
|
overview = ""
|
|
weapons = []
|
|
vehicles = []
|
|
gamemodes = []
|
|
gadgets = []
|
|
kits = []
|
|
maps = []
|
|
|
|
for segment in segments:
|
|
if segment['type'] == 'overview':
|
|
overview = segment
|
|
elif segment['type'] == 'weapon':
|
|
weapons.append(segment)
|
|
elif segment['type'] == 'vehicle':
|
|
vehicles.append(segment)
|
|
elif segment['type'] == 'gamemode':
|
|
gamemodes.append(segment)
|
|
elif segment['type'] == 'gadget':
|
|
gadgets.append(segment)
|
|
elif segment['type'] == 'kit':
|
|
kits.append(segment)
|
|
elif segment['type'] == 'level':
|
|
maps.append(segment)
|
|
if search_type == 0:
|
|
status = await get_overview(platform_info, overview, weapons, vehicles, gamemodes, gadgets, kits, maps)
|
|
if search_type == 1:
|
|
status = await get_weapons(platform_info, overview, weapons, vehicles, gamemodes, gadgets, kits, maps)
|
|
|
|
return status
|
|
|
|
|
|
async def get_user_id_2_data(title_id, search_type):
|
|
url = url_overview.format(param=title_id)
|
|
info = await search_user_with_fallback(url)
|
|
info = await format_data(info, search_type)
|
|
return info
|
|
|
|
|
|
# 调用此方法获取格式化后的数据(调用此方法即可)
|
|
async def get_info(player, search_type):
|
|
# 先使用橘子搜索
|
|
url = url_search.format(platform="orign", name=player)
|
|
result = await search_user_with_fallback(url)
|
|
# 无结果再使用steam搜索
|
|
if "errors" in result:
|
|
url = url_search.format(platform="steam", name=player)
|
|
result = await search_user_with_fallback(url)
|
|
title_id_list = []
|
|
logger.info(f"查询结果: \n{json.dumps(result, ensure_ascii=False, indent=2)}")
|
|
if "status" in result or "errors" in result:
|
|
return 3, '查询异常'
|
|
for res in result['data']:
|
|
if res['status'] is not None:
|
|
name = res['platformUserHandle']
|
|
uid = res['titleUserId']
|
|
status = res['status'].strip().split('•', 1)[0].replace("Rank", "")
|
|
user = {
|
|
'name': name,
|
|
'rank': status,
|
|
'uid': uid,
|
|
}
|
|
title_id_list.append(user)
|
|
if len(title_id_list) > 1:
|
|
user_list = sorted(title_id_list, key=lambda k: int(k['rank']), reverse=True)
|
|
msg = '\n'.join(f'用户名:{info["name"]}-等级:{info["rank"]}-UID:{info["uid"]}' for info in user_list)
|
|
logger.info(f"检测到多个同名用户\n{msg}")
|
|
return 0, title_id_list
|
|
elif len(title_id_list) == 1:
|
|
logger.info(f"单用户{title_id_list}")
|
|
info = await get_user_id_2_data(title_id_list[0]['uid'], search_type)
|
|
logger.info(f"查询结果: {json.dumps(info, ensure_ascii=False, indent=2)}")
|
|
return 1, info
|
|
else:
|
|
logger.info(f"未查询到用户")
|
|
return 2, '未查询到用户'
|
|
|
|
|
|
async def get_overview(platform_info, overview, weapons, vehicles, gamemodes, gadgets, kits, maps):
|
|
top_kill_weapon = sorted(weapons, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_weapon = {
|
|
"名称": top_kill_weapon['metadata']['name'],
|
|
"击杀": top_kill_weapon['stats']['kills']['value'],
|
|
"KPM": top_kill_weapon['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_weapon['stats']['timePlayed']['displayValue'],
|
|
"爆头率": top_kill_weapon['stats']['headshotPercentage']['displayValue'],
|
|
"命中率": top_kill_weapon['stats']['shotsAccuracy']['displayValue']
|
|
}
|
|
top_kill_vehicle = sorted(vehicles, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_vehicle = {
|
|
"名称": top_kill_vehicle['metadata']['name'],
|
|
"击杀": top_kill_vehicle['stats']['kills']['value'],
|
|
"KPM": top_kill_vehicle['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_vehicle['stats']['timePlayed']['displayValue'],
|
|
"碾压": top_kill_vehicle['stats']['roadKills']['value'],
|
|
"摧毁": top_kill_vehicle['stats']['destroyedWith']['value'],
|
|
|
|
}
|
|
shot_count = overview['stats']['shotsFired']['value']
|
|
hit_count = overview['stats']['shotsHit']['value']
|
|
logger.info(f"开火数:{shot_count}")
|
|
logger.info(f"命中数:{hit_count}")
|
|
acc = round((hit_count / shot_count) * 100, 2)
|
|
logger.info(f"命中率:{acc}%")
|
|
player_info = {
|
|
'玩家名称': platform_info['platformUserHandle'],
|
|
'游玩平台': platform_info['platformSlug'],
|
|
'游戏等级': overview['stats']['careerPlayerRank']['displayValue'],
|
|
'游玩时长': overview['stats']['timePlayed']['displayValue'],
|
|
'游玩场次': overview['stats']['matchesPlayed']['displayValue'],
|
|
'对局胜率': overview['stats']['wlPercentage']['displayValue'],
|
|
'对局得分': overview['stats']['score']['displayValue'],
|
|
'玩家K/D': overview['stats']['kdRatio']['value'],
|
|
'玩家KPM': overview['stats']['killsPerMinute']['value'],
|
|
'玩家SPM': overview['stats']['scorePerMinute']['value'],
|
|
'真人击杀': overview['stats']['playerKills']['displayValue'],
|
|
'击杀总计': overview['stats']['kills']['displayValue'],
|
|
'目标占领': overview['stats']['objectivesCaptured']['value'],
|
|
'游戏助攻': overview['stats']['assists']['displayValue'],
|
|
'救援数量': overview['stats']['revives']['displayValue'],
|
|
'最高连杀': overview['stats']['multiKills']['value'],
|
|
'命中率': f"{acc}%",
|
|
'爆头率': overview['stats']['headshotPercentage']['displayValue'],
|
|
'最佳武器': best_weapon,
|
|
'最佳载具': best_vehicle,
|
|
}
|
|
return player_info
|
|
|
|
|
|
async def get_weapons(platform_info, overview, weapons, vehicles, gamemodes, gadgets, kits, maps):
|
|
top_kill_weapon = sorted(weapons, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_weapon = {
|
|
"名称": top_kill_weapon['metadata']['name'],
|
|
"击杀": top_kill_weapon['stats']['kills']['value'],
|
|
"KPM": top_kill_weapon['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_weapon['stats']['timePlayed']['displayValue'],
|
|
"爆头率": top_kill_weapon['stats']['headshotPercentage']['displayValue'],
|
|
"命中率": top_kill_weapon['stats']['shotsAccuracy']['displayValue']
|
|
}
|
|
top_kill_vehicle = sorted(vehicles, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_vehicle = {
|
|
"名称": top_kill_vehicle['metadata']['name'],
|
|
"击杀": top_kill_vehicle['stats']['kills']['value'],
|
|
"KPM": top_kill_vehicle['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_vehicle['stats']['timePlayed']['displayValue'],
|
|
"碾压": top_kill_vehicle['stats']['roadKills']['value'],
|
|
"摧毁": top_kill_vehicle['stats']['destroyedWith']['value'],
|
|
|
|
}
|
|
shot_count = overview['stats']['shotsFired']['value']
|
|
hit_count = overview['stats']['shotsHit']['value']
|
|
logger.info(f"开火数:{shot_count}")
|
|
logger.info(f"命中数:{hit_count}")
|
|
acc = round((hit_count / shot_count) * 100, 2)
|
|
logger.info(f"命中率:{acc}%")
|
|
player_info = {
|
|
'玩家名称': platform_info['platformUserHandle'],
|
|
'游玩平台': platform_info['platformSlug'],
|
|
'游戏等级': overview['stats']['careerPlayerRank']['displayValue'],
|
|
'游玩时长': overview['stats']['timePlayed']['displayValue'],
|
|
'游玩场次': overview['stats']['matchesPlayed']['displayValue'],
|
|
'对局胜率': overview['stats']['wlPercentage']['displayValue'],
|
|
'对局得分': overview['stats']['score']['displayValue'],
|
|
'玩家K/D': overview['stats']['kdRatio']['value'],
|
|
'玩家KPM': overview['stats']['killsPerMinute']['value'],
|
|
'玩家SPM': overview['stats']['scorePerMinute']['value'],
|
|
'真人击杀': overview['stats']['playerKills']['displayValue'],
|
|
'击杀总计': overview['stats']['kills']['displayValue'],
|
|
'目标占领': overview['stats']['objectivesCaptured']['value'],
|
|
'游戏助攻': overview['stats']['assists']['displayValue'],
|
|
'救援数量': overview['stats']['revives']['displayValue'],
|
|
'最高连杀': overview['stats']['multiKills']['value'],
|
|
'命中率': f"{acc}%",
|
|
'爆头率': overview['stats']['headshotPercentage']['displayValue'],
|
|
'最佳武器': best_weapon,
|
|
'最佳载具': best_vehicle,
|
|
}
|
|
return player_info
|
|
|
|
|
|
async def get_vehicles(platform_info, overview, weapons, vehicles, gamemodes, gadgets, kits, maps):
|
|
top_kill_weapon = sorted(weapons, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_weapon = {
|
|
"名称": top_kill_weapon['metadata']['name'],
|
|
"击杀": top_kill_weapon['stats']['kills']['value'],
|
|
"KPM": top_kill_weapon['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_weapon['stats']['timePlayed']['displayValue'],
|
|
"爆头率": top_kill_weapon['stats']['headshotPercentage']['displayValue'],
|
|
"命中率": top_kill_weapon['stats']['shotsAccuracy']['displayValue']
|
|
}
|
|
top_kill_vehicle = sorted(vehicles, key=lambda k: k['stats']['kills']['value'], reverse=True)[0]
|
|
best_vehicle = {
|
|
"名称": top_kill_vehicle['metadata']['name'],
|
|
"击杀": top_kill_vehicle['stats']['kills']['value'],
|
|
"KPM": top_kill_vehicle['stats']['killsPerMinute']['value'],
|
|
"时长": top_kill_vehicle['stats']['timePlayed']['displayValue'],
|
|
"碾压": top_kill_vehicle['stats']['roadKills']['value'],
|
|
"摧毁": top_kill_vehicle['stats']['destroyedWith']['value'],
|
|
|
|
}
|
|
shot_count = overview['stats']['shotsFired']['value']
|
|
hit_count = overview['stats']['shotsHit']['value']
|
|
logger.info(f"开火数:{shot_count}")
|
|
logger.info(f"命中数:{hit_count}")
|
|
acc = round((hit_count / shot_count) * 100, 2)
|
|
logger.info(f"命中率:{acc}%")
|
|
player_info = {
|
|
'玩家名称': platform_info['platformUserHandle'],
|
|
'游玩平台': platform_info['platformSlug'],
|
|
'游戏等级': overview['stats']['careerPlayerRank']['displayValue'],
|
|
'游玩时长': overview['stats']['timePlayed']['displayValue'],
|
|
'游玩场次': overview['stats']['matchesPlayed']['displayValue'],
|
|
'对局胜率': overview['stats']['wlPercentage']['displayValue'],
|
|
'对局得分': overview['stats']['score']['displayValue'],
|
|
'玩家K/D': overview['stats']['kdRatio']['value'],
|
|
'玩家KPM': overview['stats']['killsPerMinute']['value'],
|
|
'玩家SPM': overview['stats']['scorePerMinute']['value'],
|
|
'真人击杀': overview['stats']['playerKills']['displayValue'],
|
|
'击杀总计': overview['stats']['kills']['displayValue'],
|
|
'目标占领': overview['stats']['objectivesCaptured']['value'],
|
|
'游戏助攻': overview['stats']['assists']['displayValue'],
|
|
'救援数量': overview['stats']['revives']['displayValue'],
|
|
'最高连杀': overview['stats']['multiKills']['value'],
|
|
'命中率': f"{acc}%",
|
|
'爆头率': overview['stats']['headshotPercentage']['displayValue'],
|
|
'最佳武器': best_weapon,
|
|
'最佳载具': best_vehicle,
|
|
}
|
|
return player_info
|
|
|
|
|
|
async def get_bf6_data(player_id, user_id, platform):
|
|
|
|
url = "https://api.gametools.network/bf6/multiple/?raw=false&format_values=true"
|
|
|
|
payload = json.dumps([
|
|
{
|
|
"player_id": player_id,
|
|
"user_id": user_id,
|
|
"platform": platform
|
|
}
|
|
])
|
|
headers = {
|
|
'accept': 'application/json',
|
|
'Content-Type': 'application/json'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
player_stat_json = json.loads(response.text)
|
|
|
|
return player_stat_json
|