mirror of
https://github.com/PaiGramTeam/HonkaiStarRailWikiDataParser.git
synced 2024-11-16 06:25:25 +00:00
feat: head icons
This commit is contained in:
parent
08e69236fa
commit
21eb9a999e
@ -1,19 +1,20 @@
|
||||
import asyncio
|
||||
|
||||
from res_func.avatar import fix_avatar_config, fetch_text_map
|
||||
from res_func.avatar import fix_avatar_config
|
||||
from res_func.light_cone import fix_light_cone_config
|
||||
from res_func.relic import fetch_relic_config
|
||||
from res_func.relic_res import fix_set_image
|
||||
from res_func.yatta.avatar import get_all_avatars
|
||||
from res_func.head_icon import get_head_icons
|
||||
|
||||
|
||||
async def main():
|
||||
text_map_data = await fetch_text_map()
|
||||
await fix_avatar_config(text_map_data)
|
||||
await fix_avatar_config()
|
||||
await fix_light_cone_config()
|
||||
await fetch_relic_config()
|
||||
await fix_set_image()
|
||||
await get_all_avatars()
|
||||
await get_head_icons()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
41
models/head_icon.py
Normal file
41
models/head_icon.py
Normal file
@ -0,0 +1,41 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class HeadIcon(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
desc: str
|
||||
bg_desc: str
|
||||
avatar_id: Optional[int] = None
|
||||
icons: List[str]
|
||||
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
for icon in self.icons:
|
||||
if icon:
|
||||
return icon
|
||||
|
||||
|
||||
# 原始数据
|
||||
|
||||
class ForHash(BaseModel):
|
||||
Hash: str
|
||||
|
||||
|
||||
class ItemPlayerCard(BaseModel):
|
||||
ID: int
|
||||
ItemSubType: str
|
||||
ItemName: ForHash
|
||||
ItemDesc: ForHash
|
||||
ItemBGDesc: ForHash
|
||||
|
||||
|
||||
class PlayerIcon(BaseModel):
|
||||
ID: int
|
||||
ImagePath: str
|
||||
|
||||
|
||||
class AvatarPlayerIcon(PlayerIcon):
|
||||
AvatarID: int
|
@ -18,7 +18,8 @@ async def fetch_text_map() -> Dict[str, str]:
|
||||
return await get_base_data(text_map)
|
||||
|
||||
|
||||
async def fetch_config(text_map_data: Dict[str, str]) -> List[AvatarConfig]:
|
||||
async def fetch_config() -> List[AvatarConfig]:
|
||||
text_map_data = await get_base_data(text_map)
|
||||
data = await get_base_data(avatar_config)
|
||||
datas = []
|
||||
for i in data.values():
|
||||
@ -65,6 +66,12 @@ async def dump_icons(path: Path, datas: List[AvatarIcon]):
|
||||
await f.write(ujson.dumps(data, indent=4, ensure_ascii=False))
|
||||
|
||||
|
||||
async def load_icons(path: Path) -> List[AvatarIcon]:
|
||||
async with aiofiles.open(path, "r", encoding="utf-8") as f:
|
||||
data = await f.read()
|
||||
return [AvatarIcon(**i) for i in ujson.loads(data)]
|
||||
|
||||
|
||||
async def fetch_station_ktz(tasks, datas, player_avatars: List[Tag]):
|
||||
data_map = {"开拓者·毁灭": (8001, 8002), "开拓者·存护": (8003, 8004)}
|
||||
idx = 0
|
||||
@ -105,8 +112,8 @@ async def fix_avatar_config_ktz():
|
||||
all_avatars_map[i].name = key
|
||||
|
||||
|
||||
async def fix_avatar_config(text_map_data: Dict[str, str]):
|
||||
configs = await fetch_config(text_map_data)
|
||||
async def fix_avatar_config():
|
||||
configs = await fetch_config()
|
||||
configs_map: Dict[str, AvatarConfig] = {config.name: config for config in configs}
|
||||
print(f"读取到原始数据:{list(configs_map.keys())}")
|
||||
data_path = Path("data")
|
||||
|
117
res_func/head_icon.py
Normal file
117
res_func/head_icon.py
Normal file
@ -0,0 +1,117 @@
|
||||
from pathlib import Path
|
||||
from typing import List, Dict
|
||||
|
||||
import aiofiles
|
||||
import ujson
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from models.head_icon import HeadIcon, ItemPlayerCard, PlayerIcon, AvatarPlayerIcon
|
||||
|
||||
from .avatar import load_icons
|
||||
from .base_data import get_base_data
|
||||
from .client import client
|
||||
from .url import avatar_player_icon_url, player_icon_url, item_player_card_url, text_map, icons_url, base_enka_url
|
||||
|
||||
data_path = Path("data")
|
||||
|
||||
|
||||
async def get_text_map() -> dict[str, str]:
|
||||
return await get_base_data(text_map)
|
||||
|
||||
|
||||
async def get_avatar_player_icon() -> List[AvatarPlayerIcon]:
|
||||
data = await get_base_data(avatar_player_icon_url)
|
||||
datas = []
|
||||
for i in data.values():
|
||||
datas.append(AvatarPlayerIcon(**i))
|
||||
return datas
|
||||
|
||||
|
||||
async def get_player_icon() -> List[PlayerIcon]:
|
||||
data = await get_base_data(player_icon_url)
|
||||
datas = []
|
||||
for i in data.values():
|
||||
datas.append(PlayerIcon(**i))
|
||||
return datas
|
||||
|
||||
|
||||
async def get_item_player_card() -> List[ItemPlayerCard]:
|
||||
data = await get_base_data(item_player_card_url)
|
||||
datas = []
|
||||
for i in data.values():
|
||||
datas.append(ItemPlayerCard(**i))
|
||||
return datas
|
||||
|
||||
|
||||
async def parse_station_urls() -> Dict[str, str]:
|
||||
data = await client.get(icons_url)
|
||||
soup = BeautifulSoup(data.text, "lxml")
|
||||
a_s = soup.find_all("a", {"class": "a4041 af418 a4294"})
|
||||
datas = {}
|
||||
for a in a_s:
|
||||
img = a.find("img")
|
||||
span = a.find("span")
|
||||
datas[span.get_text().strip()] = img.get("src")
|
||||
return datas
|
||||
|
||||
|
||||
async def test_enka_url(path: str) -> str:
|
||||
url = f"{base_enka_url}{path}"
|
||||
data = await client.head(url)
|
||||
if data.status_code != 200:
|
||||
return ""
|
||||
return url
|
||||
|
||||
|
||||
async def extra_head_icons(item_player_card: List[ItemPlayerCard], player_icon: List[PlayerIcon]) -> List[HeadIcon]:
|
||||
player_icon_map: Dict[int, PlayerIcon] = {i.ID: i for i in player_icon}
|
||||
text_map_ = await get_text_map()
|
||||
station_urls = await parse_station_urls()
|
||||
datas = []
|
||||
for item in item_player_card:
|
||||
if item.ItemSubType != "HeadIcon":
|
||||
continue
|
||||
id_ = item.ID
|
||||
name = text_map_[item.ItemName.Hash]
|
||||
desc = text_map_.get(item.ItemDesc.Hash, "")
|
||||
bg_desc = text_map_.get(item.ItemBGDesc.Hash, "")
|
||||
icon = player_icon_map[id_].ImagePath
|
||||
station_url = station_urls.get(name, "")
|
||||
enka_url = await test_enka_url(icon)
|
||||
icons = [station_url, enka_url]
|
||||
datas.append(HeadIcon(id=id_, name=name, desc=desc, bg_desc=bg_desc, icons=icons))
|
||||
return datas
|
||||
|
||||
|
||||
async def dump_icons(path: Path, datas: List[HeadIcon]):
|
||||
data = [icon.dict() for icon in datas]
|
||||
data.sort(key=lambda x: x["id"])
|
||||
async with aiofiles.open(path, "w", encoding="utf-8") as f:
|
||||
await f.write(ujson.dumps(data, indent=4, ensure_ascii=False))
|
||||
|
||||
|
||||
async def avatar_head_icons(avatar_player_icon: List[AvatarPlayerIcon]):
|
||||
avatar_icons = await load_icons(data_path / "avatar_icons.json")
|
||||
avatar_icons_map = {i.id: i for i in avatar_icons}
|
||||
datas = []
|
||||
for i in avatar_player_icon:
|
||||
avatar = avatar_icons_map.get(i.AvatarID)
|
||||
name = avatar.name
|
||||
station_url = avatar.icon_ or ""
|
||||
enka_url = await test_enka_url(i.ImagePath)
|
||||
icons = [station_url, enka_url]
|
||||
datas.append(HeadIcon(id=i.ID, name=name, desc="", bg_desc="", avatar_id=i.AvatarID, icons=icons))
|
||||
return datas
|
||||
|
||||
|
||||
async def get_head_icons():
|
||||
print("开始获取头像素材")
|
||||
item_player_card = await get_item_player_card()
|
||||
player_icon = await get_player_icon()
|
||||
avatar_player_icon = await get_avatar_player_icon()
|
||||
print("开始获取特殊头像")
|
||||
datas = await extra_head_icons(item_player_card, player_icon)
|
||||
print("开始获取角色头像")
|
||||
datas.extend(await avatar_head_icons(avatar_player_icon))
|
||||
await dump_icons(data_path / "head_icons.json", datas)
|
||||
print("头像素材获取完毕")
|
@ -8,13 +8,23 @@ text_map = f"{base_data_url}TextMap/TextMapCHS.json"
|
||||
relic_config = f"{base_data_url}ExcelOutput/RelicConfig.json"
|
||||
relic_main_affix_config = f"{base_data_url}ExcelOutput/RelicMainAffixConfig.json"
|
||||
relic_sub_affix_config = f"{base_data_url}ExcelOutput/RelicSubAffixConfig.json"
|
||||
avatar_player_icon_url = f"{base_data_url}ExcelOutput/AvatarPlayerIcon.json"
|
||||
player_icon_url = f"{base_data_url}ExcelOutput/PlayerIcon.json"
|
||||
item_player_card_url = f"{base_data_url}ExcelOutput/ItemPlayerCard.json"
|
||||
|
||||
|
||||
base_station_url = "https://starrailstation.com"
|
||||
avatar_url = f"{base_station_url}/cn/characters"
|
||||
light_cone_url = f"{base_station_url}/cn/equipment"
|
||||
relic_url = f"{base_station_url}/cn/relics"
|
||||
icons_url = f"{base_station_url}/cn/icons"
|
||||
|
||||
|
||||
base_yatta_url = "https://api.yatta.top"
|
||||
avatar_yatta_url = f"{base_yatta_url}/hsr/v2/cn/avatar"
|
||||
avatar_skill_url = f"{base_yatta_url}/hsr/assets/UI/skill/"
|
||||
light_cone_yatta_url = f"{base_yatta_url}/hsr/v2/cn/equipment"
|
||||
material_yatta_url = f"{base_yatta_url}/hsr/v2/cn/item"
|
||||
relic_yatta_url = f"{base_yatta_url}/hsr/v2/cn/relic"
|
||||
|
||||
base_enka_url = "https://enka.network/ui/hsr/"
|
||||
|
Loading…
Reference in New Issue
Block a user