🎨 重写玩家统计

Co-authored-by: Li Chuangbo <im@chuangbo.li>
This commit is contained in:
洛水居室 2022-10-08 20:47:55 +08:00
parent bbb6cd6e82
commit aea5e41d7b
No known key found for this signature in database
GPG Key ID: C9DE87DA724B88FC
13 changed files with 701 additions and 88 deletions

View File

@ -1,11 +1,17 @@
import os
import random
import secrets
from typing import Optional
from genshin import GenshinException, Client
from genshin.models import GenshinUserStats
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, CommandHandler, MessageHandler, ConversationHandler, filters
from telegram.ext import (
CallbackContext,
CommandHandler,
MessageHandler,
ConversationHandler,
filters,
)
from core.baseplugin import BasePlugin
from core.cookies.error import CookiesNotFoundError
@ -27,86 +33,6 @@ class UserStatsPlugins(Plugin, BasePlugin):
def __init__(self, template_service: TemplateService = None):
self.template_service = template_service
self.current_dir = os.getcwd()
async def _start_get_user_info(self, client: Client, uid: int = -1) -> bytes:
if uid == -1:
_uid = client.uid
else:
_uid = uid
try:
user_info = await client.get_genshin_user(_uid)
except GenshinException as exc:
raise exc
if user_info.teapot is None:
raise TeapotUnlocked
nickname = user_info.info.nickname
user_uid = _uid
user_avatar = user_info.characters[0].icon
user_data = {
"name": nickname,
"uid": user_uid,
"user_avatar": await url_to_file(user_avatar),
"action_day_number": user_info.stats.days_active,
"achievement_number": user_info.stats.achievements,
"avatar_number": user_info.stats.characters,
"spiral_abyss": user_info.stats.spiral_abyss,
"way_point_number": user_info.stats.unlocked_waypoints,
"domain_number": user_info.stats.unlocked_domains,
"luxurious_number": user_info.stats.luxurious_chests,
"precious_chest_number": user_info.stats.precious_chests,
"exquisite_chest_number": user_info.stats.exquisite_chests,
"common_chest_number": user_info.stats.common_chests,
"magic_chest_number": user_info.stats.remarkable_chests,
"anemoculus_number": user_info.stats.anemoculi,
"geoculus_number": user_info.stats.geoculi,
"electroculus_number": user_info.stats.electroculi,
"dendroculi_number": user_info.stats.dendroculi,
"world_exploration_list": [],
"teapot_level": user_info.teapot.level,
"teapot_comfort_num": user_info.teapot.comfort,
"teapot_item_num": user_info.teapot.items,
"teapot_visit_num": user_info.teapot.visitors,
"teapot_list": []
}
for exploration in user_info.explorations:
exploration_data = {
"name": exploration.name,
"exploration_percentage": exploration.explored,
"offerings": [],
"icon": await url_to_file(exploration.icon)
}
for offering in exploration.offerings:
# 修复上游奇怪的问题
if isinstance(offering, dict):
offering_name = offering["name"]
offering_level = offering["level"]
else:
offering_name = offering.name
offering_level = offering.level
if offering_name == "Reputation":
offering_name = "声望等级"
offering_data = {
"data": f"{offering_name}{offering_level}"
}
exploration_data["offerings"].append(offering_data)
user_data["world_exploration_list"].append(exploration_data)
for teapot in user_info.teapot.realms:
teapot_icon = teapot.icon
# 修复 国际服绘绮庭 图标 地址请求 为404
if "UI_HomeworldModule_4_Pic.png" in teapot_icon:
teapot_icon = "https://upload-bbs.mihoyo.com/game_record/genshin/home/UI_HomeworldModule_4_Pic.png"
teapot_data = {
"icon": await url_to_file(teapot_icon),
"name": teapot.name
}
user_data["teapot_list"].append(teapot_data)
background_image = random.choice(os.listdir(f"{self.current_dir}/resources/background/vertical"))
user_data[
"background_image"] = f"file://{self.current_dir}/resources/background/vertical/{background_image}"
png_data = await self.template_service.render('genshin/info', "info.html", user_data,
{"width": 1024, "height": 1024})
return png_data
@handler(CommandHandler, command="stats", block=False)
@handler(MessageHandler, filters=filters.Regex("^玩家统计查询(.*)"), block=False)
@ -133,13 +59,17 @@ class UserStatsPlugins(Plugin, BasePlugin):
client, _uid = await get_public_genshin_client(user.id)
if uid == -1:
uid = _uid
png_data = await self._start_get_user_info(client, uid)
png_data = await self.render(client, uid)
except UserNotFoundError:
reply_message = await message.reply_text("未查询到账号信息,请先私聊派蒙绑定账号")
if filters.ChatType.GROUPS.filter(message):
self._add_delete_message_job(context, reply_message.chat_id, reply_message.message_id, 30)
self._add_delete_message_job(
context, reply_message.chat_id, reply_message.message_id, 30
)
self._add_delete_message_job(context, message.chat_id, message.message_id, 30)
self._add_delete_message_job(
context, message.chat_id, message.message_id, 30
)
return
except TeapotUnlocked:
await message.reply_text("角色尘歌壶未解锁 如果想要查看具体数据 嗯...... 咕咕咕~")
@ -150,4 +80,71 @@ class UserStatsPlugins(Plugin, BasePlugin):
await message.reply_text("角色数据有误 估计是派蒙晕了")
return ConversationHandler.END
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
await message.reply_photo(png_data, filename=f"{client.uid}.png", allow_sending_without_reply=True)
await message.reply_photo(
png_data, filename=f"{client.uid}.png", allow_sending_without_reply=True
)
async def render(self, client: Client, uid: int = -1) -> bytes:
if uid == -1 and client.uid:
uid = client.uid
try:
user_info = await client.get_genshin_user(uid)
logger.debug(user_info)
except GenshinException as exc:
raise exc
# 因为需要替换线上图片地址为本地地址,先克隆数据,避免修改原数据
user_info = user_info.copy(deep=True)
data = {
"uid": uid,
"info": user_info.info,
"stats": user_info.stats,
"explorations": user_info.explorations,
"teapot": user_info.teapot,
"stats_labels": [
("活跃天数", "days_active"),
("成就达成数", "achievements"),
("获取角色数", "characters"),
("深境螺旋", "spiral_abyss"),
("解锁传送点", "unlocked_waypoints"),
("解锁秘境", "unlocked_domains"),
("奇馈宝箱数", "remarkable_chests"),
("华丽宝箱数", "luxurious_chests"),
("珍贵宝箱数", "precious_chests"),
("精致宝箱数", "exquisite_chests"),
("普通宝箱数", "common_chests"),
("风神瞳", "anemoculi"),
("岩神瞳", "geoculi"),
("雷神瞳", "electroculi"),
("草神瞳", "dendroculi"),
],
"style": secrets.choice(["mondstadt", "liyue"])
}
# html = await self.template_service.render_async(
# "genshin/stats", "stats.html", data
# )
# logger.debug(html)
await self.cache_images(user_info)
return await self.template_service.render(
"genshin/stats",
"stats.html",
data,
{"width": 650, "height": 800},
full_page=True,
)
@staticmethod
async def cache_images(data: GenshinUserStats) -> None:
"""缓存所有图片到本地"""
# TODO: 并发下载所有资源
# 探索地区
for item in data.explorations:
item.__config__.allow_mutation = True
item.icon = await url_to_file(item.icon)
item.cover = await url_to_file(item.cover)

