PaiGram/plugins/genshin/material.py

235 lines
10 KiB
Python
Raw Normal View History

2023-04-04 14:02:14 +00:00
import re
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
2023-04-04 14:02:14 +00:00
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, CommandHandler, MessageHandler, filters
2023-04-04 14:02:14 +00:00
from core.dependence.assets import AssetsService
from core.plugin import Plugin, handler
2023-04-04 14:02:14 +00:00
from core.services.template.services import TemplateService
from metadata.genshin import MATERIAL_DATA
2022-09-09 15:50:10 +00:00
from metadata.shortname import roleToName
2023-04-04 14:02:14 +00:00
from modules.apihelper.client.components.remote import Remote
from modules.material.talent import TalentMaterials
from modules.wiki.character import Character
from utils.log import logger
__all__ = ("MaterialPlugin",)
class MaterialPlugin(Plugin):
"""角色培养素材查询"""
KEYBOARD = [[InlineKeyboardButton(text="查看角色培养素材列表并查询", switch_inline_query_current_chat="查看角色培养素材列表并查询")]]
2023-04-04 14:02:14 +00:00
def __init__(
self,
template_service: TemplateService,
assets_service: AssetsService,
):
self.roles_material = {}
self.assets_service = assets_service
self.template_service = template_service
async def initialize(self):
await self._refresh()
async def _refresh(self):
self.roles_material = await Remote.get_remote_material()
async def _parse_material(self, data: dict, character_name: str, talent_level: str) -> dict:
data = data["data"]
if character_name not in data.keys():
return {}
character = self.assets_service.avatar(character_name)
level_up_material = self.assets_service.material(data[character_name]["level_up_materials"])
ascension_material = self.assets_service.material(data[character_name]["ascension_materials"])
local_material = self.assets_service.material(data[character_name]["materials"][0])
enemy_material = self.assets_service.material(data[character_name]["materials"][1])
level_up_materials = [
{
"num": 46,
"rarity": MATERIAL_DATA[str(level_up_material.id)]["rank"],
"icon": (await level_up_material.icon()).as_uri(),
"name": data[character_name]["level_up_materials"],
},
{
"num": 419,
"rarity": 4,
"icon": (await self.assets_service.material(104003).icon()).as_uri(),
"name": "大英雄的经验",
},
{
"num": 1,
"rarity": 2,
"icon": (await ascension_material.icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id)]["name"],
},
{
"num": 9,
"rarity": 3,
"icon": (await self.assets_service.material(ascension_material.id - 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 1)]["name"],
},
{
"num": 9,
"rarity": 4,
"icon": (await self.assets_service.material(str(ascension_material.id - 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 2)]["name"],
},
{
"num": 6,
"rarity": 5,
"icon": (await self.assets_service.material(ascension_material.id - 3).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 3)]["name"],
},
{
"num": 168,
"rarity": MATERIAL_DATA[str(local_material.id)]["rank"],
"icon": (await local_material.icon()).as_uri(),
"name": MATERIAL_DATA[str(local_material.id)]["name"],
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(enemy_material.id)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id)]["name"],
},
{
"num": 30,
"rarity": MATERIAL_DATA[str(enemy_material.id + 1)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 1)]["name"],
},
{
"num": 36,
"rarity": MATERIAL_DATA[str(enemy_material.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(enemy_material.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 2)]["name"],
},
]
talent_book = self.assets_service.material(f"{data[character_name]['talent'][0]}」的教导")
weekly_talent_material = self.assets_service.material(data[character_name]["talent"][1])
talent_materials = [
{
"num": 9,
"rarity": MATERIAL_DATA[str(talent_book.id)]["rank"],
"icon": (await self.assets_service.material(talent_book.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id)]["name"],
},
{
"num": 63,
"rarity": MATERIAL_DATA[str(talent_book.id + 1)]["rank"],
"icon": (await self.assets_service.material(talent_book.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id + 1)]["name"],
},
{
"num": 114,
"rarity": MATERIAL_DATA[str(talent_book.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(talent_book.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id + 2)]["name"],
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(enemy_material.id)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id)]["name"],
},
{
"num": 66,
"rarity": MATERIAL_DATA[str(enemy_material.id + 1)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 1)]["name"],
},
{
"num": 93,
"rarity": MATERIAL_DATA[str(enemy_material.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(enemy_material.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 2)]["name"],
},
{
"num": 3,
"rarity": 5,
"icon": (await self.assets_service.material(104319).icon()).as_uri(),
"name": "智识之冕",
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(weekly_talent_material.id)]["rank"],
"icon": (await self.assets_service.material(weekly_talent_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(weekly_talent_material.id)]["name"],
},
]
return {
"character": {
"element": character.enka.element.name,
"image": character.enka.images.banner.url,
"name": character_name,
"association": (await Character.get_by_name(character_name)).association.name,
},
"level_up_materials": level_up_materials,
"talent_materials": talent_materials,
"talent_level": talent_level,
"talent_amount": TalentMaterials(list(map(int, talent_level.split("/")))).cal_materials(),
}
async def render(self, character_name: str, talent_amount: str):
if not self.roles_material:
await self._refresh()
data = await self._parse_material(self.roles_material, character_name, talent_amount)
if not data:
return
return await self.template_service.render(
"genshin/material/roles_material.jinja2",
2023-04-04 14:02:14 +00:00
data,
{"width": 960, "height": 1460},
full_page=True,
ttl=7 * 24 * 60 * 60,
)
@staticmethod
def _is_valid(string: str):
"""
判断字符串是否符合`8/9/10`的格式并保证每个数字都在[110]
"""
return bool(
re.match(r"^\d+/\d+/\d+$", string)
and all(1 <= int(num) <= 10 for num in string.split("/"))
and string != "1/1/1"
and string != "10/10/10"
)
@handler(CommandHandler, command="material", block=False)
@handler(MessageHandler, filters=filters.Regex("^角色培养素材查询(.*)"), block=False)
async def command_start(self, update: Update, context: CallbackContext) -> None:
message = update.effective_message
user = update.effective_user
args = self.get_args(context)
if len(args) >= 1:
character_name = args[0]
2023-04-04 14:02:14 +00:00
material_count = "8/8/8"
if len(args) >= 2 and self._is_valid(args[1]):
material_count = args[1]
else:
reply_message = await message.reply_text(
"请回复你要查询的培养素材的角色名", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
)
if filters.ChatType.GROUPS.filter(reply_message):
self.add_delete_message_job(message)
self.add_delete_message_job(reply_message)
return
2022-09-09 15:50:10 +00:00
character_name = roleToName(character_name)
2023-04-04 14:02:14 +00:00
logger.info("用户 %s[%s] 查询角色培养素材命令请求 || 参数 %s", user.full_name, user.id, character_name)
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
result = await self.render(character_name, material_count)
if not result:
reply_message = await message.reply_text(
f"没有找到 {character_name} 的培养素材", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
)
if filters.ChatType.GROUPS.filter(reply_message):
self.add_delete_message_job(message)
self.add_delete_message_job(reply_message)
return
2023-04-04 14:02:14 +00:00
await result.reply_photo(message)