Skip to content

Commit

Permalink
✨ 支持网页控制台调整从米游社更新角色面板 (#641)
Browse files Browse the repository at this point in the history
  • Loading branch information
KimigaiiWuyi committed Aug 15, 2024
1 parent 9d4270d commit 426540c
Show file tree
Hide file tree
Showing 10 changed files with 738 additions and 5 deletions.
5 changes: 5 additions & 0 deletions GenshinUID/genshinuid_config/config_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,9 @@
'修改帮助图有多少列',
'6',
),
'EnableCharCardByMys': GsBoolConfig(
'从米游社获取面板替代Enka服务',
'开启后角色卡片将从米游社获取, 可能会遇到验证码',
False,
),
}
9 changes: 8 additions & 1 deletion GenshinUID/genshinuid_enka/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from ..utils.convert import get_uid
from .get_akasha_data import get_rank
from .start import refresh_player_list
from .to_data_by_mys import mys_to_card
from .draw_artifacts_lib import draw_lib
from .draw_rank_list import draw_rank_img
from ..utils.image.convert import convert_img
Expand All @@ -24,10 +25,13 @@
from .draw_char_info import draw_all_char_list
from .draw_char_rank import draw_cahrcard_list
from .draw_role_rank import draw_role_rank_img
from ..genshinuid_config.gs_config import gsconfig
from .get_enka_img import draw_enka_img, get_full_char
from ..genshinuid_enka.start import check_artifacts_list
from ..utils.resource.RESOURCE_PATH import TEMP_PATH, PLAYER_PATH

EnableCharCardByMys = gsconfig.get_config('EnableCharCardByMys').data

sv_enka_admin = SV('面板管理', pm=1)
sv_enka_config = SV('面板设置', pm=2)
sv_akasha = SV('排名查询', priority=10)
Expand Down Expand Up @@ -332,7 +336,10 @@ async def send_card_info(bot: Bot, ev: Event):
if uid is None:
return await bot.send(UID_HINT)
logger.info('[强制刷新]uid: {}'.format(uid))
im = await enka_to_card(uid)
if EnableCharCardByMys:
im = await mys_to_card(uid)
else:
im = await enka_to_card(uid)
logger.info(f'UID{uid}获取角色数据成功!')

if isinstance(im, Tuple):
Expand Down
273 changes: 273 additions & 0 deletions GenshinUID/genshinuid_enka/to_data_by_mys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
import json
from datetime import datetime
from typing import Dict, List, Tuple, Union

import aiofiles
from gsuid_core.utils.error_reply import get_error

from .to_card import pic_500, draw_enka_card
from ..utils.image.convert import convert_img
from ..utils.mys_api import mys_api, get_base_data
from ..utils.map.name_covert import avatarId_to_enName
from ..utils.resource.RESOURCE_PATH import PLAYER_PATH
from ..utils.map.GS_MAP_PATH import (
Id2PropId,
name2Icon,
propId2Name,
skillId2Name,
talentId2Name,
)

elementMap = {
'Anemo': 44,
'Geo': 45,
'Dendro': 43,
'Pyro': 40,
'Hydro': 42,
'Cryo': 46,
'Electro': 41,
}

posMap = {
"空之杯": "goblet",
"死之羽": "plume",
"理之冠": "circlet",
"生之花": "flower",
"时之沙": "sands",
}


def get_value(value: str):
if not value:
return 0
return float(value.replace('%', ''))


async def mys_to_data(uid: str):
path = PLAYER_PATH / uid

raw_data = await get_base_data(uid)
if isinstance(raw_data, (str, bytes)):
return raw_data
elif isinstance(raw_data, (bytearray, memoryview)):
return bytes(raw_data)

char_data = raw_data['avatars']
char_ids = []
for i in char_data:
char_ids.append(i['id'])
data = await mys_api.get_char_detail_data(uid, char_ids)
if isinstance(data, int):
return get_error(data)

now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
skill_icon_map = skillId2Name['Icon']
talent_icon_map = talentId2Name['Icon']

char_dict_list = []
for char in data:
base = char['base']
avatar_name = base['name']
avatar_id = base['id']
en_name = await avatarId_to_enName(str(avatar_id))

avatar_skill = []
avatar_talent = []
avatar_fight_prop = {}
weapon_info = {}

for skill in char['skills']:
skill_id = str(skill['skill_id'])
if len(skill_id) <= 4:
continue
avatar_skill.append(
{
"skillId": skill_id,
"skillName": skill['name'],
"skillLevel": skill['level'],
"skillIcon": skill_icon_map[skill_id],
}
)

for talent in char['constellations']:
if talent['is_actived']:
talent_id = talent['id']
avatar_talent.append(
{
"talentId": talent_id,
"talentName": talent['name'],
"talentIcon": talent_icon_map[str(talent_id)],
}
)

weapon = char['weapon']
weapon_main = weapon['main_property']
main_prop_id = Id2PropId[str(weapon_main['property_type'])]
weaponStats = [
{
"appendPropId": main_prop_id,
"statName": propId2Name[main_prop_id],
"statValue": get_value(weapon_main['final']),
}
]
weapon_sub = weapon['sub_property']
if weapon_sub:
sub_prop_id = Id2PropId[str(weapon_sub['property_type'])]
weaponStats.append(
{
"appendPropId": sub_prop_id,
"statName": propId2Name[sub_prop_id],
"statValue": get_value(weapon_sub['final']),
}
)

