mirror of
https://github.com/PaiGramTeam/PaiGram.git
synced 2024-11-22 07:07:46 +00:00
实现 深渊螺旋 基础数据查询
This commit is contained in:
parent
9b5f16d0c4
commit
ff57c122c7
@ -1,14 +1,17 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
from typing import List
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
|
import genshin
|
||||||
import httpx
|
import httpx
|
||||||
|
from genshin import GenshinClient
|
||||||
from httpx import UnsupportedProtocol
|
from httpx import UnsupportedProtocol
|
||||||
from telegram import Bot
|
from telegram import Bot
|
||||||
|
|
||||||
from logger import Log
|
from logger import Log
|
||||||
from model.base import ServiceEnum
|
from model.base import ServiceEnum
|
||||||
|
from service.base import UserInfoData
|
||||||
from service.cache import RedisCache
|
from service.cache import RedisCache
|
||||||
|
|
||||||
USER_AGENT: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " \
|
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
|
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:
|
def get_server(uid: int) -> ServiceEnum:
|
||||||
server = SERVICE_MAP.get(str(uid)[0])
|
server = SERVICE_MAP.get(str(uid)[0])
|
||||||
if server:
|
if server:
|
||||||
|
99
plugins/abyss.py
Normal file
99
plugins/abyss.py
Normal file
@ -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
|
83
resources/genshin/abyss/abyss.html
Normal file
83
resources/genshin/abyss/abyss.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-ch">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>abyss</title>
|
||||||
|
<link type="text/css" href="../../styles/tailwind.min.css" rel="stylesheet">
|
||||||
|
<link type="text/css" href="../../styles/public.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
background: url("./background/lookback-bg.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-icon {
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-side-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="mx-auto flex flex-col h-full bg-no-repeat bg-cover" id="container">
|
||||||
|
<div class="title text-2xl my-4 text-yellow-500 mx-auto">深境螺旋</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-white bg-opacity-10">
|
||||||
|
<div class="uid text-center mx-auto">UID {{uid}}</div>
|
||||||
|
<div class="text-center mx-auto">最深抵达 {{max_floor}}</div>
|
||||||
|
<div class="text-center mx-auto">战斗次数 {{total_battles}}</div>
|
||||||
|
<div class="text-center mx-auto">获得星级 {{total_stars}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-col px-20 py-1 text-black my-1">
|
||||||
|
<div class="text-center mr-auto text-yellow-500">出战次数</div>
|
||||||
|
<div class="mx-auto flex my-2">
|
||||||
|
{% for most_played in most_played_list %}
|
||||||
|
<div class="bg-white rounded-lg mx-2">
|
||||||
|
<div class="character-icon rounded-lg bg-cover"
|
||||||
|
style="background: url({{most_played.background}});background-size: cover;">
|
||||||
|
<img src="{{most_played.icon}}" alt=""></div>
|
||||||
|
<div class="text-center">{{most_played.value}}次</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col my-1">
|
||||||
|
<div class="flex flex-col px-20 py-1 text-black my-1">
|
||||||
|
<div class="text-center mr-auto text-yellow-500">出战次数</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-black bg-opacity-10 ">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">最多击破数:{{most_kills.value}}</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="{{most_kills.icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">最强一击:{{strongest_strike.value}}</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="{{strongest_strike.icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">承受最多伤害:{{most_damage_taken.value}}</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="{{most_damage_taken.icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">元素爆发数:{{most_bursts_used.value}}</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="{{most_bursts_used.icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-black bg-opacity-10 ">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">元素战技释放次数:{{most_skills_used.value}}</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="{{most_skills_used.icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="my-2"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
resources/genshin/abyss/background/lookback-bg.png
Normal file
BIN
resources/genshin/abyss/background/lookback-bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 198 KiB |
BIN
resources/genshin/abyss/background/roleStarBg4.png
Normal file
BIN
resources/genshin/abyss/background/roleStarBg4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
resources/genshin/abyss/background/roleStarBg5.png
Normal file
BIN
resources/genshin/abyss/background/roleStarBg5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
99
resources/genshin/abyss/example.html
Normal file
99
resources/genshin/abyss/example.html
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-ch">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>abyss</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
background: url("./background/lookback-bg.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-icon {
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-side-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="mx-auto flex flex-col h-full bg-no-repeat bg-cover" id="container">
|
||||||
|
<div class="title text-2xl my-4 text-yellow-500 mx-auto">深境螺旋</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-white bg-opacity-10">
|
||||||
|
<div class="uid text-center mx-auto">UID 1414514</div>
|
||||||
|
<div class="text-center mx-auto">最深抵达 12-3</div>
|
||||||
|
<div class="text-center mx-auto">战斗次数 12</div>
|
||||||
|
<div class="text-center mx-auto">获得星级 36</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-col px-20 py-1 text-black my-1">
|
||||||
|
<div class="text-center mr-auto text-yellow-500">出战次数</div>
|
||||||
|
<div class="mx-auto flex my-2">
|
||||||
|
<div class="bg-white rounded-lg mx-2">
|
||||||
|
<div class="character-icon rounded-lg bg-cover"
|
||||||
|
style="background: url('./background/roleStarBg4.png');background-size: cover;">
|
||||||
|
<img src="./../../img/example/256x256.png" alt=""></div>
|
||||||
|
<div class="text-center">12次</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white rounded-lg mx-2">
|
||||||
|
<div class="character-icon rounded-lg bg-cover"
|
||||||
|
style="background: url('./background/roleStarBg4.png');background-size: cover;">
|
||||||
|
<img src="./../../img/example/256x256.png" alt=""></div>
|
||||||
|
<div class="text-center">12次</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white rounded-lg mx-2">
|
||||||
|
<div class="character-icon rounded-lg bg-cover"
|
||||||
|
style="background: url('./background/roleStarBg5.png');background-size: cover;">
|
||||||
|
<img src="./../../img/example/256x256.png" alt=""></div>
|
||||||
|
<div class="text-center">12次</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white rounded-lg mx-2">
|
||||||
|
<div class="character-icon rounded-lg bg-cover"
|
||||||
|
style="background: url('./background/roleStarBg5.png');background-size: cover;">
|
||||||
|
<img src="./../../img/example/256x256.png" alt=""></div>
|
||||||
|
<div class="text-center">12次</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col my-1">
|
||||||
|
<div class="flex flex-col px-20 py-1 text-black my-1">
|
||||||
|
<div class="text-center mr-auto text-yellow-500">出战次数</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-black bg-opacity-10 ">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">最多击破数:21</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="./../../img/example/256x256.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">最强一击:21</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="./../../img/example/256x256.png" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">承受最多伤害:21</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="./../../img/example/256x256.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">元素爆发数:21</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="./../../img/example/256x256.png" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="base-info flex flex-row px-20 py-1 my-1 text-white bg-black bg-opacity-10 ">
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6">
|
||||||
|
<div class="my-auto">元素战技释放次数:21</div>
|
||||||
|
<img class="character-side-icon ml-auto" src="./../../img/example/256x256.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-center flex flex-row flex-1 mr-6"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="my-2"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
resources/img/example/256x256.png
Normal file
BIN
resources/img/example/256x256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 876 B |
Loading…
Reference in New Issue
Block a user