View File

@ -18,7 +18,6 @@
<i class="fa fa-address-card-o mr-2"></i>需要绑定Cookie
</div>
</div>
<div class="box pt-4 rounded-xl space-y-4 overflow-hidden">
<div>
<div class="command-background pointer-events-none">

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@ -0,0 +1,76 @@
:root {
--dark: #e0dad3;
--light: #f0ece8;
--white: #f5f5f5;
--grey: #6c6c6c;
}
body {
background-color: rgba(253, 253, 253, 0.75);
}
.header {
background-image: url(../background/liyue.png);
box-shadow: 0 0 16px rgb(255 233 144 / 50%);
}
.box {
border: 2px solid rgb(255, 233, 144, 0.5);
background-color: #9c433d;
box-shadow: 0 0 16px rgb(255 233 144 / 50%);
}
.box-title {
background-color: rgb(255, 200, 122, 0.1);
text-align: center;
line-height: 3rem;
--tw-ring-color: #ff9966;
}
.box-title h1 {
text-shadow: 0 0 1px #fff;
}
.stats-box {
color: #ffeabd;
}
.world-exploration-icon {
}
.world-exploration {
border: 1px solid rgb(255, 233, 144, 1);
background-color: rgb(255, 255, 255, 0.01);
}
.pointer-bar {
width: 95%;
height: 8px;
display: inline-block;
background-color: rgb(0, 0, 0, 0.1);
border-radius: 0.25rem;
}
.pointer-progress-bar {
border-radius: 0.25rem;
height: 100%;
background: linear-gradient(to bottom, #f5efcd, #f8eabd, #ffdf90);
}
.test {
background: linear-gradient(to bottom, #ffffff, #ffeabd, #ffdf90);
-webkit-background-clip: text;
color: transparent;
}
.test-1 {
color: #ffeabd;
background: linear-gradient(to right, rgb(0, 0, 0, 0), #cc6666, rgb(0, 0, 0, 0));
}
.about {
background-color: #e0dad3;
color: #8a4d30;
}

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<link href="../../styles/tailwind.min.css" rel="stylesheet"/>
<link href="liyue.css" rel="stylesheet"/>
</head>
<body>
<div class="container mx-auto px-5 py-10 max-w-3xl font-black">
<div class="header p-6 flex mb-8 rounded-xl bg-cover justify-between">
<div class="flex flex-col items-center justify-center">
<h1 class="text-4xl italic test mb-2">胡桃</h1>
<h1 class="text-2xl italic test-1 px-10">UID -111111111</h1>
</div>
</div>
<div class="box pt-4 rounded-xl space-y-4 overflow-hidden">
<div class="box-title text-2xl ring text-white">
<h1>数据总览</h1>
</div>
<div class="stats-box flex flex-wrap text-center">
<div class="mx-auto p-2 rounded-xl flex-1">
<div class="stats-name text-base p-1">活跃天数</div>
<div class="stats-value text-xl p-1 font-bold">114514</div>
</div>
<div class="mx-auto p-2 rounded-xl flex-1">
<div class="stats-name text-xl p-1">成就达成数</div>
<div class="stats-value text-base p-1 font-bold">test2</div>
</div>
<div class="mx-auto p-2 rounded-xl flex-1">
<div class="stats-name text-xl p-1">获取角色数</div>
<div class="stats-value text-base p-1 font-bold">test2</div>
</div>
<div class="mx-auto p-2 rounded-xl flex-1">
<div class="stats-name text-xl p-1">深境螺旋</div>
<div class="stats-value text-base p-1 font-bold">12-3</div>
</div>
</div>
<div class="box-title text-2xl ring text-white">
<h1>世界探索</h1>
</div>
<div class="stats-box flex flex-wrap text-center">
<div class="world-exploration rounded-xl flex-shrink p-2 mx-auto space-y-1">
<img class="world-exploration-icon" src="./test/UI_ChapterIcon_Mengde.png">
<div class="">蒙德</div>
<div class="text-xs">22%</div>
<div class="pointer-bar">
<div class="pointer-progress-bar" style="width: 23%"></div>
</div>
</div>
</div>
<div class="about text-center leading-8 text-xs opacity-50">
所有数据会有一小时延迟 以游戏内为准 此处仅供参考
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,49 @@
body {
background-color: #f5f6fb;
}
.header {
background-image: url(../background/mondstadt.png);
box-shadow: 0 0 8px rgb(123 242 248 / 50%);
}
.box {
background-color: #fdfdf3;
box-shadow: 0 0 8px rgb(123 242 248 / 50%);
}
.box-title {
background-color: #43849abb;
--tw-ring-color: #43849a;
}
.pointer-bar {
width: 95%;
height: 8px;
display: inline-block;
background-color: rgb(0, 0, 0, 0.2);
border-radius: 0.25rem;
}
.pointer-progress-bar {
border-radius: 0.25rem;
height: 100%;
background: #fff6e2;
}
.name {
background: linear-gradient(to bottom, #66bbee, #5ddddd, #55dddd);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.uid {
color: #fff;
background: linear-gradient(to right, rgb(0, 0, 0, 0), #5ddddd, rgb(0, 0, 0, 0));
}
.about {
background-color: #e0dad3;
color: #8a4d30;
}

View File

@ -0,0 +1,261 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<link href="./mondstadt.css" rel="stylesheet" />
<link type="text/css" href="../../../styles/public.css" rel="stylesheet" />
<script src="../../../js/tailwindcss-3.1.8.js"></script>
</head>
<body class="text-neutral-600">
<div class="mx-auto max-w-[600px] py-8">
<div class="header p-6 flex mb-8 rounded-xl bg-cover justify-between">
<div class="flex flex-col items-center justify-center">
<h1 class="text-4xl italic name mb-2 px-2">
小何
<span class="text-lg">lv.58</span>
</h1>
<h1 class="italic uid px-10">UID - 125324176</h1>
</div>
</div>
<div class="box pt-4 rounded-xl overflow-hidden">
<div>
<h2 class="box-title text-center text-xl ring text-neutral-100 p-1">
数据总览
</h2>
<div class="p-6 grid grid-cols-4 gap-4 text-center">
<div class="">
<div class="text-xl">491</div>
<div class="text-neutral-400">活跃天数</div>
</div>
<div class="">
<div class="text-xl">536</div>
<div class="text-neutral-400">成就达成数</div>
</div>
<div class="">
<div class="text-xl">38</div>
<div class="text-neutral-400">获取角色数</div>
</div>
<div class="">
<div class="text-xl">12-3</div>
<div class="text-neutral-400">深境螺旋</div>
</div>
<div class="">
<div class="text-xl">227</div>
<div class="text-neutral-400">解锁传送点</div>
</div>
<div class="">
<div class="text-xl">41</div>
<div class="text-neutral-400">解锁秘境</div>
</div>
<div class="">
<div class="text-xl">58</div>
<div class="text-neutral-400">奇馈宝箱数</div>
</div>
<div class="">
<div class="text-xl">127</div>
<div class="text-neutral-400">华丽宝箱数</div>
</div>
<div class="">
<div class="text-xl">316</div>
<div class="text-neutral-400">珍贵宝箱数</div>
</div>
<div class="">
<div class="text-xl">1180</div>
<div class="text-neutral-400">精致宝箱数</div>
</div>
<div class="">
<div class="text-xl">1591</div>
<div class="text-neutral-400">普通宝箱数</div>
</div>
<div class="">
<div class="text-xl">65</div>
<div class="text-neutral-400">风神瞳</div>
</div>
<div class="">
<div class="text-xl">131</div>
<div class="text-neutral-400">岩神瞳</div>
</div>
<div class="">
<div class="text-xl">180</div>
<div class="text-neutral-400">雷神瞳</div>
</div>
<div class="">
<div class="text-xl">79</div>
<div class="text-neutral-400">草神瞳</div>
</div>
</div>
</div>
<div>
<h2 class="box-title text-center text-xl ring text-neutral-100 p-1">
世界探索
</h2>
<div class="p-6 grid grid-cols-4 gap-4 text-center text-neutral-100">
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Xumi.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Xumi.png" />
<div class="text-sm w-full truncate">须弥</div>
<div class="text-xs">26.0%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 26.0%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_ChasmsMaw.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_ChasmsMaw.png" />
<div class="text-sm w-full truncate">层岩巨渊·地下矿区</div>
<div class="text-xs">98.7%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 98.7%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_ChasmsMaw.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_ChasmsMaw.png" />
<div class="text-sm w-full truncate">层岩巨渊</div>
<div class="text-xs">92.9%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 92.9%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Enkanomiya.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Enkanomiya.png" />
<div class="text-sm w-full truncate">渊下宫</div>
<div class="text-xs">98.3%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 98.3%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Daoqi.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Daoqi.png" />
<div class="text-sm w-full truncate">稻妻</div>
<div class="text-xs">100.0%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 100.0%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Dragonspine.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Dragonspine.png" />
<div class="text-sm w-full truncate">龙脊雪山</div>
<div class="text-xs">83.6%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 83.6%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Liyue.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Liyue.png" />
<div class="text-sm w-full truncate">璃月</div>
<div class="text-xs">95.9%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 95.9%"
></div>
</div>
</div>
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image:
url('https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterCover_Mengde.png');"
>
<img class="w-3/5"
src="https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Mengde.png" />
<div class="text-sm w-full truncate">蒙德</div>
<div class="text-xs">100.0%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: 100.0%"
></div>
</div>
</div>
</div>
</div>
<div class="about text-center leading-8 text-xs opacity-50">
所有数据会有一小时延迟 以游戏内为准 此处仅供参考
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,53 @@
body {
background-color: #f5f6fb;
}
.header {
background-image: url(background/liyue.png);
box-shadow: 0 0 16px rgb(255 233 144 / 50%);
}
.box {
background-color: #9c433d;
box-shadow: 0 0 16px rgb(255 233 144 / 50%);
}
.box-title {
background-color: rgb(255, 200, 122, 0.1);
--tw-ring-color: #ff9966;
}
.pointer-bar {
width: 95%;
height: 8px;
display: inline-block;
background-color: rgb(0, 0, 0, 0.1);
border-radius: 0.25rem;
}
.pointer-progress-bar {
border-radius: 0.25rem;
height: 100%;
background: linear-gradient(to bottom, #f5efcd, #f8eabd, #ffdf90);
}
.name {
background: linear-gradient(to bottom, #ffffff, #ffeabd, #ffdf90);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.uid {
color: #ffeabd;
background: linear-gradient(to right, rgb(0, 0, 0, 0), #cc6666, rgb(0, 0, 0, 0));
}
.about {
background-color: #e0dad3;
color: #8a4d30;
}
.box-stats {
color: #ffeabd;
}

View File

@ -0,0 +1,49 @@
body {
background-color: #f5f6fb;
}
.header {
background-image: url(background/mondstadt.png);
box-shadow: 0 0 8px rgb(123 242 248 / 50%);
}
.box {
background-color: #fdfdf3;
box-shadow: 0 0 8px rgb(123 242 248 / 50%);
}
.box-title {
background-color: #43849abb;
--tw-ring-color: #43849a;
}
.pointer-bar {
width: 95%;
height: 8px;
display: inline-block;
background-color: rgb(0, 0, 0, 0.2);
border-radius: 0.25rem;
}
.pointer-progress-bar {
border-radius: 0.25rem;
height: 100%;
background: #fff6e2;
}
.name {
background: linear-gradient(to bottom, #66bbee, #5ddddd, #55dddd);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.uid {
color: #fff;
background: linear-gradient(to right, rgb(0, 0, 0, 0), #5ddddd, rgb(0, 0, 0, 0));
}
.about {
background-color: #e0dad3;
color: #8a4d30;
}

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<link href="./{{style}}.css" rel="stylesheet" />
<link type="text/css" href="../../styles/public.css" rel="stylesheet" />
<script src="../../js/tailwindcss-3.1.8.js"></script>
</head>
<body class="text-neutral-600">
<div class="mx-auto max-w-[600px] py-8">
<div class="header p-6 flex mb-8 rounded-xl bg-cover justify-between">
<div class="flex flex-col items-center justify-center">
<h1 class="text-4xl italic name mb-2 px-2">
{{ info.nickname }}
<span class="text-lg">lv.{{ info.level }}</span>
</h1>
<h1 class="italic uid px-10">UID - {{ uid }}</h1>
</div>
</div>
<div class="box pt-4 rounded-xl overflow-hidden">
<div>
<h2 class="box-title text-center text-xl ring text-neutral-100 p-1">
数据总览
</h2>
<div class="p-6 grid grid-cols-4 gap-4 text-center">
{% for label, key in stats_labels %}
<div class="">
<div class="text-xl box-stats">{{ stats[key] }}</div>
<div class="text-neutral-400">{{ label }}</div>
</div>
{% endfor %}
</div>
</div>
<div>
<h2 class="box-title text-center text-xl ring text-neutral-100 p-1">
世界探索
</h2>
<div class="p-6 grid grid-cols-4 gap-4 text-center text-neutral-100">
{% for e in explorations %}
<div
class="w-full flex flex-col items-center rounded-lg p-2 space-y-1 bg-cover"
style="background-image: url('{{ e.cover }}');"
>
<img class="w-3/5" src="{{ e.icon }}" />
<div class="text-sm w-full truncate">{{ e.name }}</div>
<div class="text-xs">{{ e.explored }}%</div>
<div class="pointer-bar">
<div
class="pointer-progress-bar"
style="width: {{ e.explored }}%"
></div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="about text-center leading-8 text-xs opacity-50">
所有数据会有一小时延迟 以游戏内为准 此处仅供参考
</div>
</div>
</div>
</body>
</html>