BF_BOT/src/plugins/bf_bot/data_utils.py

142 lines
5.2 KiB
Python
Raw Normal View History

2025-10-28 09:30:54 +08:00
import os
from PIL import Image, ImageDraw, ImageFont
from nonebot import logger
from functools import reduce
from .img_utils import png_resize
from .param import round_data, interval_table
filepath = os.path.dirname(__file__).replace("\\", "/")
# async def avatar_cache(avatar_url, player_id):
# if avatar_url:
# try:
# # 添加10s超时判断如果超时直接使用默认头像
# res = BytesIO(requests.get(avatar_url, timeout=10).content)
# avatar = Image.open(res).convert('RGBA')
# avatar.save(f'{filepath}/avatar_cache/{player_id}.png', 'PNG')
# return avatar
# except requests.exceptions.RequestException as e:
# logger.warning(f"请求异常:{e}")
# else:
# return None
#
#
# async def get_avatar(avatar_url, player_id):
# img = Image.open(filepath + "/avatar_cache/0.png").convert('RGBA')
# path = filepath + "/avatar_cache/"
# try:
# avatar_list = os.listdir(path)
# if player_id in str(avatar_list):
# logger.info(f"本地已存在{player_id}头像")
# img = Image.open(f"{path}{player_id}.png").convert('RGBA')
# else:
# logger.info(f"未检测到{player_id}头像,缓存至本地")
# out_put = filepath + f"/avatar_cache/{player_id}.png"
# img = await avatar_cache(avatar_url, out_put)
# except Exception as err:
# logger.error(f"获取头像失败:{str(err)}")
# return img
async def get_best_weapon_and_best_vehicle(player_stat):
weapon = sorted(player_stat["weapons"], key=lambda k: k['kills'], reverse=True)[0]
vehicle = sorted(player_stat["vehicles"], key=lambda k: k['kills'], reverse=True)[0]
return weapon, vehicle
async def get_vehicle_destroyed(player_stat):
vehicle = reduce(lambda acc, x: acc + x['destroyed'], player_stat, 0)
return vehicle
async def stats_calculator(player_stat, game):
per500_data = round_data[game]
# 场次(无直接数值反馈,采用胜利数+失败数)
match_played = player_stat["wins"] + player_stat["loses"]
kd = player_stat["killDeath"]
kpm = player_stat["killsPerMinute"]
kill_assists = player_stat["killAssists"]
acc = float(player_stat["accuracy"].replace("%", ""))
if game == "bf3":
headshots = float(0)
else:
headshots = float(player_stat["headshots"].replace("%", ""))
spm = player_stat["scorePerMinute"]
revives = player_stat["revives"]
# second_play = player_stat["secondsPlayed"]
apr = kill_assists / match_played
rpr = revives / match_played
# SPM*秒数/60/场数=场均得分
# dpr = score_perMinute * (second_play / 60) / match_played
# 计算比值
# kd
ratio_kd = round(kd / per500_data["kd"], 2)
# kpm
ratio_kpm = round(kpm / per500_data["kpm"], 2)
# 爆头率
ratio_hs = round(headshots / 100 / per500_data["hs"], 2)
# 场均救援
ratio_rpr = round(rpr / per500_data["rpr"], 2)
# 场均助攻
ratio_apr = round(apr / per500_data["apr"], 2)
# 分钟得分
ratio_spm = round(spm / per500_data["spm"], 2)
logger.info(f"雷达图数据")
logger.info(f"生涯KD比值:{ratio_kd}")
logger.info(f"生涯Kpm比值:{ratio_kpm}")
logger.info(f"生涯准度比值:{ratio_hs}")
logger.info(f"场均救援比值:{ratio_rpr}")
logger.info(f"场均助攻比值:{ratio_apr}")
logger.info(f"分钟得分比值:{ratio_spm}")
stat_data = [ratio_kd, ratio_apr, ratio_hs, ratio_spm, ratio_kpm, ratio_rpr]
# 血腥度 kd*0.5 + kpm *0.4 +hs*0.1
player_blood = kd * 0.5 + kpm * 0.4 + headshots * 0.1
ratio_blood = player_blood / per500_data["blood"]
# 贡献度 场均助攻*0.4 + 场均救援*0.4 + spm*0.2
player_dedication = rpr * 0.4 + apr * 0.4 + spm * 0.2
ratio_dedication = player_dedication / per500_data["dedication"]
# 全能度 血腥度*0.5 + 贡献度*0.5
player_all_round = player_blood * 0.5 + player_dedication * 0.5
ratio_all_round = player_all_round / per500_data["all_round"]
logger.info(f"称号评级数据")
logger.info(f"血腥度:{player_blood} 比值:{ratio_blood}")
logger.info(f"贡献度:{player_dedication} 比值:{ratio_dedication}")
logger.info(f"全能度:{player_all_round} 比值:{ratio_all_round}")
level_designation = get_level_designation(ratio_blood, ratio_dedication, ratio_all_round)
return stat_data, level_designation
def get_level_designation(blood, dedication, all_round):
feature_type = ""
final_max = max([blood, dedication, all_round])
if final_max == blood:
feature_type = "blood"
elif final_max == dedication:
feature_type = "dedication"
elif final_max == all_round:
feature_type = "all_round"
logger.info(f"最高能力:{feature_type}")
logger.info(f"最高能力值:{final_max}")
final_info = get_feature(final_max, feature_type)
return final_info
def get_feature(value, feature_type):
"""根据输入值和数值类别,返回对应特征值"""
for (low, high), features in interval_table.items():
if low <= value < high:
return features[feature_type]
raise ValueError(f"数值 {value} 不在任何区间内")