✨ Support starrail activity - FantasticStory
@ -1,7 +1,6 @@
|
||||
from typing import Optional, List, Dict, TYPE_CHECKING
|
||||
|
||||
from simnet.errors import BadRequest as SimnetBadRequest
|
||||
from simnet.models.starrail.chronicle.activity import StarRailStarFight
|
||||
from simnet.models.starrail.chronicle.activity import StarRailStarFight, StarRailFantasticStory
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, Message
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import CallbackContext, filters
|
||||
@ -9,7 +8,6 @@ from telegram.helpers import create_deep_linked_url
|
||||
|
||||
from core.dependence.assets import AssetsService
|
||||
from core.plugin import Plugin, handler
|
||||
from core.services.cookies.error import TooManyRequestPublicCookies
|
||||
from core.services.template.models import RenderResult
|
||||
from core.services.template.services import TemplateService
|
||||
from plugins.tools.genshin import GenshinHelper, PlayerNotFoundError, CookiesNotFoundError
|
||||
@ -74,15 +72,9 @@ class PlayerActivityPlugins(Plugin):
|
||||
logger.info("用户 %s[%s] 查询星芒战幕信息命令请求", user.full_name, user.id)
|
||||
try:
|
||||
uid = await self.get_uid(user.id, context.args, message.reply_to_message)
|
||||
try:
|
||||
async with self.helper.genshin(user.id) as client:
|
||||
if client.player_id != uid:
|
||||
raise CookiesNotFoundError(uid)
|
||||
render_result = await self.star_fight_render(client, uid)
|
||||
except CookiesNotFoundError:
|
||||
async with self.helper.public_genshin(user.id) as client:
|
||||
render_result = await self.star_fight_render(client, uid)
|
||||
except PlayerNotFoundError:
|
||||
async with self.helper.genshin(user.id) as client:
|
||||
render_result = await self.star_fight_render(client, uid)
|
||||
except (PlayerNotFoundError, CookiesNotFoundError):
|
||||
buttons = [[InlineKeyboardButton("点我绑定账号", url=create_deep_linked_url(context.bot.username, "set_cookie"))]]
|
||||
if filters.ChatType.GROUPS.filter(message):
|
||||
reply_message = await message.reply_text(
|
||||
@ -93,25 +85,11 @@ class PlayerActivityPlugins(Plugin):
|
||||
else:
|
||||
await message.reply_text("未查询到您所绑定的账号信息,请先绑定账号", reply_markup=InlineKeyboardMarkup(buttons))
|
||||
return
|
||||
except SimnetBadRequest as exc:
|
||||
if exc.retcode == 1034:
|
||||
await message.reply_text("出错了呜呜呜 ~ 请稍后重试")
|
||||
return
|
||||
raise exc
|
||||
except TooManyRequestPublicCookies:
|
||||
await message.reply_text("用户查询次数过多 请稍后重试")
|
||||
return
|
||||
except AttributeError as exc:
|
||||
logger.error("活动数据有误")
|
||||
logger.exception(exc)
|
||||
await message.reply_text("活动数据有误 估计是彦卿晕了")
|
||||
return
|
||||
except NotSupport:
|
||||
reply_message = await message.reply_text("暂不支持该服务器查询活动数据")
|
||||
if filters.ChatType.GROUPS.filter(reply_message):
|
||||
self.add_delete_message_job(message)
|
||||
self.add_delete_message_job(reply_message)
|
||||
return
|
||||
except NotHaveData:
|
||||
reply_message = await message.reply_text("没有查找到此活动数据")
|
||||
if filters.ChatType.GROUPS.filter(reply_message):
|
||||
@ -152,3 +130,70 @@ class PlayerActivityPlugins(Plugin):
|
||||
full_page=True,
|
||||
query_selector="#container",
|
||||
)
|
||||
|
||||
@handler.command("fantastic_story", block=False)
|
||||
@handler.message(filters.Regex("^评书奇谭信息查询(.*)"), block=False)
|
||||
async def fantastic_story_command_start(self, update: Update, context: CallbackContext) -> Optional[int]:
|
||||
user = update.effective_user
|
||||
message = update.effective_message
|
||||
logger.info("用户 %s[%s] 查询评书奇谭信息命令请求", user.full_name, user.id)
|
||||
try:
|
||||
uid = await self.get_uid(user.id, context.args, message.reply_to_message)
|
||||
async with self.helper.genshin(user.id) as client:
|
||||
render_result = await self.fantastic_story_render(client, uid)
|
||||
except PlayerNotFoundError:
|
||||
buttons = [[InlineKeyboardButton("点我绑定账号", url=create_deep_linked_url(context.bot.username, "set_cookie"))]]
|
||||
if filters.ChatType.GROUPS.filter(message):
|
||||
reply_message = await message.reply_text(
|
||||
"未查询到您所绑定的账号信息,请先私聊彦卿绑定账号", reply_markup=InlineKeyboardMarkup(buttons)
|
||||
)
|
||||
self.add_delete_message_job(reply_message, delay=30)
|
||||
self.add_delete_message_job(message, delay=30)
|
||||
else:
|
||||
await message.reply_text("未查询到您所绑定的账号信息,请先绑定账号", reply_markup=InlineKeyboardMarkup(buttons))
|
||||
return
|
||||
except AttributeError as exc:
|
||||
logger.error("活动数据有误")
|
||||
logger.exception(exc)
|
||||
await message.reply_text("活动数据有误 估计是彦卿晕了")
|
||||
return
|
||||
except NotHaveData:
|
||||
reply_message = await message.reply_text("没有查找到此活动数据")
|
||||
if filters.ChatType.GROUPS.filter(reply_message):
|
||||
self.add_delete_message_job(message)
|
||||
self.add_delete_message_job(reply_message)
|
||||
return
|
||||
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
||||
await render_result.reply_photo(message, filename=f"{user.id}.png", allow_sending_without_reply=True)
|
||||
|
||||
async def get_fantastic_story_rander_data(self, uid: int, data: StarRailFantasticStory) -> Dict:
|
||||
if not data.exists_data:
|
||||
raise NotHaveData
|
||||
avatar_icons = {}
|
||||
for record in data.records:
|
||||
for avatar in record.avatars:
|
||||
avatar_icons[avatar.id] = self.assets.avatar.square(avatar.id).as_uri()
|
||||
return {
|
||||
"uid": uid,
|
||||
"records": data.records,
|
||||
"avatar_icons": avatar_icons,
|
||||
}
|
||||
|
||||
async def fantastic_story_render(self, client: "StarRailClient", uid: Optional[int] = None) -> RenderResult:
|
||||
if uid is None:
|
||||
uid = client.player_id
|
||||
|
||||
act_data = await client.get_starrail_activity(uid)
|
||||
try:
|
||||
fantastic_story_data = act_data.fantastic_story
|
||||
except ValueError:
|
||||
raise NotHaveData
|
||||
data = await self.get_fantastic_story_rander_data(uid, fantastic_story_data)
|
||||
|
||||
return await self.template_service.render(
|
||||
"starrail/activity/fantastic_story.html",
|
||||
data,
|
||||
{"width": 500, "height": 1200},
|
||||
full_page=True,
|
||||
query_selector="#container",
|
||||
)
|
||||
|
1948
resources/starrail/activity/css/32_a6abfefd22b3d1a40162.css
Normal file
189
resources/starrail/activity/css/7_1860676e902f99970620.css
Normal file
@ -0,0 +1,189 @@
|
||||
/*! Copyright © 2011 - 2023 miHoYo. All Rights Reserved */
|
||||
.no-data[data-v-5b777587] {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.no-data .text[data-v-5b777587] {
|
||||
margin-top: 2.66667vw;
|
||||
font-size: 3.73333vw;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #7f858a;
|
||||
height: 3.73333vw;
|
||||
line-height: 3.73333vw
|
||||
}
|
||||
|
||||
.item.is-editable.unable-be-select[data-v-03247942] {
|
||||
opacity: .3
|
||||
}
|
||||
|
||||
.item .name[data-v-03247942] {
|
||||
height: 3.73333vw;
|
||||
font-size: 3.73333vw;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #1e1f20;
|
||||
line-height: 3.73333vw;
|
||||
margin-top: 2.13333vw;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.item .name .text[data-v-03247942] {
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
height: 3.73333vw;
|
||||
line-height: 3.73333vw;
|
||||
width: 22.4vw;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
left: -.8vw
|
||||
}
|
||||
|
||||
.item .inner[data-v-03247942] {
|
||||
width: 100%;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.item .inner .select-label[data-v-03247942], .item .inner[data-v-03247942] {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.item .inner .select-label[data-v-03247942] {
|
||||
width: 5.33333vw;
|
||||
height: 5.33333vw;
|
||||
border: .53333vw solid #fff;
|
||||
position: absolute;
|
||||
top: 1.06667vw;
|
||||
right: 1.06667vw;
|
||||
font-size: 3.73333vw;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border-radius: 100%
|
||||
}
|
||||
|
||||
.item .inner .select-label.selected[data-v-03247942] {
|
||||
background: #f69502
|
||||
}
|
||||
|
||||
.item .inner .avatar-box[data-v-03247942] {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
border-radius: 0 4vw 0 0
|
||||
}
|
||||
|
||||
.item .inner .avatar-box .avatar-bg[data-v-03247942] {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 0
|
||||
}
|
||||
|
||||
.item .inner .avatar[data-v-03247942] {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
top: -.53333vw;
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.item .inner .icon[data-v-03247942] {
|
||||
position: absolute;
|
||||
left: 1.6vw;
|
||||
top: 1.6vw
|
||||
}
|
||||
|
||||
.item .inner .index[data-v-03247942] {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 4.8vw;
|
||||
height: 5.86667vw;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
border-radius: 0 4vw 0 1.6vw;
|
||||
font-size: 3.73333vw;
|
||||
line-height: 3.73333vw
|
||||
}
|
||||
|
||||
.item .inner .index[data-v-03247942], .item .inner .level[data-v-03247942] {
|
||||
position: absolute;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.item .inner .level[data-v-03247942] {
|
||||
bottom: .53333vw;
|
||||
left: 0;
|
||||
height: 3.73333vw;
|
||||
background: #030b0e;
|
||||
width: 100%;
|
||||
font-size: 3.2vw;
|
||||
line-height: 3.2vw
|
||||
}
|
||||
|
||||
.item .inner .trial[data-v-03247942] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 1px 1.06667vw;
|
||||
background: #ffc870;
|
||||
border-radius: 2.66667vw;
|
||||
font-weight: 500;
|
||||
font-size: 2.66667vw;
|
||||
line-height: 2.66667vw;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
color: #000;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center
|
||||
}
|
88
resources/starrail/activity/fantastic_story.html
Normal file
@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Fantastic Story</title>
|
||||
<link href="css/7_1860676e902f99970620.css" rel="stylesheet">
|
||||
<link href="css/32_a6abfefd22b3d1a40162.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div data-v-6cd4e78c="" data-v-056bcd56="" class="layout"
|
||||
style="background: url('images/story-bg.436f1d88.png') 0% 0% / 100% no-repeat rgb(71, 89, 131);">
|
||||
<div data-v-6cd4e78c="" class="header">
|
||||
<div data-v-6cd4e78c="" class="border">
|
||||
<div data-v-6cd4e78c="" class="left"><span data-v-6cd4e78c="">评书奇谭</span></div> <!---->
|
||||
</div>
|
||||
</div>
|
||||
<div data-v-6cd4e78c="" class="container">
|
||||
<div data-v-6cd4e78c="" class="border">
|
||||
{% set bg = ['1.96e45c02', '2.3f186847', '3.f7c6b1e9', '4.32486a3e', '5.426291c0', '6.b4b0eadf'] %}
|
||||
{% set level_icon = ['', '1212', '1213', '1214', '1215'] %}
|
||||
{% for record in records %}
|
||||
{% set not_challenge = record.score == 0 %}
|
||||
<div data-v-44091bd3="" class="card" data-v-6cd4e78c="">
|
||||
<div data-v-44091bd3="" class="bg {% if not_challenge %}not-challenged{% endif %}">
|
||||
<img data-v-44091bd3="" src="images/{{ bg[loop.index0] }}.png" class="icon">
|
||||
</div>
|
||||
<div data-v-44091bd3="" class="inner {% if not_challenge %}not-challenged{% endif %}">
|
||||
<div data-v-44091bd3="" class="header">
|
||||
<div data-v-44091bd3="" class="name">
|
||||
{{ record.name }}
|
||||
{% if not not_challenge %}
|
||||
<span data-v-44091bd3="">{{ record.time_str }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not not_challenge %}
|
||||
<div data-v-44091bd3="" class="info">
|
||||
<div data-v-44091bd3="" class="round">文段分数 {{ record.score }}</div>
|
||||
</div>
|
||||
<div data-v-44091bd3="" class="right">
|
||||
<img data-v-44091bd3="" src="images/{{ level_icon[record.score_rank] }}.png"
|
||||
class="icon">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not_challenge %}
|
||||
<div data-v-44091bd3="" class="not-challenged-text">尚未挑战</div>
|
||||
{% else %}
|
||||
<div data-v-44091bd3="" class="line"></div>
|
||||
<div data-v-44091bd3="" class="roles">
|
||||
{% for role in record.avatars %}
|
||||
<div data-v-03247942="" data-v-44091bd3=""
|
||||
class="role-item item unable-be-select">
|
||||
<div data-v-03247942="" class="inner">
|
||||
<div data-v-03247942="" class="avatar-box"
|
||||
style="width: 16.5333vw; height: 19.2vw;">
|
||||
<div data-v-03247942="" class="avatar-bg"
|
||||
style="background: url('{{ avatar_icons[role.id] }}') center center / 100% no-repeat;"></div>
|
||||
<div data-v-03247942="" class="level">等级 {{ role.level }}</div>
|
||||
</div>
|
||||
{% if role.is_trial %}
|
||||
<div data-v-03247942="" class="trial">试用</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div data-v-44091bd3="" class="buffs">
|
||||
{% for buff in record.buffs %}
|
||||
<div data-v-44091bd3="" class="buff-item">
|
||||
<div data-v-44091bd3="" class="icon"
|
||||
style="background-image: url('{{ buff.icon }}');"></div>
|
||||
<div data-v-44091bd3="" class="text">
|
||||
{{ buff.name }}:{{ buff.desc }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
resources/starrail/activity/images/1.96e45c02.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
resources/starrail/activity/images/1212.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
resources/starrail/activity/images/1213.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
resources/starrail/activity/images/1214.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
resources/starrail/activity/images/1215.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
resources/starrail/activity/images/2.3f186847.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
resources/starrail/activity/images/3.f7c6b1e9.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
resources/starrail/activity/images/4.32486a3e.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
resources/starrail/activity/images/5.426291c0.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
resources/starrail/activity/images/6.b4b0eadf.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
resources/starrail/activity/images/story-bg.436f1d88.png
Normal file
After Width: | Height: | Size: 81 KiB |