mirror of
https://github.com/PaiGramTeam/MibooGram.git
synced 2024-11-16 04:45:27 +00:00
🐛 Fix player info system
This commit is contained in:
parent
e25bd55e48
commit
3dbc17b2a2
@ -1 +1 @@
|
||||
Subproject commit 549a40e8afe579d2448809ef566e91f84e1440f9
|
||||
Subproject commit 0ae6a4043375a50a011efd212d54bb6c9feb7b23
|
@ -1,62 +1,113 @@
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
from enkanetwork import Assets
|
||||
from pydantic import BaseModel
|
||||
from simnet import ZZZClient
|
||||
|
||||
from core.plugin import Plugin
|
||||
from core.services.players.models import PlayersDataBase as Player
|
||||
from core.services.players.services import PlayerInfoService, PlayersService
|
||||
from metadata.genshin import AVATAR_DATA
|
||||
from gram_core.dependence.redisdb import RedisDB
|
||||
from gram_core.services.players.models import ExtraPlayerInfo
|
||||
from plugins.tools.genshin import GenshinHelper
|
||||
from utils.const import RESOURCE_DIR
|
||||
from utils.log import logger
|
||||
|
||||
|
||||
class PlayerAvatarInfo(BaseModel, frozen=False):
|
||||
player_id: int
|
||||
name_card: str
|
||||
avatar: str
|
||||
nickname: str
|
||||
level: int
|
||||
|
||||
|
||||
class PlayerInfoSystem(Plugin):
|
||||
def __init__(
|
||||
self,
|
||||
player_service: PlayersService = None,
|
||||
player_info_service: PlayerInfoService = None,
|
||||
helper: GenshinHelper = None,
|
||||
redis: RedisDB = None,
|
||||
) -> None:
|
||||
self.player_info_service = player_info_service
|
||||
self.player_service = player_service
|
||||
self.player_info_service = player_info_service
|
||||
self.helper = helper
|
||||
self.cache = redis.client
|
||||
self.qname = "players_info_avatar"
|
||||
self.ttl = 1 * 60 * 60 # 1小时
|
||||
|
||||
async def get_player_info(self, player_id: int, user_id: int, user_name: str):
|
||||
player = await self.player_service.get(user_id, player_id)
|
||||
player_info = await self.player_info_service.get(player)
|
||||
nickname = user_name
|
||||
name_card: Optional[str] = None
|
||||
avatar: Optional[str] = None
|
||||
rarity: int = 5
|
||||
try:
|
||||
if player_info is not None:
|
||||
if player_info.nickname is not None:
|
||||
nickname = player_info.nickname
|
||||
if player_info.name_card is not None:
|
||||
name_card = (await self.assets_service.namecard(int(player_info.name_card)).navbar()).as_uri()
|
||||
if player_info.hand_image is not None:
|
||||
if player_info.hand_image > 10000000:
|
||||
avatar = (await self.assets_service.avatar(player_info.hand_image).icon()).as_uri()
|
||||
try:
|
||||
rarity = {k: v["rank"] for k, v in AVATAR_DATA.items()}[str(player_info.hand_image)]
|
||||
except KeyError:
|
||||
logger.warning("未找到角色 %s 的星级", player_info.hand_image)
|
||||
else:
|
||||
avatar = Assets.profile_picture(player_info.hand_image).url
|
||||
rarity = 5
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
logger.error("卡片信息请求失败 %s", str(exc))
|
||||
if name_card is None: # 默认
|
||||
name_card = (await self.assets_service.namecard(0).navbar()).as_uri()
|
||||
if avatar is None: # 默认
|
||||
avatar = (await self.assets_service.avatar(0).icon()).as_uri()
|
||||
return name_card, avatar, nickname, rarity
|
||||
async def get_form_cache(self, player_id: int) -> Optional[PlayerAvatarInfo]:
|
||||
qname = f"{self.qname}:{player_id}"
|
||||
data = await self.cache.get(qname)
|
||||
if data is None:
|
||||
return None
|
||||
json_data = str(data, encoding="utf-8")
|
||||
return PlayerAvatarInfo.parse_raw(json_data)
|
||||
|
||||
async def get_name_card(self, player_id: int, user_id: int):
|
||||
player = await self.player_service.get(user_id, player_id)
|
||||
player_info = await self.player_info_service.get(player)
|
||||
name_card: Optional[str] = None
|
||||
async def set_form_cache(self, player: PlayerAvatarInfo):
|
||||
qname = f"{self.qname}:{player.player_id}"
|
||||
await self.cache.set(qname, player.json(), ex=self.ttl)
|
||||
|
||||
@staticmethod
|
||||
def get_base_avatar_info(player_id: int, user_name: str) -> PlayerAvatarInfo:
|
||||
res = RESOURCE_DIR / "img"
|
||||
return PlayerAvatarInfo(
|
||||
player_id=player_id,
|
||||
name_card=(res / "home.png").as_uri(),
|
||||
avatar=(res / "avatar.png").as_uri(),
|
||||
nickname=user_name,
|
||||
level=0,
|
||||
)
|
||||
|
||||
async def update_player_info(self, player: "Player", nickname: str, level: int):
|
||||
player_info = await self.player_info_service.get_form_sql(player)
|
||||
if player_info is not None and player_info.create_time is not None:
|
||||
player_info.nickname = nickname
|
||||
if player_info.extra_data is None:
|
||||
player_info.extra_data = ExtraPlayerInfo()
|
||||
player_info.extra_data.level = level
|
||||
await self.player_info_service.update(player_info)
|
||||
|
||||
async def get_player_info_by_cookie(self, player: "Player", user_name: str) -> PlayerAvatarInfo:
|
||||
base_info = self.get_base_avatar_info(player.player_id, user_name)
|
||||
try:
|
||||
if player_info is not None and player_info.name_card is not None:
|
||||
name_card = (await self.assets_service.namecard(int(player_info.name_card)).navbar()).as_uri()
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
logger.error("卡片信息请求失败 %s", str(exc))
|
||||
if name_card is None: # 默认
|
||||
name_card = (await self.assets_service.namecard(0).navbar()).as_uri()
|
||||
return name_card
|
||||
async with self.helper.genshin(player.user_id, player_id=player.player_id) as client:
|
||||
client: "ZZZClient"
|
||||
record_card = await client.get_record_card()
|
||||
if record_card is not None:
|
||||
base_info.nickname = record_card.nickname
|
||||
base_info.level = record_card.level
|
||||
await self.update_player_info(player, base_info.nickname, base_info.level)
|
||||
except Exception as e:
|
||||
logger.warning("卡片信息通过 cookie 请求失败 %s", str(e))
|
||||
return base_info
|
||||
|
||||
async def get_player_info(self, player_id: int, user_name: str) -> PlayerAvatarInfo:
|
||||
cache = await self.get_form_cache(player_id)
|
||||
if cache is not None:
|
||||
return cache
|
||||
|
||||
player = await self.player_service.get(None, player_id)
|
||||
base_info = self.get_base_avatar_info(player_id, user_name)
|
||||
if not player:
|
||||
return base_info
|
||||
player_info = await self.player_info_service.get(player)
|
||||
if player_info is None or player_info.create_time is None:
|
||||
return base_info
|
||||
expiration_time = datetime.now() - timedelta(hours=2)
|
||||
if (
|
||||
player_info.last_save_time is None
|
||||
or player_info.extra_data is None
|
||||
or player_info.last_save_time <= expiration_time
|
||||
):
|
||||
base_info = await self.get_player_info_by_cookie(player, player_info.nickname)
|
||||
else:
|
||||
base_info.nickname = player_info.nickname
|
||||
base_info.level = player_info.extra_data.level
|
||||
|
||||
await self.set_form_cache(base_info)
|
||||
return base_info
|
||||
|
||||
async def get_theme_info(self, player_id: int) -> PlayerAvatarInfo:
|
||||
return await self.get_player_info(player_id, "")
|
||||
|
@ -13,7 +13,7 @@ from gram_core.services.template.services import TemplateService
|
||||
from modules.action_log.client import ActionLogAnalyse
|
||||
from plugins.tools.action_log_system import ActionLogSystem
|
||||
from plugins.tools.genshin import GenshinHelper
|
||||
from utils.const import RESOURCE_DIR
|
||||
from plugins.tools.player_info import PlayerInfoSystem
|
||||
from utils.log import logger
|
||||
from utils.uid import mask_number
|
||||
|
||||
@ -42,11 +42,13 @@ class ActionLogPlugins(Plugin):
|
||||
action_log_service: ActionLogService,
|
||||
action_log_system: ActionLogSystem,
|
||||
template_service: TemplateService,
|
||||
player_info: PlayerInfoSystem,
|
||||
):
|
||||
self.helper = helper
|
||||
self.action_log_service = action_log_service
|
||||
self.action_log_system = action_log_system
|
||||
self.template_service = template_service
|
||||
self.player_info = player_info
|
||||
|
||||
@handler.command(command="action_log_import", filters=filters.ChatType.PRIVATE, cookie=True, block=False)
|
||||
async def action_log_import(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None:
|
||||
@ -95,9 +97,9 @@ class ActionLogPlugins(Plugin):
|
||||
}
|
||||
|
||||
async def add_theme_data(self, data: Dict, player_id: int):
|
||||
res = RESOURCE_DIR / "img"
|
||||
data["avatar"] = (res / "avatar.png").as_uri()
|
||||
data["background"] = (res / "home.png").as_uri()
|
||||
theme_info = await self.player_info.get_theme_info(player_id)
|
||||
data["avatar"] = theme_info.avatar
|
||||
data["background"] = theme_info.name_card
|
||||
return data
|
||||
|
||||
async def render(self, client: "ZZZClient") -> "RenderResult":
|
||||
|
@ -19,7 +19,7 @@ from gram_core.config import config
|
||||
from gram_core.plugin.methods.inline_use_data import IInlineUseData
|
||||
from gram_core.services.template.models import RenderGroupResult
|
||||
from plugins.tools.genshin import GenshinHelper, CharacterDetails
|
||||
from utils.const import RESOURCE_DIR
|
||||
from plugins.tools.player_info import PlayerInfoSystem
|
||||
from utils.log import logger
|
||||
from utils.uid import mask_number
|
||||
|
||||
@ -69,6 +69,7 @@ class AvatarListPlugin(Plugin):
|
||||
wiki_service: WikiService = None,
|
||||
helper: GenshinHelper = None,
|
||||
character_details: CharacterDetails = None,
|
||||
player_info: PlayerInfoSystem = None,
|
||||
) -> None:
|
||||
self.cookies_service = cookies_service
|
||||
self.assets_service = assets_service
|
||||
@ -76,6 +77,7 @@ class AvatarListPlugin(Plugin):
|
||||
self.wiki_service = wiki_service
|
||||
self.helper = helper
|
||||
self.character_details = character_details
|
||||
self.player_info = player_info
|
||||
|
||||
async def get_avatar_data(self, character_id: int, client: "ZZZClient") -> Optional["ZZZCalculatorCharacter"]:
|
||||
return await self.character_details.get_character_details(client, character_id)
|
||||
@ -179,14 +181,14 @@ class AvatarListPlugin(Plugin):
|
||||
return await asyncio.gather(*tasks)
|
||||
|
||||
async def add_theme_data(self, data: Dict, player_id: int):
|
||||
res = RESOURCE_DIR / "img"
|
||||
data["avatar"] = (res / "avatar.png").as_uri()
|
||||
data["background"] = (res / "home.png").as_uri()
|
||||
theme_info = await self.player_info.get_theme_info(player_id)
|
||||
data["avatar"] = theme_info.avatar
|
||||
data["background"] = theme_info.name_card
|
||||
return data
|
||||
|
||||
async def render(self, client: "ZZZClient", all_avatars: bool = False) -> List["RenderResult"]:
|
||||
characters: List["ZZZPartialCharacter"] = await self.get_avatars_data(client)
|
||||
|
||||
player_info = await self.player_info.get_player_info(client.player_id, "")
|
||||
has_more = (not all_avatars) and len(characters) > MAX_AVATAR_COUNT
|
||||
if has_more:
|
||||
characters = characters[:MAX_AVATAR_COUNT]
|
||||
@ -194,6 +196,8 @@ class AvatarListPlugin(Plugin):
|
||||
|
||||
base_render_data = {
|
||||
"uid": mask_number(client.player_id), # 玩家uid
|
||||
"nickname": player_info.nickname, # 玩家昵称
|
||||
"level": player_info.level,
|
||||
"has_more": has_more, # 是否显示了全部角色
|
||||
}
|
||||
await self.add_theme_data(base_render_data, client.player_id)
|
||||
|
@ -32,7 +32,7 @@ from modules.gacha_log.log import GachaLog
|
||||
from modules.gacha_log.migrate import GachaLogMigrate
|
||||
from modules.gacha_log.models import GachaLogInfo
|
||||
from plugins.tools.genshin import PlayerNotFoundError
|
||||
from utils.const import RESOURCE_DIR
|
||||
from plugins.tools.player_info import PlayerInfoSystem
|
||||
from utils.log import logger
|
||||
|
||||
try:
|
||||
@ -70,6 +70,7 @@ class WishLogPlugin(Plugin.Conversation):
|
||||
players_service: PlayersService,
|
||||
assets: AssetsService,
|
||||
cookie_service: CookiesService,
|
||||
player_info: PlayerInfoSystem,
|
||||
):
|
||||
self.template_service = template_service
|
||||
self.players_service = players_service
|
||||
@ -77,6 +78,7 @@ class WishLogPlugin(Plugin.Conversation):
|
||||
self.cookie_service = cookie_service
|
||||
self.gacha_log = GachaLog()
|
||||
self.wish_photo = None
|
||||
self.player_info = player_info
|
||||
|
||||
async def get_player_id(self, user_id: int, player_id: int, offset: int) -> int:
|
||||
"""获取绑定的游戏ID"""
|
||||
@ -543,9 +545,9 @@ class WishLogPlugin(Plugin.Conversation):
|
||||
await png.edit_media(message)
|
||||
|
||||
async def add_theme_data(self, data: Dict, player_id: int):
|
||||
res = RESOURCE_DIR / "img"
|
||||
data["avatar"] = (res / "avatar.png").as_uri()
|
||||
data["background"] = (res / "home.png").as_uri()
|
||||
theme_info = await self.player_info.get_theme_info(player_id)
|
||||
data["avatar"] = theme_info.avatar
|
||||
data["background"] = theme_info.name_card
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
|
@ -1,4 +1,3 @@
|
||||
import random
|
||||
from typing import Optional, TYPE_CHECKING, List
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import filters
|
||||
@ -10,7 +9,7 @@ from core.services.template.models import RenderResult
|
||||
from core.services.template.services import TemplateService
|
||||
from gram_core.plugin.methods.inline_use_data import IInlineUseData
|
||||
from plugins.tools.genshin import GenshinHelper
|
||||
from utils.const import RESOURCE_DIR
|
||||
from plugins.tools.player_info import PlayerInfoSystem
|
||||
from utils.log import logger
|
||||
from utils.uid import mask_number
|
||||
|
||||
@ -25,9 +24,15 @@ __all__ = ("PlayerStatsPlugins",)
|
||||
class PlayerStatsPlugins(Plugin):
|
||||
"""玩家统计查询"""
|
||||
|
||||
def __init__(self, template: TemplateService, helper: GenshinHelper):
|
||||
def __init__(
|
||||
self,
|
||||
template: TemplateService,
|
||||
helper: GenshinHelper,
|
||||
player_info: PlayerInfoSystem,
|
||||
):
|
||||
self.template_service = template
|
||||
self.helper = helper
|
||||
self.player_info = player_info
|
||||
|
||||
@handler.command("stats", player=True, block=False)
|
||||
@handler.message(filters.Regex("^玩家统计查询(.*)"), player=True, block=False)
|
||||
@ -60,11 +65,13 @@ class PlayerStatsPlugins(Plugin):
|
||||
async def render(self, client: "ZZZClient", nickname: str) -> RenderResult:
|
||||
uid = client.player_id
|
||||
user_info = await client.get_zzz_user(uid)
|
||||
player_info = await self.player_info.get_player_info(uid, nickname)
|
||||
|
||||
data = {
|
||||
"uid": mask_number(uid),
|
||||
"stats": user_info.stats,
|
||||
"nickname": nickname,
|
||||
"nickname": player_info.nickname,
|
||||
"level": player_info.level,
|
||||
"stats_labels": [
|
||||
("活跃天数", "active_days"),
|
||||
("获取角色数", "avatar_num"),
|
||||
@ -112,9 +119,9 @@ class PlayerStatsPlugins(Plugin):
|
||||
await render_result.edit_inline_media(callback_query)
|
||||
|
||||
async def add_theme_data(self, data, player_id: int):
|
||||
res = RESOURCE_DIR / "img"
|
||||
data["avatar"] = (res / "avatar.png").as_uri()
|
||||
data["background"] = (res / "home.png").as_uri()
|
||||
theme_info = await self.player_info.get_theme_info(player_id)
|
||||
data["avatar"] = theme_info.avatar
|
||||
data["background"] = theme_info.name_card
|
||||
return data
|
||||
|
||||
async def get_inline_use_data(self) -> List[Optional[IInlineUseData]]:
|
||||
|
@ -33,6 +33,13 @@
|
||||
alt="Avatar"
|
||||
/>
|
||||
<div class="flex-1">
|
||||
|
||||
<div class="nickname text-4xl italic mb-2 px-2 text-light">
|
||||
{{ nickname }}
|
||||
{% if level > 0 %}
|
||||
<span class="text-lg">lv.{{ level }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="uid text-light text-2xl">UID: {{ uid }}</div>
|
||||
</div>
|
||||
<div class="z-10">
|
||||
|
@ -46,7 +46,12 @@
|
||||
<div
|
||||
class="z-10 flex-1 flex flex-col justify-center gap-y-2 text-dark"
|
||||
>
|
||||
<h1 class="bg-background text-4xl line-clamp-1">{{ nickname }}</h1>
|
||||
<h1 class="bg-background text-4xl line-clamp-1">
|
||||
{{ nickname }}
|
||||
{% if level > 0 %}
|
||||
<span class="text-lg">lv.{{ level }}</span>
|
||||
{% endif %}
|
||||
</h1>
|
||||
<h1 class="text-lg">UID: {{ uid }}</h1>
|
||||
</div>
|
||||
<div class="z-10">
|
||||
|
Loading…
Reference in New Issue
Block a user