mirror of
https://github.com/PaiGramTeam/PaiGram.git
synced 2025-02-08 03:09:04 +00:00
⚡️ 提升 avatars-list
的性能
并发获取角色详情 Signed-off-by: Karako <karakohear@gmail.com>
This commit is contained in:
parent
7c34167ff4
commit
e524a1b8bb
@ -1,5 +1,6 @@
|
|||||||
"""练度统计"""
|
"""练度统计"""
|
||||||
from typing import Iterable, List, Optional, Sequence
|
import asyncio
|
||||||
|
from typing import Iterable, List, Optional, Sequence, Tuple
|
||||||
|
|
||||||
from arkowrapper import ArkoWrapper
|
from arkowrapper import ArkoWrapper
|
||||||
from enkanetwork import Assets as EnkaAssets, EnkaNetworkAPI
|
from enkanetwork import Assets as EnkaAssets, EnkaNetworkAPI
|
||||||
@ -61,52 +62,69 @@ class AvatarListPlugin(Plugin, BasePlugin):
|
|||||||
else:
|
else:
|
||||||
await message.reply_text("此功能需要绑定<code>cookie</code>后使用,请先私聊派蒙进行绑定", parse_mode=ParseMode.HTML)
|
await message.reply_text("此功能需要绑定<code>cookie</code>后使用,请先私聊派蒙进行绑定", parse_mode=ParseMode.HTML)
|
||||||
|
|
||||||
async def get_avatars_data(self, characters: Sequence[Character], client: Client, max_length: int = None):
|
async def get_avatar_data(self, character: Character, client: Client) -> Optional["AvatarData"]:
|
||||||
avatar_datas: List[AvatarData] = []
|
detail = None
|
||||||
for num, character in enumerate(characters):
|
for _ in range(5):
|
||||||
if num == max_length: # 若已经有 max_length 个角色
|
|
||||||
break
|
|
||||||
try:
|
try:
|
||||||
detail = await client.get_character_details(character)
|
detail = await client.get_character_details(character)
|
||||||
except Exception as e: # pylint: disable=W0703
|
except Exception as e: # pylint: disable=W0703
|
||||||
|
if isinstance(e, GenshinException) and "Too Many Requests" in e.msg:
|
||||||
|
await asyncio.sleep(0.2)
|
||||||
|
continue
|
||||||
if character.name != "旅行者":
|
if character.name != "旅行者":
|
||||||
raise e
|
raise e
|
||||||
logger.debug(f"解析旅行者数据时遇到了错误:{e}")
|
logger.debug(f"解析旅行者数据时遇到了错误:{e}")
|
||||||
continue
|
return None
|
||||||
if character.id == 10000005: # 针对男草主
|
if detail is None:
|
||||||
talents = []
|
logger.warning(f"解析[bold]{character.name}[/]的数据时遇到了错误:Too Many Requests", extra={"markup": True})
|
||||||
for talent in detail.talents:
|
return None
|
||||||
if "普通攻击" in talent.name:
|
if character.id == 10000005: # 针对男草主
|
||||||
talent.Config.allow_mutation = True
|
talents = []
|
||||||
# noinspection Pydantic
|
for talent in detail.talents:
|
||||||
talent.group_id = 1131
|
if "普通攻击" in talent.name:
|
||||||
if talent.type in ["attack", "skill", "burst"]:
|
talent.Config.allow_mutation = True
|
||||||
talents.append(talent)
|
# noinspection Pydantic
|
||||||
else:
|
talent.group_id = 1131
|
||||||
talents = [t for t in detail.talents if t.type in ["attack", "skill", "burst"]]
|
if talent.type in ["attack", "skill", "burst"]:
|
||||||
buffed_talents = []
|
talents.append(talent)
|
||||||
for constellation in filter(lambda x: x.pos in [3, 5], character.constellations[: character.constellation]):
|
else:
|
||||||
if result := list(
|
talents = [t for t in detail.talents if t.type in ["attack", "skill", "burst"]]
|
||||||
filter(lambda x: all([x.name in constellation.effect]), talents) # pylint: disable=W0640
|
buffed_talents = []
|
||||||
):
|
for constellation in filter(lambda x: x.pos in [3, 5], character.constellations[: character.constellation]):
|
||||||
buffed_talents.append(result[0].type)
|
if result := list(
|
||||||
avatar_datas.append(
|
filter(lambda x: all([x.name in constellation.effect]), talents) # pylint: disable=W0640
|
||||||
AvatarData(
|
):
|
||||||
avatar=character,
|
buffed_talents.append(result[0].type)
|
||||||
detail=detail,
|
return AvatarData(
|
||||||
icon=(await self.assets_service.avatar(character.id).side()).as_uri(),
|
avatar=character,
|
||||||
weapon=(
|
detail=detail,
|
||||||
await self.assets_service.weapon(character.weapon.id).__getattr__(
|
icon=(await self.assets_service.avatar(character.id).side()).as_uri(),
|
||||||
"icon" if character.weapon.ascension < 2 else "awaken"
|
weapon=(
|
||||||
)()
|
await self.assets_service.weapon(character.weapon.id).__getattr__(
|
||||||
).as_uri(),
|
"icon" if character.weapon.ascension < 2 else "awaken"
|
||||||
skills=[
|
)()
|
||||||
SkillData(skill=s, buffed=s.type in buffed_talents)
|
).as_uri(),
|
||||||
for s in sorted(talents, key=lambda x: ["attack", "skill", "burst"].index(x.type))
|
skills=[
|
||||||
],
|
SkillData(skill=s, buffed=s.type in buffed_talents)
|
||||||
)
|
for s in sorted(talents, key=lambda x: ["attack", "skill", "burst"].index(x.type))
|
||||||
)
|
],
|
||||||
return avatar_datas
|
)
|
||||||
|
|
||||||
|
async def get_avatars_data(
|
||||||
|
self, characters: Sequence[Character], client: Client, max_length: int = None
|
||||||
|
) -> List["AvatarData"]:
|
||||||
|
task_result: List[Tuple[int, AvatarData]] = []
|
||||||
|
|
||||||
|
async def _task(c, n):
|
||||||
|
if (result := await self.get_avatar_data(c, client)) is not None:
|
||||||
|
task_result.append((n, result))
|
||||||
|
|
||||||
|
task_list = []
|
||||||
|
for num, character in enumerate(characters[:max_length]):
|
||||||
|
task_list.append(asyncio.create_task(_task(character, num)))
|
||||||
|
|
||||||
|
await asyncio.gather(*task_list)
|
||||||
|
return list(map(lambda x: x[1], sorted(task_result, key=lambda x: x[0])))
|
||||||
|
|
||||||
async def get_final_data(self, client: Client, characters: Sequence[Character], update: Update):
|
async def get_final_data(self, client: Client, characters: Sequence[Character], update: Update):
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user