diff --git a/model/helpers.py b/model/helpers.py index 0d24d77e..4b16cadf 100644 --- a/model/helpers.py +++ b/model/helpers.py @@ -1,14 +1,17 @@ import hashlib import os -from typing import List +from typing import List, Optional, Tuple import aiofiles +import genshin import httpx +from genshin import GenshinClient from httpx import UnsupportedProtocol from telegram import Bot from logger import Log from model.base import ServiceEnum +from service.base import UserInfoData from service.cache import RedisCache USER_AGENT: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " \ @@ -68,6 +71,19 @@ async def url_to_file(url: str, prefix: str = "file://") -> str: return prefix + file_dir +async def get_genshin_client(user_info_data: UserInfoData, game_service: Optional[ServiceEnum] = None) \ + -> Tuple[GenshinClient, int]: + if game_service is None: + game_service = user_info_data.service + if game_service == ServiceEnum.HYPERION: + client = genshin.ChineseClient(cookies=user_info_data.mihoyo_cookie) + uid = user_info_data.mihoyo_game_uid + else: + client = genshin.GenshinClient(cookies=user_info_data.hoyoverse_cookie, lang="zh-cn") + uid = user_info_data.hoyoverse_game_uid + return client, uid + + def get_server(uid: int) -> ServiceEnum: server = SERVICE_MAP.get(str(uid)[0]) if server: diff --git a/plugins/abyss.py b/plugins/abyss.py new file mode 100644 index 00000000..d9b5123e --- /dev/null +++ b/plugins/abyss.py @@ -0,0 +1,99 @@ +from telegram import Update +from telegram.constants import ChatAction +from telegram.ext import CommandHandler, MessageHandler, filters + +from logger import Log +from manager import listener_plugins_class +from model.helpers import get_genshin_client, url_to_file +from service.base import UserInfoData +from utils.base import PaimonContext + + +@listener_plugins_class() +class Abyss: + + def __init__(self, *args): + """Abyss插件入口""" + pass + + @staticmethod + def create_handlers(*args) -> list: + _ = args + abyss = Abyss() + return [ + CommandHandler("abyss", abyss.command_start, block=False), + MessageHandler(filters.Regex(r"^深渊数据查询(.*)"), abyss.command_start, block=True) + ] + + @staticmethod + def _get_role_star_bg(value: int): + if value == 4: + return "./background/roleStarBg4.png" + elif value == 5: + return "./background/roleStarBg5.png" + else: + raise ValueError("错误的数据") + + async def _get_abyss_data(self, user_info_data: UserInfoData) -> dict: + client, uid = await get_genshin_client(user_info_data) + spiral_abyss_info = await client.get_spiral_abyss(uid) + if not spiral_abyss_info.unlocked: + raise ValueError("unlocked is false") + ranks = spiral_abyss_info.ranks + abyss_data = { + "uid": uid, + "max_floor": spiral_abyss_info.max_floor, + "total_battles": spiral_abyss_info.total_battles, + "total_stars": spiral_abyss_info.total_stars, + "most_played_list": [], + "most_kills": { + "icon": await url_to_file(ranks.most_kills[0].icon), + "value": ranks.most_kills[0].value, + }, + "strongest_strike": { + "icon": await url_to_file(ranks.strongest_strike[0].icon), + "value": ranks.strongest_strike[0].value + }, + "most_damage_taken": { + "icon": await url_to_file(ranks.most_damage_taken[0].icon), + "value": ranks.most_damage_taken[0].value + }, + "most_bursts_used": { + "icon": await url_to_file(ranks.most_bursts_used[0].icon), + "value": ranks.most_bursts_used[0].value + }, + "most_skills_used": { + "icon": await url_to_file(ranks.most_skills_used[0].icon), + "value": ranks.most_skills_used[0].value + } + } + # most_kills + most_played_list = ranks.most_played + for most_played in most_played_list: + temp = { + "icon": await url_to_file(most_played.icon), + "value": most_played.value, + "background": self._get_role_star_bg(most_played.rarity) + } + abyss_data["most_played_list"].append(temp) + return abyss_data + + async def command_start(self, update: Update, context: PaimonContext) -> None: + user = update.effective_user + message = update.message + service = context.service + Log.info(f"用户 {user.full_name}[{user.id}] 查深渊挑战命令请求") + await message.reply_chat_action(ChatAction.TYPING) + user_info = await service.user_service_db.get_user_info(user.id) + try: + abyss_data = await self._get_abyss_data(user_info) + except ValueError as exc: + if "unlocked is false" in str(exc): + await message.reply_text("本次深渊旅行者还没挑战呢,咕咕咕~~~") + return + raise exc + png_data = await service.template.render('genshin/abyss', "abyss.html", abyss_data, + {"width": 690, "height": 504}, full_page=False) + await message.reply_photo(png_data, filename=f"abyss_{user.id}.png", + allow_sending_without_reply=True) + return diff --git a/resources/genshin/abyss/abyss.html b/resources/genshin/abyss/abyss.html new file mode 100644 index 00000000..60ce0751 --- /dev/null +++ b/resources/genshin/abyss/abyss.html @@ -0,0 +1,83 @@ + + +
+ +