♻️ Refactor get fight prop rule

This commit is contained in:
omg-xtao 2023-10-07 23:15:30 +08:00 committed by xtaodada
parent 833e1ddeb5
commit b52e532343
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
6 changed files with 49 additions and 22 deletions

3
.gitmodules vendored
View File

@ -2,6 +2,3 @@
path = gram_core path = gram_core
url = https://github.com/PaiGramTeam/GramCore.git url = https://github.com/PaiGramTeam/GramCore.git
branch = v4 branch = v4
[submodule "modules/playercards/metadata"]
path = modules/playercards/metadata
url = https://github.com/PaiGramTeam/FightPropRule.git

View File

@ -8,12 +8,19 @@ from httpx import URL, AsyncClient, RemoteProtocolError, Response
from utils.const import AMBR_HOST, PROJECT_ROOT from utils.const import AMBR_HOST, PROJECT_ROOT
from utils.log import logger from utils.log import logger
__all__ = ["update_metadata_from_ambr", "update_metadata_from_github", "RESOURCE_DEFAULT_PATH", "RESOURCE_FAST_URL"] __all__ = [
"update_metadata_from_ambr",
"update_metadata_from_github",
"RESOURCE_DEFAULT_PATH",
"RESOURCE_FAST_URL",
"RESOURCE_FightPropRule_URL",
]
RESOURCE_REPO = "PaiGramTeam/PaiGram_Resources" RESOURCE_REPO = "PaiGramTeam/PaiGram_Resources"
RESOURCE_BRANCH = "remote" RESOURCE_BRANCH = "remote"
RESOURCE_ROOT = "Resources" RESOURCE_ROOT = "Resources"
RESOURCE_DEFAULT_PATH = f"{RESOURCE_REPO}/{RESOURCE_BRANCH}/{RESOURCE_ROOT}/" RESOURCE_DEFAULT_PATH = f"{RESOURCE_REPO}/{RESOURCE_BRANCH}/{RESOURCE_ROOT}/"
RESOURCE_FAST_URL = f"https://genshin-res.paimon.vip/{RESOURCE_ROOT}/" RESOURCE_FAST_URL = f"https://genshin-res.paimon.vip/{RESOURCE_ROOT}/"
RESOURCE_FightPropRule_URL = "https://fightproprule.paimon.vip/"
client = AsyncClient() client = AsyncClient()

View File

@ -1,8 +1,9 @@
from typing import List, Dict from typing import List, Dict
from httpx import AsyncClient, HTTPError from httpx import AsyncClient
from metadata.scripts.metadatas import RESOURCE_FAST_URL from metadata.scripts.metadatas import RESOURCE_FAST_URL, RESOURCE_FightPropRule_URL
from utils.log import logger
class Remote: class Remote:
@ -12,6 +13,7 @@ class Remote:
CALENDAR = f"{BASE_URL}calendar.json" CALENDAR = f"{BASE_URL}calendar.json"
BIRTHDAY = f"{BASE_URL}birthday.json" BIRTHDAY = f"{BASE_URL}birthday.json"
MATERIAL = f"{BASE_URL}roles_material.json" MATERIAL = f"{BASE_URL}roles_material.json"
RULE = f"{RESOURCE_FightPropRule_URL}FightPropRule_genshin.json"
@staticmethod @staticmethod
async def get_remote_calendar() -> Dict[str, Dict]: async def get_remote_calendar() -> Dict[str, Dict]:
@ -22,7 +24,8 @@ class Remote:
if req.status_code == 200: if req.status_code == 200:
return req.json() return req.json()
return {} return {}
except HTTPError: except Exception as exc:
logger.error("获取云端日历失败: %s", exc_info=exc)
return {} return {}
@staticmethod @staticmethod
@ -34,7 +37,8 @@ class Remote:
if req.status_code == 200: if req.status_code == 200:
return req.json() return req.json()
return {} return {}
except HTTPError: except Exception as exc:
logger.error("获取云端生日失败: %s", exc_info=exc)
return {} return {}
@staticmethod @staticmethod
@ -46,5 +50,19 @@ class Remote:
if req.status_code == 200: if req.status_code == 200:
return req.json() return req.json()
return {} return {}
except HTTPError: except Exception as exc:
logger.error("获取云端角色材料失败: %s", exc_info=exc)
return {}
@staticmethod
async def get_fight_prop_rule_data() -> Dict[str, Dict[str, float]]:
"""获取云端圣遗物评分规则"""
try:
async with AsyncClient() as client:
req = await client.get(Remote.RULE)
if req.status_code == 200:
return req.json()
return {}
except Exception as exc:
logger.error("获取云端圣遗物评分规则失败: %s", exc_info=exc)
return {} return {}

View File

