Enhance abyss

Signed-off-by: Karako <karakohear@gmail.com>
Co-authored-by: 洛水居室 <luoshuijs@outlook.com>
Co-authored-by: xtaodada <xtao@xtaolink.cn>
This commit is contained in:
Karako 2022-10-12 17:34:55 +08:00 committed by GitHub
parent df8cc8bea2
commit 57edccd925
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 1550 additions and 426 deletions

View File

@ -1,6 +1,6 @@
import os
import time
from typing import Optional, Dict
from typing import Dict, Optional
from jinja2 import Environment, PackageLoader, Template
from playwright.async_api import ViewportSize
@ -65,7 +65,7 @@ class TemplateService:
viewport: ViewportSize = None,
full_page: bool = True,
evaluate: Optional[str] = None,
query_selector: str = None,
query_selector: str = None
) -> bytes:
"""模板渲染成图片
:param template_path: 模板目录

View File

@ -19,6 +19,7 @@ __all__ = [
"ARTIFACT_DATA",
"NAMECARD_DATA",
"honey_id_to_game_id",
"game_id_to_role_id",
"Data",
]
@ -91,3 +92,10 @@ NAMECARD_DATA: dict[str, dict[str, int | str]] = Data("namecard")
@functools.lru_cache()
def honey_id_to_game_id(honey_id: str, item_type: str) -> str | None:
return next((key for key, value in HONEY_DATA[item_type].items() if value[0] == honey_id), None)
@functools.lru_cache
def game_id_to_role_id(gid: str) -> int | None:
return next(
(int(key.split("-")[0]) for key, value in AVATAR_DATA.items() if value["icon"].split("_")[-1] == gid), None
)

View File

@ -217,6 +217,7 @@ roles = {
10000051: ["优菈", "Eula", "eula", "优拉", "尤拉", "尤菈", "浪花骑士", "记仇", "劳伦斯"],
10000052: [
"雷电将军",
"Shougun",
"Raiden Shogun",
"Raiden",
"raiden",

View File

@ -1,9 +1,17 @@
from typing import Dict, Optional
"""深渊数据查询"""
import asyncio
import re
from datetime import datetime
from functools import lru_cache, partial
from typing import List, Match, Optional, Tuple
import ujson as json
from arkowrapper import ArkoWrapper
from genshin import Client
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, CommandHandler, MessageHandler, filters
from pytz import timezone
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Update
from telegram.constants import ChatAction, ParseMode
from telegram.ext import CallbackContext, filters
from core.base.assets import AssetsService
from core.baseplugin import BasePlugin
@ -13,23 +21,51 @@ from core.plugin import Plugin, handler
from core.template import TemplateService
from core.user import UserService
from core.user.error import UserNotFoundError
from metadata.genshin import game_id_to_role_id
from utils.decorators.error import error_callable
from utils.decorators.restricts import restricts
from utils.helpers import get_genshin_client, get_public_genshin_client
from utils.helpers import async_re_sub, get_genshin_client, get_public_genshin_client
from utils.log import logger
TZ = timezone("Asia/Shanghai")
cmd_pattern = r"^/abyss\s*((?:\d+)|(?:all))?\s*(pre)?"
msg_pattern = r"^深渊数据((?:查询)|(?:总览))(上期)?\D?(\d*)?.*?$"
regex_01 = r"['\"]icon['\"]:\s*['\"](.*?)['\"]"
regex_02 = r"['\"]side_icon['\"]:\s*['\"](.*?)['\"]"
async def replace_01(match: Match, assets_service: AssetsService) -> str:
aid = game_id_to_role_id(re.findall(r"UI_AvatarIcon_(.*?).png", match.group(1))[0])
return (await assets_service.avatar(aid).icon()).as_uri()
async def replace_02(match: Match, assets_service: AssetsService) -> str:
aid = game_id_to_role_id(re.findall(r"UI_AvatarIcon_Side_(.*?).png", match.group(1))[0])
return (await assets_service.avatar(aid).side()).as_uri()
@lru_cache
def get_args(text: str) -> Tuple[int, bool, bool]:
if text.startswith("/"):
result = re.match(cmd_pattern, text).groups()
try:
floor = int(result[0] or 0)
except ValueError:
floor = 0
return floor, result[0] == "all", bool(result[1])
else:
result = re.match(msg_pattern, text).groups()
return int(result[2] or 0), result[0] == "总览", result[1] == "上期"
class AbyssUnlocked(Exception):
"""根本没动"""
pass
class NoMostKills(Exception):
"""挑战了但是数据没刷新"""
pass
class Abyss(Plugin, BasePlugin):
"""深渊数据查询"""
@ -46,95 +82,245 @@ class Abyss(Plugin, BasePlugin):
self.user_service = user_service
self.assets_service = assets_service
@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, client: Client, uid: Optional[int] = None) -> Dict:
if uid is None:
_uid = client.uid
await client.get_record_cards()
else:
_uid = uid
spiral_abyss_info = await client.get_spiral_abyss(_uid)
if not spiral_abyss_info.unlocked:
raise AbyssUnlocked
ranks = spiral_abyss_info.ranks
if len(spiral_abyss_info.ranks.most_kills) == 0:
raise NoMostKills
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 self.assets_service.avatar(ranks.most_kills[0].id).side(),
"value": ranks.most_kills[0].value,
},
"strongest_strike": {
"icon": await self.assets_service.avatar(ranks.strongest_strike[0].id).side(),
"value": ranks.strongest_strike[0].value,
},
"most_damage_taken": {
"icon": await self.assets_service.avatar(ranks.most_damage_taken[0].id).side(),
"value": ranks.most_damage_taken[0].value,
},
"most_bursts_used": {
"icon": await self.assets_service.avatar(ranks.most_bursts_used[0].id).side(),
"value": ranks.most_bursts_used[0].value,
},
"most_skills_used": {
"icon": await self.assets_service.avatar(ranks.most_skills_used[0].id).side(),
"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 self.assets_service.avatar(most_played.id).icon(),
"value": most_played.value,
"background": self._get_role_star_bg(most_played.rarity),
}
abyss_data["most_played_list"].append(temp)
return abyss_data
@handler(CommandHandler, command="abyss", block=False)
@handler(MessageHandler, filters=filters.Regex("^深渊数据查询(.*)"), block=False)
@handler.command("abyss", block=False)
@handler.message(filters.Regex(msg_pattern), block=False)
@restricts()
@error_callable
async def command_start(self, update: Update, context: CallbackContext) -> None:
user = update.effective_user
message = update.effective_message
logger.info(f"用户 {user.full_name}[{user.id}] 查深渊挑战命令请求")
await message.reply_chat_action(ChatAction.TYPING)
try:
try:
client = await get_genshin_client(user.id)
abyss_data = await self._get_abyss_data(client)
except CookiesNotFoundError:
client, uid = await get_public_genshin_client(user.id)
abyss_data = await self._get_abyss_data(client, uid)
except UserNotFoundError:
reply_message = await message.reply_text("未查询到账号信息,请先私聊派蒙绑定账号")
# 若查询帮助
if (message.text.startswith("/") and "help" in message.text) or "帮助" in message.text:
await message.reply_text(
"<b>深渊挑战数据</b>功能使用帮助(中括号表示可选参数)\n\n"
"指令格式:\n<code>/abyss + [层数/all] + [pre]</code>\n<code>pre</code>表示上期)\n\n"
"文本格式:\n<code>深渊数据 + 查询/总览 + [上期] + [层数]</code> \n\n"
"例如以下指令都正确:\n"
"<code>/abyss</code>\n<code>/abyss 12 pre</code>\n<code>/abyss all pre</code>\n"
"<code>深渊数据查询</code>\n<code>深渊数据查询上期第12层</code>\n<code>深渊数据总览上期</code>",
parse_mode=ParseMode.HTML,
)
logger.info(f"用户 {user.full_name}[{user.id}] 查询[bold]深渊挑战数据[/bold]帮助", extra={"markup": True})
return
# 解析参数
floor, total, previous = get_args(message.text)
if floor > 12 or floor < 0:
reply_msg = await message.reply_text("深渊层数输入错误,请重新输入")
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 10)
self._add_delete_message_job(context, reply_msg.chat_id, reply_msg.message_id, 10)
self._add_delete_message_job(context, message.chat_id, message.message_id, 10)
return
except TooManyRequestPublicCookies:
await message.reply_text("用户查询次数过多 请稍后重试")
return
except (AbyssUnlocked, NoMostKills):
await message.reply_text("本次深渊旅行者还没挑战呢,咕咕咕~~~")
return
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
png_data = await self.template_service.render(
"genshin/abyss", "abyss.html", abyss_data, {"width": 865, "height": 504}, full_page=False
elif 0 < floor < 9:
previous = False
logger.info(
f"用户 {user.full_name}[{user.id}] [bold]深渊挑战数据[/bold]请求: "
f"floor={floor} total={total} previous={previous}",
extra={"markup": True},
)
await message.reply_photo(png_data, filename=f"abyss_{user.id}.png", allow_sending_without_reply=True)
try:
client = await get_genshin_client(user.id)
await client.get_record_cards()
uid = client.uid
except UserNotFoundError: # 若未找到账号
if filters.ChatType.GROUPS.filter(message):
buttons = [[InlineKeyboardButton("点我私聊", url=f"https://t.me/{context.bot.username}?start=set_cookies")]]
reply_msg = await message.reply_text(
"未查询到您所绑定的账号信息,请先私聊派蒙绑定账号", reply_markup=InlineKeyboardMarkup(buttons)
)
self._add_delete_message_job(context, reply_msg.chat_id, reply_msg.message_id, 30)
self._add_delete_message_job(context, message.chat_id, message.message_id, 30)
else:
await message.reply_text("未查询到您所绑定的账号信息,请先私聊派蒙绑定账号")
return
except CookiesNotFoundError: # 若未找到cookie
client, uid = await get_public_genshin_client(user.id)
except TooManyRequestPublicCookies:
reply_msg = await message.reply_text(
"查询次数太多,请您稍后重试",
)
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, reply_msg.chat_id, reply_msg.message_id, 10)
self._add_delete_message_job(context, message.chat_id, message.message_id, 10)
return
async def reply_message(content: str) -> None:
_user = await client.get_genshin_user(uid)
_reply_msg = await message.reply_text(
f"旅行者 {_user.info.nickname}(<code>{uid}</code>) {content}", parse_mode=ParseMode.HTML
)
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, _reply_msg.chat_id, _reply_msg.message_id, 10)
self._add_delete_message_job(context, message.chat_id, message.message_id, 10)
if total:
reply_msg = await message.reply_text("派蒙需要时间整理深渊数据,还请耐心等待哦~")
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, reply_msg.chat_id, reply_msg.message_id, 10)
self._add_delete_message_job(context, message.chat_id, message.message_id, 10)
await message.reply_chat_action(ChatAction.TYPING)
try:
images = await self.get_rendered_pic(client, uid, floor, total, previous)
except AbyssUnlocked: # 若深渊未解锁
return await reply_message("还未解锁深渊哦~")
except NoMostKills: # 若深渊还未挑战
return await reply_message("还没有挑战本次深渊呢,咕咕咕~")
except IndexError: # 若深渊为挑战此层
return await reply_message("还没有挑战本层呢,咕咕咕~")
if images is None:
return await reply_message(f"还没有第 {floor} 层的挑战数据")
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
for group in ArkoWrapper(images).map(InputMediaPhoto).group(10): # 每 10 张图片分一个组
await message.reply_media_group(list(group), allow_sending_without_reply=True)
logger.info(f"用户 {user.full_name}[{user.id}] [bold]深渊挑战数据[/bold]: 成功发送图片", extra={"markup": True})
async def get_rendered_pic(
self, client: Client, uid: int, floor: int, total: bool, previous: bool
) -> Optional[List[bytes]]:
"""
获取渲染后的图片
Args:
client (Client): 获取 genshin 数据的 client
uid (int): 需要查询的 uid
floor (int): 层数
total (bool): 是否为总览
previous (bool): 是否为上期
Returns:
bytes格式的图片
"""
def json_encoder(value):
if isinstance(value, datetime):
return value.astimezone(TZ).strftime("%Y-%m-%d %H:%M:%S")
return value
abyss_data = await client.get_spiral_abyss(uid, previous=previous, lang="zh-cn")
if not abyss_data.unlocked:
raise AbyssUnlocked()
if not abyss_data.ranks.most_kills:
raise NoMostKills()
end_time = abyss_data.end_time.astimezone(TZ)
time = end_time.strftime("%Y年%m月") + "" if end_time.day <= 16 else "" + ""
stars = [i.stars for i in filter(lambda x: x.floor > 8, abyss_data.floors)]
total_stars = f"{sum(stars)} ({'-'.join(map(str, stars))})"
render_data = {}
result = await async_re_sub(
regex_01,
partial(replace_01, assets_service=self.assets_service),
abyss_data.json(encoder=json_encoder),
)
result = await async_re_sub(regex_02, partial(replace_02, assets_service=self.assets_service), result)
render_data["time"] = time
render_data["stars"] = total_stars
render_data["uid"] = uid
render_data["floor_colors"] = {
1: "#374952",
2: "#374952",
3: "#55464B",
4: "#55464B",
5: "#55464B",
6: "#1D2A5D",
7: "#1D2A5D",
8: "#1D2A5D",
9: "#292B58",
10: "#382024",
11: "#252550",
12: "#1D2A4A",
}
if total:
avatars = await client.get_genshin_characters(uid, lang="zh-cn")
render_data["avatar_data"] = {i.id: i.constellation for i in avatars}
data = json.loads(result)
render_data["data"] = data
render_result = []
async def overview_task():
render_result.append(
[
-1,
await self.template_service.render(
"genshin/abyss", "overview.html", render_data, viewport={"width": 750, "height": 580}
),
]
)
async def floor_task(floor_index: int):
floor_d = data["floors"][floor_index]
render_result.append(
[
floor_d["floor"],
await self.template_service.render(
"genshin/abyss",
"floor.html",
{
**render_data,
"floor": floor_d,
"total_stars": f"{floor_d['stars']}/{floor_d['max_stars']}",
},
viewport={"width": 690, "height": 500},
full_page=True,
),
]
)
task_list = [asyncio.create_task(overview_task())]
for i, f in enumerate(data["floors"]):
if f["floor"] >= 9:
task_list.append(asyncio.create_task(floor_task(i)))
await asyncio.gather(*task_list)
return list(map(lambda x: x[1], sorted(render_result, key=lambda x: x[0])))
elif floor < 1:
render_data["data"] = json.loads(result)
return [
await self.template_service.render(
"genshin/abyss",
"overview.html",
render_data,
viewport={"width": 750, "height": 580},
)
]
else:
num_dic = {
"0": "",
"1": "",
"2": "",
"3": "",
"4": "",
"5": "",
"6": "",
"7": "",
"8": "",
"9": "",
}
if num := num_dic.get(str(floor)):
render_data["floor-num"] = num
else:
render_data["floor-num"] = f"{num_dic.get(str(floor % 10))}"
floors = json.loads(result)["floors"]
if (floor_data := list(filter(lambda x: x["floor"] == floor, floors))) is None:
return None
avatars = await client.get_genshin_characters(uid, lang="zh-cn")
render_data["avatar_data"] = {i.id: i.constellation for i in avatars}
render_data["floor"] = floor_data[0]
render_data["total_stars"] = f"{floor_data[0]['stars']}/{floor_data[0]['max_stars']}"
return [
await self.template_service.render(
"genshin/abyss", "floor.html", render_data, viewport={"width": 690, "height": 500}, full_page=True
)
]

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,101 +0,0 @@
<!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 {
width: 865px;
height: 504px;
background: url("./background/lookback-bg.png");
background-size: cover;
}
.character-icon {
width: 128px;
height: 128px;
}
.character-side-icon {
position: absolute;
right: 0;
bottom: 1px;
width: 48px;
height: 48px;
}
div:has(> img.character-side-icon) {
position: relative;
height: 32px;
}
div:has(> img.character-side-icon) > div {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
</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="rounded-lg mx-2 overflow-hidden" style="background-color: rgb(233, 229, 220)">
<div class="character-icon rounded-br-3xl bg-cover overflow-hidden"
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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -2,115 +2,518 @@
<html lang="zh-ch">
<head>
<meta charset="UTF-8">
<title>abyss</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
#container {
width: 865px;
height: 504px;
background: url("./background/lookback-bg.png");
background-size: cover;
}
.character-icon {
width: 128px;
height: 128px;
}
.character-side-icon {
position: absolute;
right: 0;
bottom: 1px;
width: 48px;
height: 48px;
}
div:has(> img.character-side-icon) {
position: relative;
height: 32px;
}
div:has(> img.character-side-icon) > div {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
</style>
<title>abyss-example</title>
<link type="text/css" href="./style.css" rel="stylesheet"/>
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
</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 overflow-hidden">
<div class="character-icon rounded-br-3xl 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 class="container">
<div class="overview">
<div class="title">挑战回顾</div>
<div class="summarize">
<div>
<div>UID: 100206192</div>
<div class="star">
<span>36 (9-9-9-9)</span>
</div>
</div>
<div class="bg-white rounded-lg mx-2 overflow-hidden">
<div class="character-icon rounded-br-3xl 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 overflow-hidden">
<div class="character-icon rounded-br-3xl 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 overflow-hidden">
<div class="character-icon rounded-br-3xl 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>时间: 2022年10月上</div>
<div>最深抵达: 12-3</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 class="most-played">
<div class="caption">出战次数</div>
<div class="characters">
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">15次</div>
</div>
<i class="four-star"></i>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">15次</div>
</div>
<i class="four-star"></i>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">15次</div>
</div>
<i class="four-star"></i>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">15次</div>
</div>
</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" src="./../../img/example/256x256.png" alt="">
<div class="caption">战斗数据</div>
<div class="ranks">
<div style="background-color: rgb(61 76 86 / 60%);">
<div class="rank">战斗次数: 12</div>
<div class="rank">
<span>最多击破999</span>
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
</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 class="rank">
<span>最强一击: 999,999</span>
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
<div class="rank">
<span>最多承伤: 114,514</span>
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
</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 style="background-color: rgb(61 76 86 / 60%);">
<div class="rank">
<span>元素爆发: 26</span>
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
<div class="rank">
<span>元素战技: 48</span>
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
</div>
</div>
</div>
</div>
<div class="floors">
<div class="floor" style="background-image: url('./background/floor1.png');background-color: #374952;">
<div class="head">
<div class="floor-name">
<div class="floor-num"></div>
<div>深境螺旋第一层</div>
</div>
<div class="star">
<span>9/9</span>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 1 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star dim-star"></div>
<div class="star dim-star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">5命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">4命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">3命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">上半</div>
</div>
<div class="battle">
<div class="character">
<div style="background-color: var(--blue)">2命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--blue)">1命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">下半</div>
</div>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 2 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">上半</div>
</div>
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">下半</div>
</div>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 3 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star"></div>
<div class="star dim-star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">4命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--blue)">2命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
</div>
</div>
</div>
</div>
<div class="floor" style="background-image: url('./background/floor1.png');background-color: #374952;">
<div class="head">
<div class="floor-name">
<div class="floor-num">
<div>1</div>
</div>
<span>深境螺旋第一层</span>
</div>
<div class="star">
<span>9/9</span>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 1 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star dim-star"></div>
<div class="star dim-star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">5命</div>
<div class="element" style="background-image: url('../../img/element/Cyro.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">4命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">3命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">上半</div>
</div>
<div class="battle">
<div class="character">
<div style="background-color: var(--blue)">2命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--blue)">1命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">下半</div>
</div>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 2 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">上半</div>
</div>
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="battle-info">下半</div>
</div>
</div>
</div>
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 3 间 <span style="color: #A3A3A3">2022-10-01 10:02:05</span>
</div>
<div class="stars">
<div class="star"></div>
<div class="star"></div>
<div class="star dim-star"></div>
</div>
</div>
<div class="battles">
<div class="battle">
<div class="character">
<div style="background-color: var(--red)">6命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--green)">4命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div style="background-color: var(--blue)">2命</div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="caption">Lv.90</div>
</div>
</div>
</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>

View File

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>floor</title>
<link type="text/css" href="./style.css" rel="stylesheet"/>
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
<style>
body {
margin: 0;
padding: 0;
}
.floors, .floor {
border-radius: unset;
margin: 0;
}
.floor-num > div:last-child {
display: flex;
flex-flow: column;
justify-content: center;
align-content: center;
}
</style>
</head>
<body>
<div class="container">
<div class="floors">
<div
class="floor"
style="
background-image: url('./background/floor{{ floor.floor }}.png');
background-color: {{ floor_colors[floor.floor] }};"
>
<div class="head">
<div class="floor-name">
<div class="floor-num"></div>
<div>
<div>UID: {{ uid }}</div>
<div>深境螺旋第 {{ floor.floor }} 层</div>
</div>
</div>
<div class="star">
<span>{{ total_stars }}</span>
</div>
</div>
{% for chamber in floor.chambers %}
<div class="hr"></div>
<div class="chamber">
<div class="chamber-info">
<div>
第 {{ loop.index }} 间 <span
style="color: #A3A3A3">{{ chamber.battles[0].timestamp }}</span>
</div>
<div class="stars">
{% for n in range(chamber.stars) %}
<div class="star"></div>
{% endfor %}
{% for n in range(chamber.max_stars - chamber.stars) %}
<div class="star dim-star"></div>
{% endfor %}
</div>
</div>
<div class="battles">
{% for battle in chamber.battles %}
<div class="battle">
{% for character in battle.characters %}
<div class="character">
{% if avatar_data[character.id] > 0 %}
{% set constellation = avatar_data[character.id] %}
{% set bg = ['blue','blue', 'green','green', 'red', 'red'][constellation - 1] %}
<div style="background-color: var(--{{ bg }})">
{{ constellation }} 命
</div>
{% endif %}
<div class="icon"
style="background-image: url('../../background/rarity/half/{{ character.rarity }}.png')">
<img src="{{ character.icon }}" alt=""/>
</div>
<div class="caption">Lv.{{ character.level }}</div>
</div>
{% endfor %}
{% if loop.length > 1 %}
<div class="battle-info">{{ ['上', '下'][loop.index0] }}半</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="zh-ch">
<head>
<meta charset="UTF-8">
<title>overview</title>
<link type="text/css" href="./style.css" rel="stylesheet"/>
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
<style>
body {
margin: 0;
padding: 0;
}
.overview {
border-radius: unset;
}
</style>
</head>
<body>
<div class="container">
<div class="overview">
<div class="title">挑战回顾</div>
<div class="summarize">
<div>
<div>UID: {{ uid }}</div>
<div class="star">
<span>{{ stars }}</span>
</div>
</div>
<div>
<div>时间: {{ time }}</div>
<div>最深抵达: {{ data.max_floor }}</div>
</div>
</div>
<div class="most-played">
<div class="caption">出战次数</div>
<div class="characters">
{% for avatar in data.ranks.most_played %}
<div class="character">
<div
class="icon"
style="background-image: url('../../background/rarity/half/{{ avatar.rarity }}.png')"
>
<img src="{{ avatar.icon }}" alt=""/>
</div>
<div class="caption">{{ avatar.value }} 次</div>
</div>
{% if loop.index != 4 %}
<i class="four-star"></i>
{% endif %}
{% endfor %}
</div>
</div>
<div>
<div class="caption">战斗数据</div>
<div class="ranks">
<div style="background-color: rgb(61 76 86 / 60%);">
<div class="rank">战斗次数: {{ data.total_battles }}</div>
<div class="rank">
<span>最多击破:{{ data.ranks.most_kills[0].value }}</span>
<img src="{{ data.ranks.most_kills[0].side_icon }}" alt=""/>
</div>
</div>
<div>
<div class="rank">
<span>最强一击: {{ data.ranks.strongest_strike[0].value }}</span>
<img src="{{ data.ranks.strongest_strike[0].side_icon }}" alt=""/>
</div>
<div class="rank">
<span>最多承伤: {{ data.ranks.most_damage_taken[0].value }}</span>
<img src="{{ data.ranks.most_damage_taken[0].side_icon }}" alt=""/>
</div>
</div>
<div style="background-color: rgb(61 76 86 / 60%);">
<div class="rank">
<span>元素爆发: {{ data.ranks.most_bursts_used[0].value }}</span>
<img src="{{ data.ranks.most_bursts_used[0].side_icon }}" alt=""/>
</div>
<div class="rank">
<span>元素战技: {{ data.ranks.most_skills_used[0].value }}</span>
<img src="{{ data.ranks.most_skills_used[0].side_icon }}" alt=""/>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,346 @@
:root {
--white: rgb(246 248 249);
--bg-color: rgb(233 229 220);
--h-color: rgb(203 189 162);
--red: rgb(255 86 33/ 80%);
--blue: rgb(98 168 233/ 80%);
--green: rgb(67 185 124/ 80%);
}
body {
margin: 0;
padding: 10px;
}
.hr {
width: 100%;
height: 3px;
background-color: rgb(246 248 249 / 50%);
}
.container {
width: 750px;
position: relative;
filter: drop-shadow(2px 2px 5px rgb(0 0 0 /70%));
}
.title {
text-align: center;
font-size: 27px;
font-weight: bold;
color: var(--h-color);
}
.caption {
margin: 10px 0;
color: var(--h-color);
font-size: 20px;
}
/* 概览 */
.overview {
height: 540px;
padding: 20px 40px;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-image: linear-gradient(to top, rgb(0 0 0 / 10%), rgb(0 0 0 / 10%)), url("./background/lookback-bg.png");
background-attachment: local;
border-radius: 15px;
overflow: hidden;
}
.summarize {
font-size: 20px;
width: calc(100% - 90px);
height: calc(100px - 20px);
margin: 20px 0;
padding: 10px 0 10px 80px;
border-radius: 5px;
border: 2px solid rgb(118 121 120 / 80%);
outline: 4px solid rgb(74, 82, 101);
background-color: rgb(74 82 101 / 60%);
background-image: url("./background/banner 01.png"), url("./background/banner 02.png");
background-repeat: no-repeat, no-repeat;
background-position: right, left;
background-size: auto 100%, auto 100%;
backdrop-filter: blur(5px);
}
.summarize > div {
width: 100%;
height: 50%;
color: var(--white);
display: flex;
align-items: center;
}
.summarize > div > div {
flex: 1;
}
.star {
display: inline-flex;
align-items: center;
position: relative;
}
.star::before {
content: "";
width: 40px;
height: 40px;
background-size: cover;
background-image: url("./background/star.png");
}
.star > span {
margin-left: 10px;
}
.most-played {
width: 100%;
margin: 30px 0;
}
.characters {
width: calc(100% - 60px);
padding: 0 30px;
display: flex;
justify-content: center;
align-items: center;
}
.character {
width: 100px;
height: 125px;
margin: 0 20px;
background-color: rgb(233 229 220);
overflow: hidden;
border-radius: 10px;
position: relative;
}
.icon {
width: 100%;
height: 100px;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
overflow: hidden;
border-radius: 0 0 20px 0;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
}
.icon > img {
width: inherit;
height: inherit;
}
.character > .caption {
font-size: 18px;
margin: 4px 0 0;
padding: 0;
height: min-content;
text-align: center;
color: black;
}
.four-star {
width: 15px;
height: 15px;
position: relative;
}
.four-star::after {
content: '';
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: inherit;
height: inherit;
background-position: center;
background-image: url("./background/four-star.png");
background-blend-mode: lighten;
background-size: contain;
}
.ranks {
width: calc(100% + 80px);
transform: translateX(-40px);
color: var(--white);
position: relative;
display: flex;
flex-flow: column;
flex-wrap: wrap;
}
.ranks > div {
font-size: 18px;
width: 100%;
height: 43px;
display: flex;
align-items: center;
}
.rank {
flex: 1;
position: relative;
display: flex;
margin-left: 80px;
margin-right: 60px;
}
.ranks > div > .rank:first-child {
margin-right: 10px;
}
.rank > img {
width: 50px;
position: absolute;
right: 0;
bottom: -5px;
}
/* 层数 */
.floors {
margin-top: 20px;
}
.floor {
margin: 20px 0;
padding: 0 30px;
width: calc(100% - 60px);
border-radius: 20px;
overflow: hidden;
outline: rgb(233 229 220 / 30%) solid 3px;
outline-offset: -7px;
background-position: top center;
background-repeat: no-repeat;
background-size: contain;
}
.head {
width: 100%;
height: 160px;
display: flex;
}
.floor-name {
font-size: 28px;
display: flex;
align-items: center;
font-weight: bold;
color: var(--white);
}
.floor-name > div:not(.floor-num) {
margin-left: 20px;
text-shadow: 1px 1px 5px rgb(0 0 0/50%);
}
.floor-num {
color: black;
width: 100px;
height: 100px;
background-image: url("./background/abyss.png");
background-size: contain;
filter: drop-shadow(0 0 5px rgb(0 0 0/80%)) grayscale(10%);
position: relative;
}
.head > .star {
margin-left: auto;
float: right;
color: var(--white);
font-size: 25px;
text-shadow: 1px 1px 5px rgb(0 0 0/50%);
}
.head > .star::before {
width: 50px;
height: 50px;
}
.chamber {
margin: 10px 0;
display: flex;
flex-flow: column;
}
.chamber-info {
height: 70px;
display: flex;
align-items: center;
color: var(--white);
font-size: 22px;
}
.stars {
margin-left: auto;
}
.dim-star::before {
filter: brightness(50%);
}
.battle {
margin: 10px 0 20px 0;
display: flex;
justify-content: center;
align-items: center;
}
.battle > .character {
flex: 2;
max-width: 120px;
height: 145px;
}
.battle > .battle-info {
flex: 1;
color: var(--white);
font-size: 22px;
font-weight: bold;
}
.battle > .character > div:first-child:not(.icon, .element) {
position: absolute;
top: 0;
right: 0;
padding: 5px;
min-width: 27px;
text-align: center;
border-radius: 0 0 0 10px;
filter: drop-shadow(1px 1px 5px rgb(0 0 0/50%));
font-weight: 500;
color: var(--white);
}
.battle > .character > .element {
position: absolute;
top: 3px;
left: 3px;
width: 30px;
height: 30px;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.battle > .character > .icon {
width: 100%;
height: fit-content;
border-radius: 0 0 28px 0;
}
.battle > .character > .caption {
font-size: 20px;
margin-top: 2px;
}

View File

@ -31,12 +31,12 @@
{% for material in area.materials %}
<div class="material">
<div class="material-icon"
style="background-image: url(./bg/rarity/half/{{ material.rarity }}.png)">
style="background-image: url(../../background/rarity/half/{{ material.rarity }}.png)">
<img alt="{{ material.name }}" src="{{ material.icon }}"/>
</div>
<div class="material-star">
{% for _ in range(material.rarity) %}
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
{% endfor %}
</div>
</div>
@ -53,7 +53,7 @@
{% endif %}
>
<div class="item-icon"
style="background-image: url(./bg/rarity/full/{{ item.rarity }}.png)">
style="background-image: url(../../background/rarity/full/{{ item.rarity }}.png)">
{% if item.level != none %}
<div>Lv.{{ item.level }}</div>
{% endif %}

View File

@ -27,52 +27,52 @@
</span>
<span class="materials">
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/2.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/2.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/3.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/3.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/4.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/4.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/5.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/5.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
</span>
</div>
<div class="area-content">
<div class="item character item-not-owned">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000058/icon.png" alt="八重神子"/>
@ -82,7 +82,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
@ -92,7 +92,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
@ -102,7 +102,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
@ -111,7 +111,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="item-name">
@ -119,7 +119,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="item-name">
@ -139,52 +139,52 @@
</span>
<span class="materials">
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/2.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/2.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/3.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/3.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/4.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/4.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/5.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/5.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
</span>
</div>
<div class="area-content">
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000058/icon.png" alt="神里绫华"/>
@ -194,7 +194,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
@ -204,7 +204,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: rgba(255, 20, 147, 0.8); backdrop-filter: blur(3px);">6命</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
@ -214,7 +214,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
@ -223,7 +223,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="item-name">
@ -231,7 +231,7 @@
</div>
</div>
<div class="item character">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/avatar/10000002/icon.png" alt="神里绫华"/>
</div>
<div class="item-name">
@ -255,45 +255,45 @@
</span>
<span class="materials">
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/2.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/2.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/3.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/3.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/4.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/4.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
<div class="material">
<div class="material-icon" style="background-image: url(./bg/rarity/half/5.png)">
<div class="material-icon" style="background-image: url(../../background/rarity/half/5.png)">
<img alt="" src="../../assets/material/114003/icon.png"/>
</div>
<div class="material-star">
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
</div>
</div>
</span>
@ -303,7 +303,7 @@
<div class="role">
<img src="../../assets/avatar/10000063/side.png" alt="申鹤"/>
</div>
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: deepskyblue">精炼5</div>
<img src="../../assets/weapon/14501/awaken.png" alt="天空之刃"/>
@ -316,7 +316,7 @@
<div class="role">
<img src="../../assets/avatar/10000041/side.png" alt="神里绫华"/>
</div>
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: deepskyblue">精炼5</div>
<img src="../../assets/weapon/14502/awaken.png" alt="天空之刃"/>
@ -329,7 +329,7 @@
<div class="role">
<img src="../../assets/avatar/10000067/side.png" alt="神里绫华"/>
</div>
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: deepskyblue">精炼5</div>
<img src="../../assets/weapon/14502/awaken.png" alt="天空之刃"/>
@ -342,7 +342,7 @@
<div class="role">
<img src="../../assets/avatar/10000002/side.png" alt="神里绫华"/>
</div>
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<div>Lv.90</div>
<div style="background-color: deepskyblue">精炼5</div>
<img src="../../assets/weapon/14502/awaken.png" alt="天空之刃"/>
@ -352,7 +352,7 @@
</div>
</div>
<div class="item weapon">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/weapon/14502/awaken.png" alt="天空之刃"/>
</div>
<div class="item-name">
@ -360,7 +360,7 @@
</div>
</div>
<div class="item weapon">
<div class="item-icon" style="background-image: url(./bg/rarity/full/5.png)">
<div class="item-icon" style="background-image: url(../../background/rarity/full/5.png)">
<img src="../../assets/weapon/14502/awaken.png" alt="天空之刃"/>
</div>
<div class="item-name">

View File

@ -1,13 +1,13 @@
@font-face {
font-family: 'HYWH';
src: url('../../fonts/汉仪文黑-85W.ttf') format('truetype');
src: url('../../fonts/HYWenHei-85W.ttf') format('truetype');
}
:root {
--bg-color: #ebe5d9;
--font-color: #514e49;
--color-1: #d6ba92;
--shadow: #726c65;
--bg-color: #EBE5D9;
--font-color: #514E49;
--color-1: #D6BA92;
--shadow: #726C65;
}
@ -190,7 +190,7 @@ body {
display: flex;
justify-content: center;
align-items: center;
filter: drop-shadow(1px 1px 2px #6c6c6c);
filter: drop-shadow(1px 1px 2px #6C6C6C);
}
.material-star > img {

View File

@ -31,12 +31,12 @@
{% for material in area.materials %}
<div class="material">
<div class="material-icon"
style="background-image: url(./bg/rarity/half/{{ material.rarity }}.png)">
style="background-image: url(../../background/rarity/half/{{ material.rarity }}.png)">
<img alt="{{ material.name }}" src="{{ material.icon }}"/>
</div>
<div class="material-star">
{% for _ in range(material.rarity) %}
<img alt="star" src="./bg/rarity/star.webp"/>
<img alt="star" src="../../background/rarity/star.webp"/>
{% endfor %}
</div>
</div>
@ -58,7 +58,7 @@
</div>
{% endif %}
<div class="item-icon"
style="background-image: url(./bg/rarity/full/{{ item.rarity }}.png)">
style="background-image: url(../../background/rarity/full/{{ item.rarity }}.png)">
{% if item.level != none %}
<div>Lv.{{ item.level }}</div>
{% endif %}

View File

@ -4,7 +4,7 @@
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="shortcut icon" href="#"/>
<link rel="stylesheet" type="text/css" href="gacha_count.css"/>
<link rel="preload" href="./../../fonts/汉仪文黑-85W.ttf" as="font">
<link rel="preload" href="../../fonts/HYWenHei-85W.ttf" as="font">
<link rel="preload" href="./../../fonts/tttgbnumber.ttf" as="font">
<link rel="preload" href="./../abyss/background/roleStarBg5.png" as="image">
<link rel="preload" href="./../abyss/background/roleStarBg4.png" as="image">

View File

@ -7,7 +7,7 @@
@font-face {
font-family: "HYWenHei-55W";
src: url("./../../fonts/汉仪文黑-85W.ttf");
src: url("../../fonts/HYWenHei-85W.ttf");
font-weight: normal;
font-style: normal;
}
@ -22,7 +22,7 @@
body {
font-size: 16px;
width: 530px;
color: #1e1f20;
color: #1E1F20;
transform: scale(1.5);
transform-origin: 0 0;
}
@ -30,7 +30,7 @@ body {
.container {
width: 530px;
padding: 20px 15px 10px 15px;
background-color: #f5f6fb;
background-color: #F5F6FB;
}
.head_box {
@ -72,7 +72,7 @@ body {
margin-top: 20px;
margin-bottom: 20px;
padding: 10px 5px 5px 5px;
background: #fff;
background: #FFF;
box-shadow: 0 5px 10px 0 rgb(0 0 0 / 15%);
position: relative;
}
@ -111,7 +111,7 @@ body {
box-shadow: 0 2px 6px 0 rgb(132 93 90 / 30%);
height: 70px;
width: 70px;
background: #e9e5dc;
background: #E9E5DC;
position: relative;
}
@ -132,7 +132,7 @@ body {
z-index: 9;
font-size: 18px;
text-align: center;
color: #fff;
color: #FFF;
border-radius: 3px;
padding: 1px 5px;
background: rgb(0 0 0 / 50%);
@ -144,15 +144,15 @@ body {
}
.label_302 {
background-color: #e69449;
background-color: #E69449;
}
.label_200 {
background-color: #757cc8;
background-color: #757CC8;
}
.label {
color: #fff;
color: #FFF;
border-radius: 10px;
font-size: 16px;
padding: 2px 7px;
@ -177,38 +177,38 @@ body {
}
.list_box .item .life1 {
background-color: #62a8ea;
background-color: #62A8EA;
}
.list_box .item .life2 {
background-color: #62a8ea;
background-color: #62A8EA;
}
.list_box .item .life3 {
background-color: #45b97c;
background-color: #45B97C;
}
.list_box .item .life4 {
background-color: #45b97c;
background-color: #45B97C;
}
.list_box .item .life5 {
background-color: #ff5722;
background-color: #FF5722;
}
.list_box .item .life6 {
background-color: #ff5722;
background-color: #FF5722;
}
.logo {
font-size: 14px;
font-family: "tttgbnumber", serif;
text-align: center;
color: #7994a7;
color: #7994A7;
}
.hasMore {
font-size: 12px;
margin: -6px 0 10px 6px;
color: #7f858a;
color: #7F858A;
}

View File

@ -4,7 +4,7 @@
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="shortcut icon" href="#"/>
<link rel="stylesheet" type="text/css" href="gacha_count.css"/>
<link rel="preload" href="./../../fonts/汉仪文黑-85W.ttf" as="font">
<link rel="preload" href="../../fonts/HYWenHei-85W.ttf" as="font">
<link rel="preload" href="./../../fonts/tttgbnumber.ttf" as="font">
<link rel="preload" href="./../abyss/background/roleStarBg5.png" as="image">
<link rel="preload" href="./../abyss/background/roleStarBg4.png" as="image">
@ -20,34 +20,34 @@
<body id="container" class="body_box">
<div class="container">
<div class="head_box">
<div class="id_text">ID: {{uid}}</div>
<h2 class="day_text">抽卡统计-{{typeName}}</h2>
<div class="id_text">ID: {{ uid }}</div>
<h2 class="day_text">抽卡统计-{{ typeName }}</h2>
<img class="genshin_logo" src="./../../bot/help/background/genshin.png" alt=""/>
</div>
{% for val in pool %}
<div class="pool_box">
<div class="title_box">
<div class="name_box">
<div class="title"><h2>「{{val.name}}」</h2></div>
<span class="label label_301">{{val.count}}抽</span>
<div class="pool_box">
<div class="title_box">
<div class="name_box">
<div class="title"><h2>「{{ val.name }}」</h2></div>
<span class="label label_301">{{ val.count }}抽</span>
</div>
{% if typeName != "常驻祈愿" %}
<span class="date">{{ val.start }} - {{ val.end }}</span>
{% endif %}
</div>
{% if typeName != "常驻祈愿" %}
<span class="date">{{val.start}} - {{val.end}}</span>
{% endif %}
</div>
<div class="list_box">
{% for v in val.list %}
<div class="item">
<div class="bg{{v.rank_type}}"></div>
<span class="num {% if v.count>=5 and v.rank_type == 5 %}life5{% endif %}">{{v.count}}</span>
<img class="role_img" src="{{ v.icon }}" alt=""/>
<div class="list_box">
{% for v in val.list %}
<div class="item">
<div class="bg{{ v.rank_type }}"></div>
<span class="num {% if v.count>=5 and v.rank_type == 5 %}life5{% endif %}">{{ v.count }}</span>
<img class="role_img" src="{{ v.icon }}" alt=""/>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% endfor %}
{% if hasMore %}
<div class="hasMore">*完整数据请私聊查看</div>
<div class="hasMore">*完整数据请私聊查看</div>
{% endif %}
<div class="logo">Template By Yunzai-Bot</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -6,12 +6,54 @@
}
@font-face {
font-family: "hywh";
src: url("../fonts/汉仪文黑-85W.ttf");
font-family: "HYWH";
src: url("../fonts/HYWenHei-35W.ttf") format("truetype");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "HYWH";
src: url("../fonts/HYWenHei-45W.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "HYWH";
src: url("../fonts/HYWenHei-55W.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "HYWH";
src: url("../fonts/HYWenHei-65W.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "HYWH";
src: url("../fonts/HYWenHei-75W.ttf") format("truetype");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "HYWH";
src: url("../fonts/HYWenHei-85W.ttf") format("truetype");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "Number";
src: url("../fonts/tttgbnumber.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
body {
font-family: "hywh", "seguiemj", emoji, system-ui;
font-family: "Number", "HYWH", "seguiemj", emoji, serif, system-ui;
}

View File

@ -1,9 +1,13 @@
from __future__ import annotations
import hashlib
import os
import re
from asyncio import create_subprocess_shell
from asyncio.subprocess import PIPE
from inspect import iscoroutinefunction
from pathlib import Path
from typing import Optional, Tuple, TypeVar, Union, cast
from typing import Awaitable, Callable, Match, Optional, Pattern, Tuple, TypeVar, Union, cast
import aiofiles
import genshin
@ -80,10 +84,7 @@ async def url_to_file(url: str, return_path: bool = False) -> str:
await f.write(data.content)
logger.debug(f"url_to_file 获取url[{url}] 并下载到 file_dir[{file_dir}]")
if return_path:
return file_dir
return Path(file_dir).as_uri()
return file_dir if return_path else Path(file_dir).as_uri()
async def get_genshin_client(user_id: int, region: Optional[RegionEnum] = None, need_cookie: bool = True) -> Client:
@ -133,9 +134,7 @@ async def get_public_genshin_client(user_id: int) -> Tuple[Client, Optional[int]
def region_server(uid: Union[int, str]) -> RegionEnum:
if isinstance(uid, int):
region = REGION_MAP.get(str(uid)[0])
elif isinstance(uid, str):
if isinstance(uid, (int, str)):
region = REGION_MAP.get(str(uid)[0])
else:
raise TypeError("UID variable type error")
@ -161,3 +160,50 @@ async def execute(command, pass_error=True):
except UnicodeDecodeError:
result = str(stdout.decode("gbk").strip())
return result
async def async_re_sub(
pattern: str | Pattern,
repl: str | Callable[[Match], str] | Callable[[Match], Awaitable[str]],
string: str,
count: int = 0,
flags: int = 0,
) -> str:
"""
一个支持 repl 参数为 async 函数的 re.sub
Args:
pattern (str | Pattern): 正则对象
repl (str | Callable[[Match], str] | Callable[[Match], Awaitable[str]]): 替换后的文本或函数
string (str): 目标文本
count (int): 要替换的最大次数
flags (int): 标志常量
Returns:
返回经替换后的字符串
"""
result = ""
temp = string
if count != 0:
for _ in range(count):
match = re.search(pattern, temp, flags=flags)
replaced = None
if iscoroutinefunction(repl):
# noinspection PyUnresolvedReferences,PyCallingNonCallable
replaced = await repl(match)
elif callable(repl):
# noinspection PyCallingNonCallable
replaced = repl(match)
result += temp[: match.span(1)[0]] + (replaced or repl)
temp = temp[match.span(1)[1] :]
else:
while match := re.search(pattern, temp, flags=flags):
replaced = None
if iscoroutinefunction(repl):
# noinspection PyUnresolvedReferences,PyCallingNonCallable
replaced = await repl(match)
elif callable(repl):
# noinspection PyCallingNonCallable
replaced = repl(match)
result += temp[: match.span(1)[0]] + (replaced or repl)
temp = temp[match.span(1)[1] :]
return result + temp

View File

@ -77,7 +77,14 @@ log_console = Console(color_system=color_system, theme=Theme(DEFAULT_STYLE), wid
class Traceback(BaseTraceback):
def __init__(self, *args, **kwargs):
kwargs.update({"show_locals": True, "max_frames": config.logger.traceback_max_frames})
kwargs.update(
{
"show_locals": True,
"max_frames": config.logger.traceback_max_frames,
"locals_max_length": 3,
"locals_max_string": 80,
}
)
super(Traceback, self).__init__(*args, **kwargs)
self.theme = PygmentsSyntaxTheme(MonokaiProStyle)