MibooGram/plugins/tools/player_info.py

127 lines
5.1 KiB
Python
Raw Normal View History

2024-07-12 13:54:54 +00:00
from datetime import datetime, timedelta
from typing import Optional
2023-04-28 01:19:20 +00:00
2024-07-12 13:54:54 +00:00
from pydantic import BaseModel
from simnet import ZZZClient
2024-06-01 14:21:03 +00:00
2023-04-28 01:19:20 +00:00
from core.plugin import Plugin
2024-07-12 13:54:54 +00:00
from core.services.players.models import PlayersDataBase as Player
2023-04-28 01:19:20 +00:00
from core.services.players.services import PlayerInfoService, PlayersService
2024-07-12 13:54:54 +00:00
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
2023-04-28 05:21:27 +00:00
from utils.log import logger
2023-04-28 01:19:20 +00:00
2024-07-12 13:54:54 +00:00
class PlayerAvatarInfo(BaseModel, frozen=False):
player_id: int
name_card: str
avatar: str
nickname: str
level: int
2023-04-28 01:19:20 +00:00
class PlayerInfoSystem(Plugin):
def __init__(
self,
player_service: PlayersService = None,
player_info_service: PlayerInfoService = None,
2024-07-12 13:54:54 +00:00
helper: GenshinHelper = None,
redis: RedisDB = None,
2023-04-28 01:19:20 +00:00
) -> None:
self.player_service = player_service
2024-07-12 13:54:54 +00:00
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小时
2023-04-28 01:19:20 +00:00
2024-07-12 13:54:54 +00:00
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 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,
)
2024-08-14 09:13:13 +00:00
async def update_player_info(self, player: "Player", base_info: "PlayerAvatarInfo"):
2024-07-12 13:54:54 +00:00
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:
2024-08-14 09:13:13 +00:00
player_info.nickname = base_info.nickname
ex = player_info.extra_data
player_info.extra_data = ExtraPlayerInfo()
if ex is not None:
ex.copy_to(player_info.extra_data)
player_info.extra_data.level = base_info.level
player_info.extra_data.avatar = base_info.avatar
2024-07-12 13:54:54 +00:00
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)
2023-04-28 05:21:27 +00:00
try:
2024-07-12 13:54:54 +00:00
async with self.helper.genshin(player.user_id, player_id=player.player_id) as client:
client: "ZZZClient"
record_card = await client.get_record_card()
2024-08-14 09:13:13 +00:00
index = await client.get_zzz_user()
2024-07-12 13:54:54 +00:00
if record_card is not None:
base_info.nickname = record_card.nickname
base_info.level = record_card.level
2024-08-14 09:13:13 +00:00
if index is not None:
base_info.avatar = index.cur_head_icon_url
if base_info.level:
await self.update_player_info(player, base_info)
2024-07-12 13:54:54 +00:00
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
2023-04-28 05:21:27 +00:00
player_info = await self.player_info_service.get(player)
2024-07-12 13:54:54 +00:00
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:
2024-08-14 09:13:13 +00:00
base_info.nickname = player_info.nickname or ""
base_info.avatar = player_info.extra_data.avatar or base_info.avatar
base_info.level = player_info.extra_data.level or 0
2024-07-12 13:54:54 +00:00
await self.set_form_cache(base_info)
return base_info
2024-11-19 14:21:48 +00:00
async def get_theme_info(self, player_id: Optional[int], user_id: Optional[int] = None) -> PlayerAvatarInfo:
if not player_id and user_id is not None:
player = await self.player_service.get_player(user_id)
if player is None:
return self.get_base_avatar_info(0, "")
player_id = player.player_id
2024-07-12 13:54:54 +00:00
return await self.get_player_info(player_id, "")