新增:查询展柜角色

This commit is contained in:
KimgiaiiWuyi 2022-06-01 22:23:22 +08:00
parent 53a6358c20
commit eb8411fa3a
975 changed files with 609577 additions and 1 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

579516
enkaToData/data/textMap.json Normal file

File diff suppressed because it is too large Load Diff

115
enkaToData/dataToMap.py Normal file
View File

@ -0,0 +1,115 @@
import asyncio
from pathlib import Path
import httpx
import json
R_PATH = Path(__file__).parents[0]
MAP_PATH = R_PATH / 'map'
DATA_PATH = R_PATH / 'data'
verison = '2.7.0'
avatarName2Element_fileName = f'avatarName2Element_mapping_{verison}.json'
weaponHash2Name_fileName = f'weaponHash2Name_mapping_{verison}.json'
weaponHash2Type_fileName = f'weaponHash2Type_mapping_{verison}.json'
skillId2Name_fileName = f'skillId2Name_mapping_{verison}.json'
talentId2Name_fileName = f'talentId2Name_mapping_{verison}.json'
avatarId2Name_fileName = f'avatarId2Name_mapping_{verison}.json'
with open(DATA_PATH / 'textMap.json', "r", encoding='UTF-8') as f:
raw_data = json.load(f)
async def avatarId2NameJson() -> None:
with open(DATA_PATH / 'AvatarExcelConfigData.json', "r", encoding='UTF-8') as f:
avatar_data = json.load(f)
temp = {}
for i in avatar_data:
temp[str(i['id'])] = raw_data[str(i['nameTextMapHash'])]
with open(MAP_PATH / avatarId2Name_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def avatarName2ElementJson() -> None:
with open(MAP_PATH / avatarId2Name_fileName, "r", encoding='UTF-8') as f:
avatarId2Name = json.load(f)
temp = {}
elementMap = {'':'Anemo','':'Geo','':'Dendro','':'Pyro','':'Hydro','':'Cryo','':'Electro'}
for i in list(avatarId2Name.values()):
data = json.loads(httpx.get('https://info.minigg.cn/characters?query={}'.format(i)).text)
if 'errcode' in data:
pass
else:
temp[i] = elementMap[data['element']]
with open(MAP_PATH / avatarName2Element_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def weaponHash2NameJson() -> None:
with open(DATA_PATH / 'WeaponExcelConfigData.json', "r", encoding='UTF-8') as f:
weapon_data = json.load(f)
temp = {}
for i in weapon_data:
temp[str(i['nameTextMapHash'])] = raw_data[str(i['nameTextMapHash'])]
with open(MAP_PATH / weaponHash2Name_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def weaponHash2NameJson() -> None:
with open(DATA_PATH / 'WeaponExcelConfigData.json', "r", encoding='UTF-8') as f:
weapon_data = json.load(f)
temp = {}
for i in weapon_data:
if i['weaponType'] == 'WEAPON_POLE':
weaponType = "长柄武器"
elif i['weaponType'] == 'WEAPON_BOW':
weaponType = ""
elif i['weaponType'] == 'WEAPON_SWORD_ONE_HAND':
weaponType = "单手剑"
elif i['weaponType'] == 'WEAPON_CLAYMORE':
weaponType = "双手剑"
elif i['weaponType'] == 'WEAPON_CATALYST':
weaponType = "法器"
else:
weaponType = ""
temp[str(i['nameTextMapHash'])] = weaponType
with open(MAP_PATH / weaponHash2Type_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def skillId2NameJson() -> None:
with open(DATA_PATH / 'AvatarSkillExcelConfigData.json', "r", encoding='UTF-8') as f:
skill_data = json.load(f)
temp = {'Name':{},'Icon':{}}
for i in skill_data:
temp['Name'][str(i['id'])] = raw_data[str(i['nameTextMapHash'])]
temp['Icon'][str(i['id'])] = i['skillIcon']
with open(MAP_PATH / skillId2Name_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def talentId2NameJson() -> None:
with open(DATA_PATH / 'AvatarTalentExcelConfigData.json', "r", encoding='UTF-8') as f:
talent_data = json.load(f)
temp = {'Name':{},'Icon':{}}
for i in talent_data:
temp['Name'][str(i['talentId'])] = raw_data[str(i['nameTextMapHash'])]
temp['Icon'][str(i['talentId'])] = i['icon']
with open(MAP_PATH / talentId2Name_fileName,'w', encoding='UTF-8') as file:
json.dump(temp, file, ensure_ascii=False)
async def main():
await avatarId2NameJson()
await avatarName2ElementJson()
await weaponHash2NameJson()
await skillId2NameJson()
await talentId2NameJson()
await weaponHash2NameJson()
asyncio.run(main())

299
enkaToData/drawCharCard.py Normal file
View File

@ -0,0 +1,299 @@
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from base64 import b64encode
from httpx import get
import math
import json
R_PATH = Path(__file__).parents[0]
TEXT_PATH = R_PATH / 'texture2D'
ICON_PATH = R_PATH / 'icon'
GACHA_PATH = R_PATH / 'gachaImg'
PLAYER_PATH = R_PATH / 'player'
RELIC_PATH = R_PATH / 'relicIcon'
COLOR_MAP = {'Anemo':(3, 90, 77),'Cryo':(5, 85, 151),'Dendro':(4, 87, 3),
'Electro':(47, 1, 85),'Geo':(85, 34, 1),'Hydro':(4, 6, 114),'Pyro':(88, 4, 4)}
def genshin_font_origin(size: int) -> ImageFont:
return ImageFont.truetype(str(TEXT_PATH / 'yuanshen_origin.ttf'), size=size)
def get_star_png(star: int) -> Image:
png = Image.open(TEXT_PATH / 's-{}.png'.format(str(star)))
return png
def strLenth(r: str, size: int, limit: int = 540) -> str:
result = ''
temp = 0
for i in r:
if temp >= limit:
result += '\n' + i
temp = 0
else:
result += i
if i.isdigit():
temp += round(size / 10 * 6)
elif i == '/':
temp += round(size / 10 * 2.2)
elif i == '.':
temp += round(size / 10 * 3)
elif i == '%':
temp += round(size / 10 * 9.4)
else:
temp += size
return result
async def draw_char_card(raw_data: dict, charUrl: str = None) -> str:
img = Image.open(TEXT_PATH / '{}.png'.format(raw_data['avatarElement']))
char_info_1 = Image.open(TEXT_PATH / 'char_info_1.png')
char_imfo_mask = Image.open(TEXT_PATH / 'char_info_mask.png')
based_w, based_h = 320, 1024
if charUrl:
char_img = Image.open(BytesIO(get(charUrl).content)).convert('RGBA')
else:
char_img = Image.open(GACHA_PATH / 'UI_Gacha_AvatarIcon_{}.png'.format(raw_data['avatarEnName'])) #角色图像
# 确定图片的长宽
w, h = char_img.size
if (w, h) != (320, 1024):
based_scale = '%.3f' % (based_w / based_h)
scale_f = '%.3f' % (w / h)
new_w = math.ceil(based_h * float(scale_f))
new_h = math.ceil(based_w / float(scale_f))
if scale_f > based_scale:
bg_img2 = char_img.resize((new_w, based_h), Image.Resampling.LANCZOS)
char_img = bg_img2.crop((new_w/2 - 160, 0, new_w/2 + 160, based_h))
else:
bg_img2 = char_img.resize((based_w, new_h), Image.Resampling.LANCZOS)
char_img = bg_img2.crop((0, new_h/2 - 512, based_w, new_h/2 + 512))
else:
pass
img_temp = Image.new('RGBA', (320, 1024), (0,0,0,0))
img_temp.paste(char_img,(0,0),char_imfo_mask)
img.paste(img_temp, (41, 29), img_temp)
img.paste(char_info_1, (0, 0), char_info_1)
#holo_img = Image.open(TEXT_PATH / 'icon_holo.png')
#skill_holo_img = Image.open(TEXT_PATH / 'skillHolo.png')
lock_img = Image.open(TEXT_PATH / 'icon_lock.png')
#color_soild = Image.new('RGBA', (950, 1850), COLOR_MAP[raw_data['avatarElement']])
#img.paste(color_soild, (0, 0), skill_holo_img)
#color_holo_img = Image.new('RGBA', (100, 100), COLOR_MAP[raw_data['avatarElement']])
# 命座处理
for talent_num in range(0,6):
if talent_num + 1 <= len(raw_data['talentList']):
talent = raw_data['talentList'][talent_num]
#img.paste(color_holo_img, (13,270 + talent_num * 66), holo_img)
talent_img = Image.open(ICON_PATH / '{}.png'.format(talent['talentIcon']))
talent_img_new = talent_img.resize((50, 50), Image.Resampling.LANCZOS).convert("RGBA")
img.paste(talent_img_new, (850, 375 + talent_num * 81), talent_img_new)
else:
img.paste(lock_img, (850, 375 + talent_num * 81), lock_img)
# 天赋处理
skillList = raw_data['avatarSkill']
a_skill_name = skillList[0]['skillName'].replace('普通攻击·','')
a_skill_level = skillList[0]['skillLevel']
e_skill_name = skillList[1]['skillName']
e_skill_level = skillList[1]['skillLevel']
q_skill_name = skillList[-1]['skillName']
q_skill_level = skillList[-1]['skillLevel']
for skill_num, skill in enumerate(skillList[0:2]+[skillList[-1]]):
skill_img = Image.open(ICON_PATH / '{}.png'.format(skill['skillIcon']))
skill_img_new = skill_img.resize((50, 50), Image.Resampling.LANCZOS).convert("RGBA")
img.paste(skill_img_new, (78, 756 + 101 * skill_num), skill_img_new)
# 武器部分
weapon_img = Image.open(TEXT_PATH / 'char_info_weapon.png')
weapon_star_img = get_star_png(raw_data['weaponInfo']['weaponStar'])
weaponName = raw_data['weaponInfo']['weaponName']
weaponAtk = raw_data['weaponInfo']['weaponStats'][0]['statValue']
weaponLevel = raw_data['weaponInfo']['weaponLevel']
weaponAffix = raw_data['weaponInfo']['weaponAffix']
weaponEffect = raw_data['weaponInfo']['weaponEffect']
weapon_type = raw_data['weaponInfo']['weaponType']
weapon_img.paste(weapon_star_img, (25,235), weapon_star_img)
weapon_text = ImageDraw.Draw(weapon_img)
weapon_text.text((35, 80), weaponName, (255, 255, 255), genshin_font_origin(50), anchor='lm')
weapon_text.text((35, 120), weapon_type, (255, 255, 255), genshin_font_origin(20), anchor='lm')
weapon_text.text((35, 160), '基础攻击力', (255, 255, 255), genshin_font_origin(32), anchor='lm')
weapon_text.text((368, 160), str(weaponAtk), (255, 255, 255), genshin_font_origin(32), anchor='rm')
if len(raw_data['weaponInfo']['weaponStats']) == 2:
weapon_sub_info = raw_data['weaponInfo']['weaponStats'][1]['statName']
weapon_sub_value = raw_data['weaponInfo']['weaponStats'][1]['statValue']
weapon_text.text((35, 211), weapon_sub_info, (255, 255, 255), genshin_font_origin(32), anchor='lm')
weapon_text.text((368, 211), str(weapon_sub_value), (255, 255, 255), genshin_font_origin(32), anchor='rm')
else:
weapon_text.text((35, 211), '该武器无副词条', (255, 255, 255), genshin_font_origin(32), anchor='lm')
weapon_text.text((73, 303), f'Lv.{weaponLevel}', (255, 255, 255), genshin_font_origin(28), anchor='mm')
weapon_text.text((130, 305), f'精炼{str(weaponAffix)}', (255, 239, 173), genshin_font_origin(28), anchor='lm')
weaponEffect = strLenth(weaponEffect, 25, 455)
weapon_text.text((25, 335), weaponEffect, (255, 255, 255), genshin_font_origin(25))
img.paste(weapon_img, (387, 570), weapon_img)
# 圣遗物部分
artifactsAllScore = 0
for aritifact in raw_data['equipList']:
artifacts_img = Image.open(TEXT_PATH / 'char_info_artifacts.png')
artifacts_piece_img = Image.open(RELIC_PATH / '{}.png'.format(aritifact['icon']))
artifacts_piece_new_img = artifacts_piece_img.resize((180, 180), Image.Resampling.LANCZOS).convert("RGBA")
artifacts_piece_new_img.putalpha(artifacts_piece_new_img.getchannel('A').point(lambda x: round(x * 0.5) if x > 0 else 0))
artifacts_img.paste(artifacts_piece_new_img, (100, 35), artifacts_piece_new_img)
aritifactStar_img = get_star_png(aritifact['aritifactStar'])
artifactsPos = aritifact['aritifactPieceName']
artifacts_img.paste(aritifactStar_img, (20, 165), aritifactStar_img)
artifacts_text = ImageDraw.Draw(artifacts_img)
artifacts_text.text((30, 66), aritifact['aritifactName'], (255, 255, 255), genshin_font_origin(34), anchor='lm')
artifacts_text.text((30, 102), artifactsPos, (255, 255, 255), genshin_font_origin(20), anchor='lm')
mainValue = aritifact['reliquaryMainstat']['statValue']
mainName = aritifact['reliquaryMainstat']['statName']
mainLevel = aritifact['aritifactLevel']
if mainName in ['攻击力', '血量', '防御力', '元素精通']:
mainValueStr = str(mainValue)
else:
mainValueStr = str(mainValue) + '%'
mainNameNew = mainName.replace('百分比','')
artifacts_text.text((26, 140), mainNameNew, (255, 255, 255), genshin_font_origin(28), anchor='lm')
artifacts_text.text((268, 140), mainValueStr, (255, 255, 255), genshin_font_origin(28), anchor='rm')
artifacts_text.text((55, 219), '+{}'.format(str(mainLevel)), (255, 255, 255), genshin_font_origin(24), anchor='mm')
artifactsScore = 0
for index,i in enumerate(aritifact['reliquarySubstats']):
subName = i['statName']
subValue = i['statValue']
if subName in ['攻击力', '血量', '防御力', '元素精通']:
subValueStr = str(subValue)
if subName == '血量':
artifactsScore += subValue * 0.014
elif subName == '攻击力':
artifactsScore += subValue * 0.12
elif subName == '防御力':
artifactsScore += subValue * 0.18
elif subName == '元素精通':
artifactsScore += subValue * 0.25
else:
subValueStr = str(subValue) + '%'
if subName == '暴击率':
artifactsScore += subValue * 2
elif subName == '暴击伤害':
artifactsScore += subValue * 1
elif subName == '元素精通':
artifactsScore += subValue * 0.25
elif subName == '元素充能效率':
artifactsScore += subValue * 0.65
elif subName == '百分比血量':
artifactsScore += subValue * 0.86
elif subName == '百分比攻击力':
artifactsScore += subValue * 1
elif subName == '百分比防御力':
artifactsScore += subValue * 0.7
artifacts_text.text((20, 263 + index*30), '·{}+{}'.format(subName, subValueStr), (255, 255, 255), genshin_font_origin(25), anchor='lm')
artifactsAllScore += artifactsScore
artifacts_text.text((268, 190), f'{math.ceil(artifactsScore)}', (255, 255, 255), genshin_font_origin(23), anchor='rm')
if artifactsPos == '生之花':
img.paste(artifacts_img, (18, 1075), artifacts_img)
elif artifactsPos == '死之羽':
img.paste(artifacts_img, (318, 1075), artifacts_img)
elif artifactsPos == '时之沙':
img.paste(artifacts_img, (618, 1075), artifacts_img)
elif artifactsPos == '空之杯':
img.paste(artifacts_img, (18, 1447), artifacts_img)
elif artifactsPos == '理之冠':
img.paste(artifacts_img, (318, 1447), artifacts_img)
char_name = raw_data['avatarName']
char_level = raw_data['avatarLevel']
char_fetter = raw_data['avatarFetter']
# 评分算法
# 圣遗物总分 + 角色等级 + (a+e+q)*4 + 武器等级 * 1+(武器精炼数 -1 * 0.25
charAllScore = artifactsAllScore + int(char_level) + \
(a_skill_level + e_skill_level + q_skill_level) * 4 + \
int(weaponLevel) * (1 + ((int(weaponAffix) - 1) * 0.25))
# 角色基本信息
img_text = ImageDraw.Draw(img)
img_text.text((411, 72), char_name, (255, 255, 255), genshin_font_origin(55), anchor='lm')
img_text.text((411, 122), '等级{}'.format(char_level), (255, 255, 255), genshin_font_origin(40), anchor='lm')
img_text.text((747, 126), str(char_fetter), (255, 255, 255), genshin_font_origin(28), anchor='lm')
# aeq
#img_text.text((110, 771), a_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
img_text.text((103, 812), f'{str(a_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
#img_text.text((110, 872), e_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
img_text.text((103, 915), f'{str(e_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
#img_text.text((110, 973), q_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
img_text.text((103, 1016), f'{str(q_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
fight_prop = raw_data['avatarFightProp']
hp = fight_prop['hp']
attack = fight_prop['atk']
defense = fight_prop['def']
em = fight_prop['elementalMastery']
critrate = fight_prop['critRate']
critdmg = fight_prop['critDmg']
ce = fight_prop['energyRecharge']
dmgBonus = fight_prop['dmgBonus']
hp_green = fight_prop['addHp']
attack_green = fight_prop['addAtk']
defense_green = fight_prop['addDef']
# 属性
img_text.text((785, 174), str(round(hp)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 227), str(round(attack)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 280), str(round(defense)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 333), str(round(em)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 386), f'{str(round(critrate*100,2))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 439), f'{str(round(critdmg*100,2))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 492), f'{str(round(ce*100,1))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((785, 545), f'{str(round(dmgBonus*100,1))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
img_text.text((805, 174), f'(+{str(round(hp_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
img_text.text((805, 227), f'(+{str(round(attack_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
img_text.text((805, 280), f'(+{str(round(defense_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
uid = raw_data['playerUid']
data_time = raw_data['dataTime']
# uid
img_text.text((350, 1035), f'UID{uid}', (255, 255, 255), genshin_font_origin(24), anchor='rm')
# 数据最后更新时间
img_text.text((780, 600), f'数据最后更新于{data_time}', (255, 255, 255), genshin_font_origin(22), anchor='rm')
# 角色评分
img_text.text((904, 1505), f'圣遗物总分', (255, 255, 255), genshin_font_origin(45), anchor='rm')
img_text.text((904, 1570), f'{round(artifactsAllScore, 1)}', (255, 255, 255), genshin_font_origin(60), anchor='rm')
img_text.text((904, 1655), f'角色评分', (255, 255, 255), genshin_font_origin(45), anchor='rm')
img_text.text((904, 1720), f'{round(charAllScore, 1)}', (255, 255, 255), genshin_font_origin(60), anchor='rm')
img = img.convert('RGB')
result_buffer = BytesIO()
img.save(result_buffer, format='JPEG', subsampling=0, quality=90)
#img.save(R_PATH / 'result.png', format='JPEG', subsampling=0, quality=90)
img.save(result_buffer, format='PNG')
imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode()
resultmes = imgmes
return resultmes

230
enkaToData/enkaToData.py Normal file
View File

@ -0,0 +1,230 @@
from pathlib import Path
from typing import Optional
import httpx
import json
import time
R_PATH = Path(__file__).parents[0]
MAP_PATH = R_PATH / 'map'
ICON_PATH = R_PATH / 'icon'
DATA_PATH = R_PATH / 'data'
PLAYER_PATH = R_PATH / 'player'
verison = '2.7.0'
avatarName2Element_fileName = f'avatarName2Element_mapping_{verison}.json'
weaponHash2Name_fileName = f'weaponHash2Name_mapping_{verison}.json'
weaponHash2Type_fileName = f'weaponHash2Type_mapping_{verison}.json'
skillId2Name_fileName = f'skillId2Name_mapping_{verison}.json'
talentId2Name_fileName = f'talentId2Name_mapping_{verison}.json'
avatarId2Name_fileName = f'avatarId2Name_mapping_{verison}.json'
with open(MAP_PATH / avatarId2Name_fileName, "r", encoding='UTF-8') as f:
avatarId2Name = json.load(f)
with open(MAP_PATH / 'icon2Name_mapping_2.6.0.json', "r", encoding='UTF-8') as f:
icon2Name = json.load(f)
with open(MAP_PATH / 'artifact2attr_mapping_2.6.0.json', "r", encoding='UTF-8') as f:
artifact2attr = json.load(f)
with open(MAP_PATH / 'propId2Name_mapping.json', "r", encoding='UTF-8') as f:
propId2Name = json.load(f)
with open(MAP_PATH / weaponHash2Name_fileName, "r", encoding='UTF-8') as f:
weaponHash2Name = json.load(f)
with open(MAP_PATH / weaponHash2Type_fileName, "r", encoding='UTF-8') as f:
weaponHash2Type = json.load(f)
with open(MAP_PATH / 'artifactId2Piece_mapping.json', "r", encoding='UTF-8') as f:
artifactId2Piece = json.load(f)
with open(MAP_PATH / skillId2Name_fileName, "r", encoding='UTF-8') as f:
skillId2Name = json.load(f)
with open(MAP_PATH / talentId2Name_fileName, "r", encoding='UTF-8') as f:
talentId2Name = json.load(f)
with open(MAP_PATH / avatarName2Element_fileName,'r', encoding='UTF-8') as f:
avatarName2Element = json.load(f)
async def enkaToData(uid: str, enka_data: Optional[dict] = None) -> dict:
if enka_data:
pass
else:
enka_data = json.loads(httpx.get(f'https://enka.shinshin.moe/u/{str(uid)}/__data.json').text)
if enka_data == {}:
return enka_data
now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
playerInfo = enka_data['playerInfo']
path = PLAYER_PATH / str(uid)
path.mkdir(parents=True, exist_ok=True)
with open(path / '{}.json'.format(str(uid)),'w', encoding='UTF-8') as file:
json.dump(playerInfo, file, ensure_ascii=False)
with open(path / 'rawData.json','w', encoding='UTF-8') as file:
json.dump(enka_data, file, ensure_ascii=False)
if 'avatarInfoList' not in enka_data:
return f'UID{uid}刷新失败!未打开角色展柜!'
char_name_list = []
for char in enka_data['avatarInfoList']:
# 处理基本信息
char_data = {}
avatarId = char['avatarId']
char_data['playerUid'] = str(uid)
char_data['playerName'] = enka_data['playerInfo']['nickname']
char_data['avatarId'] = avatarId
avatarName = avatarId2Name[str(char['avatarId'])]
char_data['avatarName'] = avatarId2Name[str(char['avatarId'])]
char_name_list.append(char_data['avatarName'])
char_data['avatarFetter'] = char['fetterInfo']['expLevel']
char_data['avatarLevel'] = char['propMap']['4001']['val']
try:
char_data['avatarElement'] = avatarName2Element[char_data['avatarName']]
except KeyError:
check = skillId2Name['Name'][str(list(char['skillLevelMap'].keys())[0])]
if '' in check :
char_data['avatarElement'] = 'Anemo'
elif '' in check :
char_data['avatarElement'] = 'Electro'
elif '' in check :
char_data['avatarElement'] = 'Geo'
elif '' in check :
char_data['avatarElement'] = 'Dendro'
elif '' in check :
char_data['avatarElement'] = 'Cryo'
elif '' in check :
char_data['avatarElement'] = 'Hydro'
else:
char_data['avatarElement'] = 'Pyro'
char_data['dataTime'] = now
char_data['avatarSkill'] = []
# 处理天赋
for skill in char['skillLevelMap']:
skill_temp = {}
skill_temp['skillId'] = skill
skill_temp['skillName'] = skillId2Name['Name'][skill_temp['skillId']]
skill_temp['skillLevel'] = char['skillLevelMap'][skill]
skill_temp['skillIcon'] = skillId2Name['Icon'][skill_temp['skillId']]
char_data['avatarSkill'].append(skill_temp)
char_data['avatarEnName'] = char_data['avatarSkill'][-1]['skillIcon'].split('_')[-2]
# 处理命座
talent_temp = []
if 'talentIdList' in char:
talentTemp = {}
for index,talent in enumerate(char['talentIdList']):
talentTemp['talentId'] = char['talentIdList'][index]
talentTemp['talentName'] = talentId2Name['Name'][str(talent)]
talentTemp['talentIcon'] = talentId2Name['Icon'][str(talent)]
talent_temp.append(talentTemp)
char_data['talentList'] = talent_temp
# 处理属性
fight_prop = {}
# 血量
fight_prop['hp'] = char["fightPropMap"]["2000"]
fight_prop['baseHp'] = char["fightPropMap"]["1"]
fight_prop['addHp'] = char["fightPropMap"]["2000"] - char["fightPropMap"]["1"]
# 攻击力
fight_prop['atk'] = char["fightPropMap"]["2001"]
fight_prop['baseAtk'] = char["fightPropMap"]["4"]
fight_prop['addAtk'] = char["fightPropMap"]["2001"] - char["fightPropMap"]["4"]
# 防御力
fight_prop['def'] = char["fightPropMap"]["2002"]
fight_prop['baseDef'] = char["fightPropMap"]["7"]
fight_prop['addDef'] = char["fightPropMap"]["2002"] - char["fightPropMap"]["7"]
# 元素精通
fight_prop['elementalMastery'] = char["fightPropMap"]["28"]
# 暴击率
fight_prop['critRate'] = char["fightPropMap"]["20"]
# 暴击伤害
fight_prop['critDmg'] = char["fightPropMap"]["22"]
# 充能效率
fight_prop['energyRecharge'] = char["fightPropMap"]["23"]
# 治疗&受治疗
fight_prop['healBonus'] = char["fightPropMap"]["26"]
fight_prop['healedBonus'] = char["fightPropMap"]["27"]
# 物理伤害加成 & 抗性
fight_prop['physicalDmgSub'] = char["fightPropMap"]["29"]
fight_prop['physicalDmgBonus'] = char["fightPropMap"]["30"]
# 伤害加成
for i in range(40,47):
if char["fightPropMap"][str(i)] > 0:
fight_prop['dmgBonus'] = char["fightPropMap"][str(i)]
break
else:
fight_prop['dmgBonus'] = 0
char_data['avatarFightProp'] = fight_prop
# 处理武器
weapon_info = {}
weapon_data = char['equipList'][-1]
weapon_info['itemId'] = weapon_data['itemId']
weapon_info['nameTextMapHash'] = weapon_data['flat']['nameTextMapHash']
weapon_info['weaponIcon'] = weapon_data['flat']['icon']
weapon_info['weaponType'] = weaponHash2Type[weapon_info['nameTextMapHash']]
weapon_info['weaponName'] = weaponHash2Name[weapon_info['nameTextMapHash']]
weapon_info['weaponStar'] = weapon_data['flat']['rankLevel']
# 防止未精炼
if 'promoteLevel' in weapon_data['weapon']:
weapon_info['promoteLevel'] = weapon_data['weapon']['promoteLevel']
else:
weapon_info['promoteLevel'] = 0
weapon_info['weaponLevel'] = weapon_data['weapon']['level']
if 'affixMap' in weapon_data['weapon']:
weapon_info['weaponAffix'] = list(weapon_data['weapon']['affixMap'].values())[0] + 1
else:
weapon_info['weaponAffix'] = 1
weapon_info['weaponStats'] = []
for k in weapon_data['flat']['weaponStats']:
weapon_prop_temp = {}
weapon_prop_temp['appendPropId'] = k['appendPropId']
weapon_prop_temp['statName'] = propId2Name[k['appendPropId']]
weapon_prop_temp['statValue'] = k['statValue']
weapon_info['weaponStats'].append(weapon_prop_temp)
# 武器特效须请求API
effect_raw = json.loads(httpx.get('https://info.minigg.cn/weapons?query={}'.format(weapon_info['weaponName'])).text)
if 'effect' in effect_raw:
effect = effect_raw['effect'].format(*effect_raw['r{}'.format(str(weapon_info['weaponAffix']))])
else:
effect = '无特效。'
weapon_info['weaponEffect'] = effect
char_data['weaponInfo'] = weapon_info
# 处理圣遗物
artifacts_info = []
artifacts_data = char['equipList'][:-1]
for artifact in artifacts_data:
artifact_temp = {}
artifact_temp['itemId'] = artifact['itemId']
artifact_temp['nameTextMapHash'] = artifact['flat']['nameTextMapHash']
artifact_temp['icon'] = artifact['flat']['icon']
artifact_temp['aritifactName'] = icon2Name[artifact['flat']['icon']]
artifact_temp['aritifactSetsName'] = artifact2attr['mapping'][artifact_temp['aritifactName']]
artifact_temp['aritifactSetPiece'] = artifactId2Piece[artifact_temp['icon'].split('_')[-1]][0]
artifact_temp['aritifactPieceName'] = artifactId2Piece[artifact_temp['icon'].split('_')[-1]][1]
artifact_temp['aritifactStar'] = artifact['flat']['rankLevel']
artifact_temp['aritifactLevel'] = artifact['reliquary']['level'] - 1
artifact_temp['reliquaryMainstat'] = artifact['flat']['reliquaryMainstat']
artifact_temp['reliquaryMainstat']['statName'] = propId2Name[artifact_temp['reliquaryMainstat']['mainPropId']]
artifact_temp['reliquarySubstats'] = artifact['flat']['reliquarySubstats']
for sub in artifact_temp['reliquarySubstats']:
sub['statName'] = propId2Name[sub['appendPropId']]
artifacts_info.append(artifact_temp)
char_data['equipList'] = artifacts_info
with open(path / '{}.json'.format(avatarName),'w', encoding='UTF-8') as file:
json.dump(char_data, file, ensure_ascii=False)
char_name_list_str = ','.join(char_name_list)
return f'UID{uid}刷新成功!刷新角色:{char_name_list_str}'

View File

@ -0,0 +1 @@
{"1": "FIGHT_PROP_BASE_HP", "2": "FIGHT_PROP_HP", "3": "FIGHT_PROP_HP_PERCENT", "4": "FIGHT_PROP_BASE_ATTACK", "5": "FIGHT_PROP_ATTACK", "6": "FIGHT_PROP_ATTACK_PERCENT", "7": "FIGHT_PROP_BASE_DEFENSE", "8": "FIGHT_PROP_DEFENSE", "9": "FIGHT_PROP_DEFENSE_PERCENT", "10": "FIGHT_PROP_BASE_SPEED", "11": "FIGHT_PROP_SPEED_PERCENT", "12": "FIGHT_PROP_HP_MP_PERCENT", "13": "FIGHT_PROP_ATTACK_MP_PERCENT", "20": "FIGHT_PROP_CRITICAL", "21": "FIGHT_PROP_ANTI_CRITICAL", "22": "FIGHT_PROP_CRITICAL_HURT", "23": "FIGHT_PROP_CHARGE_EFFICIENCY", "24": "FIGHT_PROP_ADD_HURT", "25": "FIGHT_PROP_SUB_HURT", "26": "FIGHT_PROP_HEAL_ADD", "27": "FIGHT_PROP_HEALED_ADD", "28": "FIGHT_PROP_ELEMENT_MASTERY", "29": "FIGHT_PROP_PHYSICAL_SUB_HURT", "30": "FIGHT_PROP_PHYSICAL_ADD_HURT", "31": "FIGHT_PROP_DEFENCE_IGNORE_RATIO", "32": "FIGHT_PROP_DEFENCE_IGNORE_DELTA", "40": "FIGHT_PROP_FIRE_ADD_HURT", "41": "FIGHT_PROP_ELEC_ADD_HURT", "42": "FIGHT_PROP_WATER_ADD_HURT", "43": "FIGHT_PROP_GRASS_ADD_HURT", "44": "FIGHT_PROP_WIND_ADD_HURT", "45": "FIGHT_PROP_ROCK_ADD_HURT", "46": "FIGHT_PROP_ICE_ADD_HURT", "47": "FIGHT_PROP_HIT_HEAD_ADD_HURT", "50": "FIGHT_PROP_FIRE_SUB_HURT", "51": "FIGHT_PROP_ELEC_SUB_HURT", "52": "FIGHT_PROP_WATER_SUB_HURT", "53": "FIGHT_PROP_GRASS_SUB_HURT", "54": "FIGHT_PROP_WIND_SUB_HURT", "55": "FIGHT_PROP_ROCK_SUB_HURT", "56": "FIGHT_PROP_ICE_SUB_HURT", "60": "FIGHT_PROP_EFFECT_HIT", "61": "FIGHT_PROP_EFFECT_RESIST", "62": "FIGHT_PROP_FREEZE_RESIST", "63": "FIGHT_PROP_TORPOR_RESIST", "64": "FIGHT_PROP_DIZZY_RESIST", "65": "FIGHT_PROP_FREEZE_SHORTEN", "66": "FIGHT_PROP_TORPOR_SHORTEN", "67": "FIGHT_PROP_DIZZY_SHORTEN", "70": "FIGHT_PROP_MAX_FIRE_ENERGY", "71": "FIGHT_PROP_MAX_ELEC_ENERGY", "72": "FIGHT_PROP_MAX_WATER_ENERGY", "73": "FIGHT_PROP_MAX_GRASS_ENERGY", "74": "FIGHT_PROP_MAX_WIND_ENERGY", "75": "FIGHT_PROP_MAX_ICE_ENERGY", "76": "FIGHT_PROP_MAX_ROCK_ENERGY", "80": "FIGHT_PROP_SKILL_CD_MINUS_RATIO", "81": "FIGHT_PROP_SHIELD_COST_MINUS_RATIO", "1000": "FIGHT_PROP_CUR_FIRE_ENERGY", "1001": "FIGHT_PROP_CUR_ELEC_ENERGY", "1002": "FIGHT_PROP_CUR_WATER_ENERGY", "1003": "FIGHT_PROP_CUR_GRASS_ENERGY", "1004": "FIGHT_PROP_CUR_WIND_ENERGY", "1005": "FIGHT_PROP_CUR_ICE_ENERGY", "1006": "FIGHT_PROP_CUR_ROCK_ENERGY", "1010": "FIGHT_PROP_CUR_HP", "2000": "FIGHT_PROP_MAX_HP", "2001": "FIGHT_PROP_CUR_ATTACK", "2002": "FIGHT_PROP_CUR_DEFENSE", "2003": "FIGHT_PROP_CUR_SPEED", "3000": "FIGHT_PROP_NONEXTRA_ATTACK", "3001": "FIGHT_PROP_NONEXTRA_DEFENSE", "3002": "FIGHT_PROP_NONEXTRA_CRITICAL", "3003": "FIGHT_PROP_NONEXTRA_ANTI_CRITICAL", "3004": "FIGHT_PROP_NONEXTRA_CRITICAL_HURT", "3005": "FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY", "3006": "FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY", "3007": "FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT", "3008": "FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT", "3009": "FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT", "3010": "FIGHT_PROP_NONEXTRA_WATER_ADD_HURT", "3011": "FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT", "3012": "FIGHT_PROP_NONEXTRA_WIND_ADD_HURT", "3013": "FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT", "3014": "FIGHT_PROP_NONEXTRA_ICE_ADD_HURT", "3015": "FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT", "3016": "FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT", "3017": "FIGHT_PROP_NONEXTRA_WATER_SUB_HURT", "3018": "FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT", "3019": "FIGHT_PROP_NONEXTRA_WIND_SUB_HURT", "3020": "FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT", "3021": "FIGHT_PROP_NONEXTRA_ICE_SUB_HURT", "3022": "FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO", "3023": "FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO", "3024": "FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Some files were not shown because too many files have changed in this diff Show More