weapon_info = {
"itemId": weapon['id'],
"nameTextMapHash": "807607555",
"weaponIcon": "UI_EquipIcon_Catalyst_Dvalin",
"weaponType": weapon['type_name'],
"weaponName": weapon['name'],
"weaponStar": weapon['rarity'],
"promoteLevel": 1,
"weaponLevel": weapon['level'],
"weaponAffix": weapon['affix_level'],
"weaponStats": weaponStats,
"weaponEffect": weapon['desc'],
}
all_prop = (
char['base_properties']
+ char['extra_properties']
+ char['element_properties']
)

element_id = elementMap.get(base['element'], 41)
for prop in all_prop:
prop_id = prop['property_type']
if prop_id == 2000:
avatar_fight_prop['baseHp'] = get_value(prop['base'])
avatar_fight_prop['addHp'] = get_value(prop['add'])
avatar_fight_prop['hp'] = get_value(prop['final'])
elif prop_id == 2001:
avatar_fight_prop['baseAtk'] = get_value(prop['base'])
avatar_fight_prop['addAtk'] = get_value(prop['add'])
avatar_fight_prop['atk'] = get_value(prop['final'])
elif prop_id == 2002:
avatar_fight_prop['baseDef'] = get_value(prop['base'])
avatar_fight_prop['addDef'] = get_value(prop['add'])
avatar_fight_prop['def'] = get_value(prop['final'])
elif prop_id == 28:
avatar_fight_prop['elementalMastery'] = get_value(
prop['final']
)
elif prop_id == 20:
avatar_fight_prop['critRate'] = get_value(prop['final'])
elif prop_id == 22:
avatar_fight_prop['critDmg'] = get_value(prop['final'])
elif prop_id == 23:
avatar_fight_prop['energyRecharge'] = get_value(prop['final'])
elif prop_id == 26:
avatar_fight_prop['healBonus'] = get_value(prop['final'])
elif prop_id == 27:
avatar_fight_prop['healedBonus'] = get_value(prop['final'])
elif prop_id == 30:
avatar_fight_prop['physicalDmgBonus'] = get_value(
prop['final']
)
elif prop_id == element_id:
avatar_fight_prop['dmgBonus'] = get_value(prop['final']) / 100

avatar_fight_prop['physicalDmgSub'] = 0

relic_list = []
artifact_set_list = []
for relic in char['relics']:
main_prop = relic['main_property']
main_prop_id = Id2PropId[str(main_prop['property_type'])]

sub_prop = relic['sub_property_list']
reliquarySubstats = []
for su in sub_prop:
sub_prop_id = Id2PropId[str(su['property_type'])]
reliquarySubstats.append(
{
"appendPropId": sub_prop_id,
"statName": propId2Name[sub_prop_id],
"statValue": get_value(su['value']),
}
)

artifact_set_list.append(relic['set']['name'])
relic_list.append(
{
"itemId": relic['id'],
"nameTextMapHash": "2007346252",
"icon": name2Icon[relic['name']],
"aritifactName": relic['name'],
"aritifactSetsName": relic['set']['name'],
"aritifactSetPiece": posMap[relic['pos_name']],
"aritifactPieceName": relic['pos_name'],
"aritifactStar": relic['rarity'],
"aritifactLevel": relic['level'],
"reliquaryMainstat": {
"mainPropId": main_prop_id,
"statValue": get_value(main_prop['value']),
"statName": propId2Name[main_prop_id],
},
"reliquarySubstats": reliquarySubstats,
}
)

equipSetList = set(artifact_set_list)
equipSets = {'type': '', 'set': ''}
for equip in equipSetList:
if artifact_set_list.count(equip) >= 4:
equipSets['type'] = '4'
equipSets['set'] = equip
break
elif artifact_set_list.count(equip) == 1:
pass
elif artifact_set_list.count(equip) >= 2:
equipSets['type'] += '2'
equipSets['set'] += '|' + equip

if equipSets['set'].startswith('|'):
equipSets['set'] = equipSets['set'][1:]

result = {
'playerUid': uid,
'playerName': raw_data['role']['nickname'],
'avatarId': avatar_id,
'avatarName': avatar_name,
'avatarFetter': base['fetter'],
'avatarLevel': str(base['level']),
'avatarElement': base['element'],
'dataTime': now,
'avatarEnName': en_name,
'avatarSkill': avatar_skill,
'talentList': avatar_talent,
'weaponInfo': weapon_info,
'avatarFightProp': avatar_fight_prop,
'equipSets': equipSets,
'equipList': relic_list,
}

char_dict_list.append(result)
async with aiofiles.open(
path / f'{avatar_name}.json', 'w', encoding='UTF-8'
) as file:
await file.write(json.dumps(result, indent=4, ensure_ascii=False))

return char_dict_list


async def mys_to_card(uid: str) -> Union[str, bytes, Tuple[bytes, List[Dict]]]:
char_data_list = await mys_to_data(uid)
if char_data_list == []:
return await convert_img(pic_500)
elif isinstance(char_data_list, str):
return char_data_list
elif isinstance(char_data_list, bytes):
return char_data_list

img = await draw_enka_card(uid=uid, char_data_list=char_data_list)
return img, char_data_list
1 change: 1 addition & 0 deletions GenshinUID/utils/api/mys/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
base_url = 'https://api-takumi-record.mihoyo.com'
widget_url = f'{base_url}/game_record/genshin/aapi/widget/v2'

This comment has been minimized.

Copy link
@ShikiSuen

ShikiSuen Sep 1, 2024

widget_url 的 game_record 與 genshin 之間可能少寫了個app

new_abyss_url = f'{base_url}/game_record/app/genshin/api/role_combat'
char_detail_url = f'{base_url}/game_record/app/genshin/api/character/detail'
Loading

0 comments on commit 426540c

Please sign in to comment.