@ -1,18 +1,12 @@
import os from typing import Dict
import ujson as json
from enkanetwork import EquipmentsStats from enkanetwork import EquipmentsStats
from modules.playercards.fight_prop import FightProp, FightPropScore from modules.playercards.fight_prop import FightProp, FightPropScore
_project_path = os.path.dirname(__file__)
_fight_prop_rule_file = os.path.join(_project_path, "metadata", "FightPropRule_genshin.json")
with open(_fight_prop_rule_file, "r", encoding="utf-8") as f:
fight_prop_rule_data: dict = json.load(f)
class ArtifactStatsTheory: class ArtifactStatsTheory:
def __init__(self, character_name: str): def __init__(self, character_name: str, fight_prop_rule_data: Dict[str, Dict[str, float]]):
self.character_name = character_name self.character_name = character_name
self.fight_prop_rules = fight_prop_rule_data.get(self.character_name, {}) self.fight_prop_rules = fight_prop_rule_data.get(self.character_name, {})
fight_prop_rule_list = list(self.fight_prop_rules.keys()) fight_prop_rule_list = list(self.fight_prop_rules.keys())

@ -1 +0,0 @@
Subproject commit c8e481518e29aff43244afdee1048604ab1e8148

View File

@ -1,5 +1,5 @@
import math import math
from typing import Any, List, Tuple, Union, Optional, TYPE_CHECKING from typing import Any, List, Tuple, Union, Optional, TYPE_CHECKING, Dict
from enkanetwork import ( from enkanetwork import (
DigitType, DigitType,
@ -31,6 +31,7 @@ from core.plugin import Plugin, handler
from core.services.players import PlayersService from core.services.players import PlayersService
from core.services.template.services import TemplateService from core.services.template.services import TemplateService
from metadata.shortname import roleToName from metadata.shortname import roleToName
from modules.apihelper.client.components.remote import Remote
from modules.playercards.file import PlayerCardsFile from modules.playercards.file import PlayerCardsFile
from modules.playercards.helpers import ArtifactStatsTheory from modules.playercards.helpers import ArtifactStatsTheory
from utils.enkanetwork import RedisCache, EnkaNetworkAPI from utils.enkanetwork import RedisCache, EnkaNetworkAPI
@ -64,6 +65,13 @@ class PlayerCards(Plugin):
self.assets_service = assets_service self.assets_service = assets_service
self.template_service = template_service self.template_service = template_service
self.kitsune: Optional[str] = None self.kitsune: Optional[str] = None
self.fight_prop_rule: Dict[str, Dict[str, float]] = {}
async def initialize(self):
await self._refresh()
async def _refresh(self):
self.fight_prop_rule = await Remote.get_fight_prop_rule_data()
async def _update_enka_data(self, uid) -> Union[EnkaNetworkResponse, str]: async def _update_enka_data(self, uid) -> Union[EnkaNetworkResponse, str]:
try: try:
@ -193,7 +201,7 @@ class PlayerCards(Plugin):
return return
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
render_result = await RenderTemplate( render_result = await RenderTemplate(
player_info.player_id, characters, self.template_service player_info.player_id, characters, self.fight_prop_rule, self.template_service
).render() # pylint: disable=W0631 ).render() # pylint: disable=W0631
await render_result.reply_photo( await render_result.reply_photo(
message, message,
@ -313,7 +321,9 @@ class PlayerCards(Plugin):
return return
await callback_query.answer(text="正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False) await callback_query.answer(text="正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False)
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO) await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
render_result = await RenderTemplate(uid, characters, self.template_service).render() # pylint: disable=W0631 render_result = await RenderTemplate(
uid, characters, self.fight_prop_rule, self.template_service
).render() # pylint: disable=W0631
render_result.filename = f"player_card_{uid}_{result}.png" render_result.filename = f"player_card_{uid}_{result}.png"
await render_result.edit_media(message) await render_result.edit_media(message)
@ -454,12 +464,14 @@ class RenderTemplate:
self, self,
uid: Union[int, str], uid: Union[int, str],
character: "CharacterInfo", character: "CharacterInfo",
fight_prop_rule: Dict[str, Dict[str, float]],
template_service: TemplateService = None, template_service: TemplateService = None,
): ):
self.uid = uid self.uid = uid
self.template_service = template_service self.template_service = template_service
# 因为需要替换线上 enka 图片地址为本地地址,先克隆数据,避免修改原数据 # 因为需要替换线上 enka 图片地址为本地地址,先克隆数据,避免修改原数据
self.character = character.copy(deep=True) self.character = character.copy(deep=True)
self.fight_prop_rule = fight_prop_rule
async def render(self): async def render(self):
# 缓存所有图片到本地 # 缓存所有图片到本地
@ -590,7 +602,7 @@ class RenderTemplate:
def find_artifacts(self) -> List[Artifact]: def find_artifacts(self) -> List[Artifact]:
"""在 equipments 数组中找到圣遗物,并转换成带有分数的 model。equipments 数组包含圣遗物和武器""" """在 equipments 数组中找到圣遗物,并转换成带有分数的 model。equipments 数组包含圣遗物和武器"""
stats = ArtifactStatsTheory(self.character.name) stats = ArtifactStatsTheory(self.character.name, self.fight_prop_rule)
def substat_score(s: "EquipmentsStats") -> float: def substat_score(s: "EquipmentsStats") -> float:
return stats.theory(s) return stats.theory(s)