2024-06-19 08:29:47 +00:00
|
|
|
|
from functools import partial
|
2022-10-08 10:56:40 +00:00
|
|
|
|
from io import BytesIO
|
2024-03-13 07:38:49 +00:00
|
|
|
|
from typing import Optional, TYPE_CHECKING, List, Union, Tuple
|
2023-09-12 14:58:08 +00:00
|
|
|
|
from urllib.parse import urlencode
|
2022-10-08 10:56:40 +00:00
|
|
|
|
|
2022-10-21 11:34:49 +00:00
|
|
|
|
from aiofiles import open as async_open
|
2024-12-01 13:55:44 +00:00
|
|
|
|
from simnet import GenshinClient, Region, Game
|
|
|
|
|
from simnet.client.routes import GACHA_INFO_URL
|
2023-07-18 09:29:31 +00:00
|
|
|
|
from simnet.models.genshin.wish import BannerType
|
2024-12-01 09:30:08 +00:00
|
|
|
|
from telegram import (
|
|
|
|
|
InlineKeyboardButton,
|
|
|
|
|
InlineKeyboardMarkup,
|
|
|
|
|
ReplyKeyboardMarkup,
|
|
|
|
|
ReplyKeyboardRemove,
|
|
|
|
|
TelegramObject,
|
|
|
|
|
)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
from telegram.constants import ChatAction
|
2023-12-02 04:18:45 +00:00
|
|
|
|
from telegram.ext import ConversationHandler, filters
|
2022-11-28 08:38:49 +00:00
|
|
|
|
from telegram.helpers import create_deep_linked_url
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from core.basemodel import RegionEnum
|
|
|
|
|
from core.dependence.assets import AssetsService
|
|
|
|
|
from core.plugin import Plugin, conversation, handler
|
|
|
|
|
from core.services.cookies import CookiesService
|
|
|
|
|
from core.services.players import PlayersService
|
|
|
|
|
from core.services.template.models import FileType
|
|
|
|
|
from core.services.template.services import TemplateService
|
2024-03-13 07:38:49 +00:00
|
|
|
|
from gram_core.config import config
|
2024-06-19 08:29:47 +00:00
|
|
|
|
from gram_core.plugin.methods.inline_use_data import IInlineUseData
|
2024-09-12 13:13:05 +00:00
|
|
|
|
from gram_core.services.gacha_log_rank.services import GachaLogRankService
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from metadata.scripts.paimon_moe import GACHA_LOG_PAIMON_MOE_PATH, update_paimon_moe_zh
|
2024-03-13 07:38:49 +00:00
|
|
|
|
from modules.gacha_log.const import UIGF_VERSION, GACHA_TYPE_LIST_REVERSE
|
2022-10-21 11:34:49 +00:00
|
|
|
|
from modules.gacha_log.error import (
|
|
|
|
|
GachaLogAccountNotFound,
|
2022-12-28 13:57:40 +00:00
|
|
|
|
GachaLogAuthkeyTimeout,
|
2023-03-14 01:27:22 +00:00
|
|
|
|
GachaLogFileError,
|
|
|
|
|
GachaLogInvalidAuthkey,
|
|
|
|
|
GachaLogMixedProvider,
|
|
|
|
|
GachaLogNotFound,
|
|
|
|
|
PaimonMoeGachaLogFileError,
|
2024-09-08 14:45:03 +00:00
|
|
|
|
GachaLogWebError,
|
2022-10-21 11:34:49 +00:00
|
|
|
|
)
|
|
|
|
|
from modules.gacha_log.helpers import from_url_get_authkey
|
|
|
|
|
from modules.gacha_log.log import GachaLog
|
2023-12-16 10:01:27 +00:00
|
|
|
|
from modules.gacha_log.migrate import GachaLogMigrate
|
2024-03-13 07:38:49 +00:00
|
|
|
|
from modules.gacha_log.models import GachaLogInfo
|
2023-09-01 02:04:39 +00:00
|
|
|
|
from plugins.tools.genshin import PlayerNotFoundError
|
2023-04-28 01:19:20 +00:00
|
|
|
|
from plugins.tools.player_info import PlayerInfoSystem
|
2022-10-08 08:50:02 +00:00
|
|
|
|
from utils.log import logger
|
|
|
|
|
|
2023-01-07 08:00:32 +00:00
|
|
|
|
try:
|
|
|
|
|
import ujson as jsonlib
|
|
|
|
|
|
|
|
|
|
except ImportError:
|
|
|
|
|
import json as jsonlib
|
|
|
|
|
|
2023-12-02 04:18:45 +00:00
|
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from telegram import Update, Message, User, Document
|
|
|
|
|
from telegram.ext import ContextTypes
|
2023-12-16 10:01:27 +00:00
|
|
|
|
from gram_core.services.players.models import Player
|
2024-03-13 07:38:49 +00:00
|
|
|
|
from gram_core.services.template.models import RenderResult
|
2023-12-02 04:18:45 +00:00
|
|
|
|
|
2024-12-01 09:30:08 +00:00
|
|
|
|
INPUT_URL, INPUT_LAZY, CONFIRM_DELETE = range(10100, 10103)
|
2024-12-01 16:24:40 +00:00
|
|
|
|
WAITING = f"小{config.notice.bot_name}正在从服务器获取数据,请稍候"
|
2024-06-07 15:22:30 +00:00
|
|
|
|
WISHLOG_NOT_FOUND = f"{config.notice.bot_name}没有找到你的抽卡记录,快来私聊{config.notice.bot_name}导入吧~"
|
2024-09-08 14:45:03 +00:00
|
|
|
|
WISHLOG_WEB = """<b>抽卡记录详细信息查询</b>
|
|
|
|
|
|
|
|
|
|
已为您创建一枚令牌,点击下方按钮可直接进行查询。
|
|
|
|
|
|
|
|
|
|
有效期为 1 小时,过期需重新申请。如怀疑泄漏请立即重新申请。"""
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
|
|
|
|
|
2024-12-01 09:30:08 +00:00
|
|
|
|
class WishLogPluginData(TelegramObject):
|
|
|
|
|
player_id: int = 0
|
|
|
|
|
authkey: str = ""
|
|
|
|
|
|
|
|
|
|
def reset_data(self):
|
|
|
|
|
self.player_id = 0
|
|
|
|
|
self.authkey = ""
|
|
|
|
|
|
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
class WishLogPlugin(Plugin.Conversation):
|
2022-10-09 03:07:22 +00:00
|
|
|
|
"""抽卡记录导入/导出/分析"""
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2023-12-02 04:18:45 +00:00
|
|
|
|
IMPORT_HINT = (
|
|
|
|
|
"<b>开始导入祈愿历史记录:请通过 https://paimon.moe/wish/import 获取抽卡记录链接后发送给我"
|
|
|
|
|
"(非 paimon.moe 导出的文件数据)</b>\n\n"
|
2024-06-07 15:22:30 +00:00
|
|
|
|
f"> 你还可以向{config.notice.bot_name}发送从其他工具导出的 UIGF {UIGF_VERSION} 标准的记录文件\n"
|
2023-12-02 04:18:45 +00:00
|
|
|
|
"> 或者从 paimon.moe 、非小酋 导出的 xlsx 记录文件\n"
|
|
|
|
|
"> 在绑定 Cookie 时添加 stoken 可能有特殊效果哦(仅限国服)\n"
|
|
|
|
|
"<b>注意:导入的数据将会与旧数据进行合并。</b>"
|
|
|
|
|
)
|
|
|
|
|
|
2022-10-09 03:07:22 +00:00
|
|
|
|
def __init__(
|
2022-10-11 04:00:55 +00:00
|
|
|
|
self,
|
2023-03-14 01:27:22 +00:00
|
|
|
|
template_service: TemplateService,
|
|
|
|
|
players_service: PlayersService,
|
|
|
|
|
assets: AssetsService,
|
|
|
|
|
cookie_service: CookiesService,
|
2023-04-28 01:19:20 +00:00
|
|
|
|
player_info: PlayerInfoSystem,
|
2024-09-12 13:13:05 +00:00
|
|
|
|
gacha_log_rank: GachaLogRankService,
|
2022-10-09 03:07:22 +00:00
|
|
|
|
):
|
2022-10-08 08:50:02 +00:00
|
|
|
|
self.template_service = template_service
|
2023-03-14 01:27:22 +00:00
|
|
|
|
self.players_service = players_service
|
2022-10-08 08:50:02 +00:00
|
|
|
|
self.assets_service = assets
|
2022-10-11 04:00:55 +00:00
|
|
|
|
self.cookie_service = cookie_service
|
2022-10-21 11:34:49 +00:00
|
|
|
|
self.zh_dict = None
|
2024-09-12 13:13:05 +00:00
|
|
|
|
self.gacha_log = GachaLog(gacha_log_rank_service=gacha_log_rank)
|
2023-04-28 01:19:20 +00:00
|
|
|
|
self.player_info = player_info
|
2024-03-13 07:38:49 +00:00
|
|
|
|
self.wish_photo = None
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
async def initialize(self) -> None:
|
2022-10-21 11:34:49 +00:00
|
|
|
|
await update_paimon_moe_zh(False)
|
|
|
|
|
async with async_open(GACHA_LOG_PAIMON_MOE_PATH, "r", encoding="utf-8") as load_f:
|
2023-01-07 08:00:32 +00:00
|
|
|
|
self.zh_dict = jsonlib.loads(await load_f.read())
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def get_player_id(self, user_id: int, player_id: int, offset: int) -> int:
|
2023-07-19 03:41:40 +00:00
|
|
|
|
"""获取绑定的游戏ID"""
|
|
|
|
|
logger.debug("尝试获取已绑定的原神账号")
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player = await self.players_service.get_player(user_id, player_id=player_id, offset=offset)
|
2023-07-19 03:41:40 +00:00
|
|
|
|
if player is None:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
raise PlayerNotFoundError(user_id)
|
2023-07-19 03:41:40 +00:00
|
|
|
|
return player.player_id
|
|
|
|
|
|
2022-10-21 11:34:49 +00:00
|
|
|
|
async def _refresh_user_data(
|
2024-12-01 09:30:08 +00:00
|
|
|
|
self,
|
|
|
|
|
user: "User",
|
|
|
|
|
player_id: int,
|
|
|
|
|
data: dict = None,
|
|
|
|
|
authkey: str = None,
|
|
|
|
|
verify_uid: bool = True,
|
|
|
|
|
is_lazy: bool = True,
|
2022-10-21 11:34:49 +00:00
|
|
|
|
) -> str:
|
2022-10-08 08:50:02 +00:00
|
|
|
|
"""刷新用户数据
|
|
|
|
|
:param user: 用户
|
|
|
|
|
:param data: 数据
|
|
|
|
|
:param authkey: 认证密钥
|
|
|
|
|
:return: 返回信息
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
logger.debug("尝试获取已绑定的原神账号")
|
|
|
|
|
if authkey:
|
2024-12-01 09:30:08 +00:00
|
|
|
|
new_num = await self.gacha_log.get_gacha_log_data(user.id, player_id, authkey, is_lazy)
|
2022-10-21 11:34:49 +00:00
|
|
|
|
return "更新完成,本次没有新增数据" if new_num == 0 else f"更新完成,本次共新增{new_num}条抽卡记录"
|
2022-10-08 08:50:02 +00:00
|
|
|
|
if data:
|
2023-07-19 03:41:40 +00:00
|
|
|
|
new_num = await self.gacha_log.import_gacha_log_data(user.id, player_id, data, verify_uid)
|
2022-10-21 11:34:49 +00:00
|
|
|
|
return "更新完成,本次没有新增数据" if new_num == 0 else f"更新完成,本次共新增{new_num}条抽卡记录"
|
|
|
|
|
except GachaLogNotFound:
|
2024-06-07 15:22:30 +00:00
|
|
|
|
return WAITING
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogAccountNotFound:
|
|
|
|
|
return "导入失败,可能文件包含的祈愿记录所属 uid 与你当前绑定的 uid 不同"
|
|
|
|
|
except GachaLogFileError:
|
|
|
|
|
return "导入失败,数据格式错误"
|
|
|
|
|
except GachaLogInvalidAuthkey:
|
|
|
|
|
return "更新数据失败,authkey 无效"
|
2022-12-28 13:57:40 +00:00
|
|
|
|
except GachaLogAuthkeyTimeout:
|
|
|
|
|
return "更新数据失败,authkey 已经过期"
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogMixedProvider:
|
|
|
|
|
return "导入失败,你已经通过其他方式导入过抽卡记录了,本次无法导入"
|
2023-03-14 01:27:22 +00:00
|
|
|
|
except PlayerNotFoundError:
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id)
|
2024-06-07 15:22:30 +00:00
|
|
|
|
return config.notice.user_not_found
|
2022-10-08 10:56:40 +00:00
|
|
|
|
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def import_from_file(
|
|
|
|
|
self, user: "User", player_id: int, message: "Message", document: "Optional[Document]" = None
|
|
|
|
|
) -> None:
|
2022-10-08 10:56:40 +00:00
|
|
|
|
if not document:
|
|
|
|
|
document = message.document
|
2022-10-20 07:48:40 +00:00
|
|
|
|
# TODO: 使用 mimetype 判断文件类型
|
|
|
|
|
if document.file_name.endswith(".xlsx"):
|
|
|
|
|
file_type = "xlsx"
|
|
|
|
|
elif document.file_name.endswith(".json"):
|
|
|
|
|
file_type = "json"
|
|
|
|
|
else:
|
2022-10-21 11:34:49 +00:00
|
|
|
|
await message.reply_text(
|
2024-12-01 16:24:40 +00:00
|
|
|
|
"文件格式错误,请发送符合 UIGF 标准的抽卡记录文件或者 paimon.moe、非小酋导出的 xlsx 格式的抽卡记录文件",
|
|
|
|
|
reply_markup=ReplyKeyboardRemove(),
|
2022-10-21 11:34:49 +00:00
|
|
|
|
)
|
|
|
|
|
return
|
2023-12-02 04:18:45 +00:00
|
|
|
|
if document.file_size > 5 * 1024 * 1024:
|
2024-12-01 16:24:40 +00:00
|
|
|
|
await message.reply_text("文件过大,请发送小于 5 MB 的文件", reply_markup=ReplyKeyboardRemove())
|
2022-10-21 11:34:49 +00:00
|
|
|
|
return
|
2022-10-08 10:56:40 +00:00
|
|
|
|
try:
|
2022-11-25 07:33:25 +00:00
|
|
|
|
out = BytesIO()
|
|
|
|
|
await (await document.get_file()).download_to_memory(out=out)
|
2022-10-20 07:48:40 +00:00
|
|
|
|
if file_type == "json":
|
|
|
|
|
# bytesio to json
|
2023-01-07 08:00:32 +00:00
|
|
|
|
data = jsonlib.loads(out.getvalue().decode("utf-8"))
|
2022-10-21 11:34:49 +00:00
|
|
|
|
elif file_type == "xlsx":
|
2022-11-25 07:33:25 +00:00
|
|
|
|
data = self.gacha_log.convert_xlsx_to_uigf(out, self.zh_dict)
|
2022-12-22 15:50:37 +00:00
|
|
|
|
else:
|
2024-12-01 16:24:40 +00:00
|
|
|
|
await message.reply_text("文件解析失败,请检查文件", reply_markup=ReplyKeyboardRemove())
|
2022-12-22 15:50:37 +00:00
|
|
|
|
return
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except PaimonMoeGachaLogFileError as exc:
|
|
|
|
|
await message.reply_text(
|
2024-12-01 16:24:40 +00:00
|
|
|
|
f"导入失败,PaimonMoe的抽卡记录当前版本不支持\n支持抽卡记录的版本为 {exc.support_version},你的抽卡记录版本为 {exc.file_version}",
|
|
|
|
|
reply_markup=ReplyKeyboardRemove(),
|
2022-10-21 11:34:49 +00:00
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
except GachaLogFileError:
|
2024-12-01 16:24:40 +00:00
|
|
|
|
await message.reply_text(
|
|
|
|
|
f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准", reply_markup=ReplyKeyboardRemove()
|
|
|
|
|
)
|
2022-10-21 11:34:49 +00:00
|
|
|
|
return
|
|
|
|
|
except (KeyError, IndexError, ValueError):
|
2024-12-01 16:24:40 +00:00
|
|
|
|
await message.reply_text(
|
|
|
|
|
f"文件解析失败,请检查文件编码是否正确或符合 UIGF {UIGF_VERSION} 标准",
|
|
|
|
|
reply_markup=ReplyKeyboardRemove(),
|
|
|
|
|
)
|
2022-10-11 06:45:07 +00:00
|
|
|
|
return
|
2022-10-08 10:56:40 +00:00
|
|
|
|
except Exception as exc:
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.error("文件解析失败 %s", repr(exc))
|
2024-12-01 16:24:40 +00:00
|
|
|
|
await message.reply_text(
|
|
|
|
|
f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准", reply_markup=ReplyKeyboardRemove()
|
|
|
|
|
)
|
2022-10-08 10:56:40 +00:00
|
|
|
|
return
|
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
2024-12-01 16:24:40 +00:00
|
|
|
|
reply = await message.reply_text("文件解析成功,正在导入数据", reply_markup=ReplyKeyboardRemove())
|
2022-10-09 04:43:11 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
2022-10-08 10:56:40 +00:00
|
|
|
|
try:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
text = await self._refresh_user_data(user, player_id, data=data, verify_uid=file_type == "json")
|
2022-10-11 06:45:07 +00:00
|
|
|
|
except Exception as exc: # pylint: disable=W0703
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.error("文件解析失败 %s", repr(exc))
|
2024-01-16 11:33:14 +00:00
|
|
|
|
text = f"文件解析失败,请检查文件是否符合 UIGF {UIGF_VERSION} 标准"
|
2024-12-01 16:24:40 +00:00
|
|
|
|
self.add_delete_message_job(reply, delay=1)
|
|
|
|
|
await message.reply_text(text, reply_markup=ReplyKeyboardRemove())
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def can_gen_authkey(self, user_id: int, player_id: int) -> bool:
|
|
|
|
|
player_info = await self.players_service.get_player(user_id, region=RegionEnum.HYPERION, player_id=player_id)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
if player_info is not None:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
cookies = await self.cookie_service.get(user_id, account_id=player_info.account_id)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
if (
|
|
|
|
|
cookies is not None
|
|
|
|
|
and cookies.data
|
|
|
|
|
and "stoken" in cookies.data
|
|
|
|
|
and next((value for key, value in cookies.data.items() if key in ["ltuid", "login_uid"]), None)
|
|
|
|
|
):
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
2024-07-18 12:55:16 +00:00
|
|
|
|
async def gen_authkey(self, uid: int, player_id: int) -> Optional[str]:
|
|
|
|
|
player_info = await self.players_service.get_player(uid, region=RegionEnum.HYPERION, player_id=player_id)
|
2023-09-12 14:58:08 +00:00
|
|
|
|
if player_info is not None:
|
|
|
|
|
cookies = await self.cookie_service.get(uid, account_id=player_info.account_id)
|
|
|
|
|
if cookies is not None and cookies.data and "stoken" in cookies.data:
|
|
|
|
|
if stuid := next((value for key, value in cookies.data.items() if key in ["ltuid", "login_uid"]), None):
|
|
|
|
|
cookies.data["stuid"] = stuid
|
|
|
|
|
async with GenshinClient(
|
|
|
|
|
cookies=cookies.data, region=Region.CHINESE, lang="zh-cn", player_id=player_info.player_id
|
|
|
|
|
) as client:
|
|
|
|
|
return await client.get_authkey_by_stoken("webview_gacha")
|
|
|
|
|
|
2022-10-08 08:50:02 +00:00
|
|
|
|
@conversation.entry_point
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log_import", filters=filters.ChatType.PRIVATE, block=False)
|
2023-08-29 07:20:02 +00:00
|
|
|
|
@handler.command(command="gacha_log_import", filters=filters.ChatType.PRIVATE, block=False)
|
|
|
|
|
@handler.message(filters=filters.Regex("^导入抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False)
|
2023-12-24 13:53:05 +00:00
|
|
|
|
@handler.command(command="start", filters=filters.Regex("gacha_log_import$"), block=False)
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def command_start(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int:
|
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player_id = await self.get_player_id(user.id, uid, offset)
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data: WishLogPluginData = context.chat_data.get("wish_log_plugin_data")
|
|
|
|
|
if wish_log_plugin_data is None:
|
|
|
|
|
wish_log_plugin_data = WishLogPluginData()
|
|
|
|
|
context.chat_data["wish_log_plugin_data"] = wish_log_plugin_data
|
|
|
|
|
else:
|
|
|
|
|
wish_log_plugin_data.reset_data()
|
|
|
|
|
wish_log_plugin_data.player_id = player_id
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("用户 %s[%s] 导入抽卡记录命令请求", user.full_name, user.id)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
keyboard = None
|
2024-06-12 11:59:16 +00:00
|
|
|
|
if await self.can_gen_authkey(user.id, player_id):
|
2023-12-02 04:18:45 +00:00
|
|
|
|
keyboard = ReplyKeyboardMarkup([["自动导入"], ["退出"]], one_time_keyboard=True)
|
|
|
|
|
await message.reply_text(self.IMPORT_HINT, parse_mode="html", reply_markup=keyboard)
|
|
|
|
|
return INPUT_URL
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
|
|
|
|
@conversation.state(state=INPUT_URL)
|
2023-02-09 03:12:47 +00:00
|
|
|
|
@handler.message(filters=~filters.COMMAND, block=False)
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def import_data_from_message(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int:
|
2022-10-08 08:50:02 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data: WishLogPluginData = context.chat_data.get("wish_log_plugin_data")
|
|
|
|
|
player_id = wish_log_plugin_data.player_id
|
2022-10-08 10:56:40 +00:00
|
|
|
|
if message.document:
|
2024-12-01 09:30:08 +00:00
|
|
|
|
logger.info("用户 %s[%s] 从文件导入抽卡记录", user.full_name, user.id)
|
2024-06-12 11:59:16 +00:00
|
|
|
|
await self.import_from_file(user, player_id, message)
|
2022-10-08 10:56:40 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-04-25 11:52:16 +00:00
|
|
|
|
if not message.text:
|
|
|
|
|
await message.reply_text("请发送文件或链接")
|
|
|
|
|
return INPUT_URL
|
2023-12-02 04:18:45 +00:00
|
|
|
|
if message.text == "自动导入":
|
2024-07-18 12:55:16 +00:00
|
|
|
|
authkey = await self.gen_authkey(user.id, player_id)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
if not authkey:
|
2024-01-14 15:04:08 +00:00
|
|
|
|
await message.reply_text(
|
|
|
|
|
"自动生成 authkey 失败,请尝试通过其他方式导入。", reply_markup=ReplyKeyboardRemove()
|
2024-03-16 01:44:15 +00:00
|
|
|
|
)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
elif message.text == "退出":
|
2024-01-14 15:04:08 +00:00
|
|
|
|
await message.reply_text("取消导入抽卡记录", reply_markup=ReplyKeyboardRemove())
|
2023-12-02 04:18:45 +00:00
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
else:
|
|
|
|
|
authkey = from_url_get_authkey(message.text)
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data.authkey = authkey
|
|
|
|
|
keyboard = ReplyKeyboardMarkup([["快速导入(推荐)"], ["全量刷新"], ["退出"]], one_time_keyboard=True)
|
|
|
|
|
await message.reply_text("请选择导入方式", parse_mode="html", reply_markup=keyboard)
|
|
|
|
|
return INPUT_LAZY
|
|
|
|
|
|
|
|
|
|
@conversation.state(state=INPUT_LAZY)
|
|
|
|
|
@handler.message(filters=~filters.COMMAND, block=False)
|
|
|
|
|
async def get_lazy_from_message(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int:
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
|
|
|
|
wish_log_plugin_data: WishLogPluginData = context.chat_data.get("wish_log_plugin_data")
|
|
|
|
|
player_id = wish_log_plugin_data.player_id
|
|
|
|
|
authkey = wish_log_plugin_data.authkey
|
|
|
|
|
is_lazy = True
|
|
|
|
|
if message.text == "全量刷新":
|
|
|
|
|
is_lazy = False
|
|
|
|
|
elif message.text == "退出":
|
|
|
|
|
await message.reply_text("取消导入抽卡记录", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
logger.info("用户 %s[%s] 从 authkey 导入抽卡记录 is_lazy[%s]", user.full_name, user.id, is_lazy)
|
2024-06-07 15:22:30 +00:00
|
|
|
|
reply = await message.reply_text(WAITING, reply_markup=ReplyKeyboardRemove())
|
2022-10-11 04:00:55 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
2024-12-01 09:30:08 +00:00
|
|
|
|
text = await self._refresh_user_data(user, player_id, authkey=authkey, is_lazy=is_lazy)
|
2024-07-06 04:58:57 +00:00
|
|
|
|
self.add_delete_message_job(reply, delay=1)
|
|
|
|
|
await message.reply_text(text, reply_markup=ReplyKeyboardRemove())
|
2022-10-08 08:50:02 +00:00
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
|
2022-10-08 15:40:15 +00:00
|
|
|
|
@conversation.entry_point
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log_delete", filters=filters.ChatType.PRIVATE, block=False)
|
2023-08-29 07:20:02 +00:00
|
|
|
|
@handler.command(command="gacha_log_delete", filters=filters.ChatType.PRIVATE, block=False)
|
|
|
|
|
@handler.message(filters=filters.Regex("^删除抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_start_delete(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data: WishLogPluginData = context.chat_data.get("wish_log_plugin_data")
|
|
|
|
|
if wish_log_plugin_data is None:
|
|
|
|
|
wish_log_plugin_data = WishLogPluginData()
|
|
|
|
|
context.chat_data["wish_log_plugin_data"] = wish_log_plugin_data
|
|
|
|
|
else:
|
|
|
|
|
wish_log_plugin_data.reset_data()
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("用户 %s[%s] 删除抽卡记录命令请求", user.full_name, user.id)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
try:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player_id = await self.get_player_id(user.id, uid, offset)
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data.player_id = player_id
|
2023-03-14 01:27:22 +00:00
|
|
|
|
except PlayerNotFoundError:
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id)
|
2024-06-07 15:22:30 +00:00
|
|
|
|
await message.reply_text(config.notice.user_not_found)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-07-19 03:41:40 +00:00
|
|
|
|
_, status = await self.gacha_log.load_history_info(str(user.id), str(player_id), only_status=True)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
if not status:
|
|
|
|
|
await message.reply_text("你还没有导入抽卡记录哦~")
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
await message.reply_text(
|
|
|
|
|
"你确定要删除抽卡记录吗?(此项操作无法恢复),如果确定请发送 ”确定“,发送其他内容取消"
|
|
|
|
|
)
|
|
|
|
|
return CONFIRM_DELETE
|
|
|
|
|
|
|
|
|
|
@conversation.state(state=CONFIRM_DELETE)
|
|
|
|
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_confirm_delete(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> int:
|
2022-10-08 15:40:15 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2024-12-01 09:30:08 +00:00
|
|
|
|
wish_log_plugin_data: WishLogPluginData = context.chat_data.get("wish_log_plugin_data")
|
2022-10-08 15:40:15 +00:00
|
|
|
|
if message.text == "确定":
|
2024-12-01 09:30:08 +00:00
|
|
|
|
status = await self.gacha_log.remove_history_info(str(user.id), str(wish_log_plugin_data.player_id))
|
2022-10-08 15:40:15 +00:00
|
|
|
|
await message.reply_text("抽卡记录已删除" if status else "抽卡记录删除失败")
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
await message.reply_text("已取消")
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log_force_delete", block=False, admin=True)
|
2023-08-29 07:20:02 +00:00
|
|
|
|
@handler.command(command="gacha_log_force_delete", block=False, admin=True)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_gacha_log_force_delete(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE"):
|
2024-06-12 11:59:16 +00:00
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
message = update.effective_message
|
2023-07-18 09:29:31 +00:00
|
|
|
|
user = update.effective_user
|
2023-07-19 03:41:40 +00:00
|
|
|
|
logger.info("用户 %s[%s] 强制删除抽卡记录命令请求", user.full_name, user.id)
|
2023-03-14 01:27:22 +00:00
|
|
|
|
args = self.get_args(context)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
if not args:
|
|
|
|
|
await message.reply_text("请指定用户ID")
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
cid = int(args[0])
|
|
|
|
|
if cid < 0:
|
|
|
|
|
raise ValueError("Invalid cid")
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player_id = await self.get_player_id(cid, uid, offset)
|
2023-07-19 03:41:40 +00:00
|
|
|
|
_, status = await self.gacha_log.load_history_info(str(cid), str(player_id), only_status=True)
|
2022-10-08 15:40:15 +00:00
|
|
|
|
if not status:
|
|
|
|
|
await message.reply_text("该用户还没有导入抽卡记录")
|
|
|
|
|
return
|
2023-07-19 03:41:40 +00:00
|
|
|
|
status = await self.gacha_log.remove_history_info(str(cid), str(player_id))
|
2022-10-08 15:40:15 +00:00
|
|
|
|
await message.reply_text("抽卡记录已强制删除" if status else "抽卡记录删除失败")
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogNotFound:
|
2022-10-22 13:54:04 +00:00
|
|
|
|
await message.reply_text("该用户还没有导入抽卡记录")
|
2023-03-14 01:27:22 +00:00
|
|
|
|
except PlayerNotFoundError:
|
2022-10-08 15:40:15 +00:00
|
|
|
|
await message.reply_text("该用户暂未绑定账号")
|
|
|
|
|
except (ValueError, IndexError):
|
|
|
|
|
await message.reply_text("用户ID 不合法")
|
|
|
|
|
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log_export", filters=filters.ChatType.PRIVATE, block=False)
|
2023-08-29 07:20:02 +00:00
|
|
|
|
@handler.command(command="gacha_log_export", filters=filters.ChatType.PRIVATE, block=False)
|
|
|
|
|
@handler.message(filters=filters.Regex("^导出抽卡记录(.*)") & filters.ChatType.PRIVATE, block=False)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_start_export(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("用户 %s[%s] 导出抽卡记录命令请求", user.full_name, user.id)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
try:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player_id = await self.get_player_id(user.id, uid, offset)
|
2022-10-08 10:56:40 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
2023-07-19 03:41:40 +00:00
|
|
|
|
path = await self.gacha_log.gacha_log_to_uigf(str(user.id), str(player_id))
|
2022-10-21 11:34:49 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT)
|
2024-03-13 07:38:49 +00:00
|
|
|
|
await message.reply_document(document=open(path, "rb+"), caption=f"抽卡记录导出文件 - UIGF {UIGF_VERSION}")
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogNotFound:
|
2023-01-06 11:23:32 +00:00
|
|
|
|
logger.info("未找到用户 %s[%s] 的抽卡记录", user.full_name, user.id)
|
2022-10-22 13:54:04 +00:00
|
|
|
|
buttons = [
|
2022-11-28 08:38:49 +00:00
|
|
|
|
[InlineKeyboardButton("点我导入", url=create_deep_linked_url(context.bot.username, "gacha_log_import"))]
|
2022-10-22 13:54:04 +00:00
|
|
|
|
]
|
2024-06-07 15:22:30 +00:00
|
|
|
|
await message.reply_text(WISHLOG_NOT_FOUND, reply_markup=InlineKeyboardMarkup(buttons))
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogAccountNotFound:
|
|
|
|
|
await message.reply_text("导入失败,可能文件包含的祈愿记录所属 uid 与你当前绑定的 uid 不同")
|
|
|
|
|
except GachaLogFileError:
|
|
|
|
|
await message.reply_text("导入失败,数据格式错误")
|
2023-03-14 01:27:22 +00:00
|
|
|
|
except PlayerNotFoundError:
|
2022-12-22 15:50:37 +00:00
|
|
|
|
logger.info("未查询到用户 %s[%s] 所绑定的账号信息", user.full_name, user.id)
|
2024-06-07 15:22:30 +00:00
|
|
|
|
await message.reply_text(config.notice.user_not_found)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log_url", filters=filters.ChatType.PRIVATE, block=False)
|
2023-09-12 14:58:08 +00:00
|
|
|
|
@handler.command(command="gacha_log_url", filters=filters.ChatType.PRIVATE, block=False)
|
|
|
|
|
@handler.message(filters=filters.Regex("^抽卡记录链接(.*)") & filters.ChatType.PRIVATE, block=False)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_start_url(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None:
|
2024-07-18 12:55:16 +00:00
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2023-09-12 14:58:08 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
user = update.effective_user
|
2024-07-18 12:55:16 +00:00
|
|
|
|
player_id = await self.get_player_id(user.id, uid, offset)
|
|
|
|
|
logger.info("用户 %s[%s] 生成抽卡记录链接命令请求 player_id[%s]", user.full_name, user.id, player_id)
|
|
|
|
|
authkey = await self.gen_authkey(user.id, player_id)
|
2023-09-12 14:58:08 +00:00
|
|
|
|
if not authkey:
|
|
|
|
|
await message.reply_text("生成失败,仅国服且绑定 stoken 的用户才能生成抽卡记录链接")
|
|
|
|
|
else:
|
2024-12-01 13:55:44 +00:00
|
|
|
|
url = str(GACHA_INFO_URL.get_url(Region.CHINESE, Game.GENSHIN) / "getGachaLog")
|
2023-09-12 14:58:08 +00:00
|
|
|
|
params = {
|
|
|
|
|
"authkey_ver": 1,
|
|
|
|
|
"lang": "zh-cn",
|
|
|
|
|
"gacha_type": 301,
|
|
|
|
|
"authkey": authkey,
|
|
|
|
|
}
|
|
|
|
|
await message.reply_text(f"{url}?{urlencode(params)}", disable_web_page_preview=True)
|
|
|
|
|
|
2024-03-13 07:38:49 +00:00
|
|
|
|
async def rander_wish_log_analysis(
|
|
|
|
|
self, user_id: int, player_id: int, pool_type: BannerType
|
|
|
|
|
) -> Union[str, "RenderResult"]:
|
|
|
|
|
data = await self.gacha_log.get_analysis(user_id, player_id, pool_type, self.assets_service)
|
|
|
|
|
if isinstance(data, str):
|
|
|
|
|
return data
|
|
|
|
|
name_card = await self.player_info.get_name_card(player_id, user_id)
|
|
|
|
|
data["name_card"] = name_card
|
|
|
|
|
png_data = await self.template_service.render(
|
|
|
|
|
"genshin/wish_log/wish_log.jinja2",
|
|
|
|
|
data,
|
|
|
|
|
full_page=True,
|
|
|
|
|
file_type=FileType.DOCUMENT if len(data.get("fiveLog")) > 300 else FileType.PHOTO,
|
|
|
|
|
query_selector=".body_box",
|
|
|
|
|
)
|
|
|
|
|
return png_data
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def gen_button(user_id: int, uid: int, info: "GachaLogInfo") -> List[List[InlineKeyboardButton]]:
|
|
|
|
|
buttons = []
|
|
|
|
|
pools = []
|
2024-03-13 13:17:41 +00:00
|
|
|
|
skip_pools = []
|
2024-03-13 07:38:49 +00:00
|
|
|
|
for k, v in info.item_list.items():
|
|
|
|
|
if k in skip_pools:
|
|
|
|
|
continue
|
|
|
|
|
if not v:
|
|
|
|
|
continue
|
|
|
|
|
pools.append(k)
|
|
|
|
|
# 2 个一组
|
|
|
|
|
for i in range(0, len(pools), 2):
|
|
|
|
|
row = []
|
|
|
|
|
for pool in pools[i : i + 2]:
|
2024-03-13 10:14:03 +00:00
|
|
|
|
for k, v in {"log": "", "count": "(按卡池)"}.items():
|
|
|
|
|
row.append(
|
|
|
|
|
InlineKeyboardButton(
|
|
|
|
|
f"{pool.replace('祈愿', '')}{v}",
|
|
|
|
|
callback_data=f"get_wish_log|{user_id}|{uid}|{k}|{pool}",
|
|
|
|
|
)
|
2024-03-13 07:38:49 +00:00
|
|
|
|
)
|
|
|
|
|
buttons.append(row)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
buttons.append([InlineKeyboardButton("五星抽卡统计", callback_data=f"get_wish_log|{user_id}|{uid}|count|five")])
|
2024-03-13 07:38:49 +00:00
|
|
|
|
return buttons
|
|
|
|
|
|
2024-06-12 11:59:16 +00:00
|
|
|
|
async def wish_log_pool_choose(self, user_id: int, player_id: int, message: "Message"):
|
2024-03-13 07:38:49 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
|
|
|
|
gacha_log, status = await self.gacha_log.load_history_info(str(user_id), str(player_id))
|
|
|
|
|
if not status:
|
|
|
|
|
raise GachaLogNotFound
|
|
|
|
|
buttons = self.gen_button(user_id, player_id, gacha_log)
|
|
|
|
|
if isinstance(self.wish_photo, str):
|
|
|
|
|
photo = self.wish_photo
|
|
|
|
|
else:
|
|
|
|
|
photo = open("resources/img/wish.jpg", "rb")
|
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
|
|
|
|
reply_message = await message.reply_photo(
|
|
|
|
|
photo=photo,
|
|
|
|
|
caption="请选择你要查询的卡池",
|
|
|
|
|
reply_markup=InlineKeyboardMarkup(buttons),
|
|
|
|
|
)
|
|
|
|
|
if reply_message.photo:
|
|
|
|
|
self.wish_photo = reply_message.photo[-1].file_id
|
|
|
|
|
|
2024-09-08 14:45:03 +00:00
|
|
|
|
async def wish_log_pool_send(
|
|
|
|
|
self, user_id: int, uid: int, pool_type: "BannerType", message: "Message", bot_username: str
|
|
|
|
|
):
|
2024-03-13 07:38:49 +00:00
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
|
|
|
|
png_data = await self.rander_wish_log_analysis(user_id, uid, pool_type)
|
|
|
|
|
if isinstance(png_data, str):
|
|
|
|
|
reply = await message.reply_text(png_data)
|
2024-03-28 14:05:57 +00:00
|
|
|
|
if filters.ChatType.GROUPS.filter(message):
|
|
|
|
|
self.add_delete_message_job(reply)
|
|
|
|
|
self.add_delete_message_job(message)
|
2024-03-13 07:38:49 +00:00
|
|
|
|
else:
|
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
if png_data.file_type == FileType.DOCUMENT:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png_data.reply_document(
|
|
|
|
|
message, filename="抽卡统计.png", reply_markup=self.gacha_log.get_web_upload_button(bot_username)
|
|
|
|
|
)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
else:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png_data.reply_photo(message, reply_markup=self.gacha_log.get_web_upload_button(bot_username))
|
2024-03-13 07:38:49 +00:00
|
|
|
|
|
2023-10-12 01:12:06 +00:00
|
|
|
|
@handler.command(command="wish_log", block=False)
|
2023-08-29 07:20:02 +00:00
|
|
|
|
@handler.command(command="gacha_log", block=False)
|
|
|
|
|
@handler.message(filters=filters.Regex("^抽卡记录?(武器|角色|常驻|)$"), block=False)
|
2023-12-02 04:18:45 +00:00
|
|
|
|
async def command_start_analysis(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
|
2024-03-10 12:40:26 +00:00
|
|
|
|
user_id = await self.get_real_user_id(update)
|
2024-06-12 11:59:16 +00:00
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
message = update.effective_message
|
2024-03-13 07:38:49 +00:00
|
|
|
|
pool_type = None
|
2023-03-14 01:27:22 +00:00
|
|
|
|
if args := self.get_args(context):
|
2024-03-13 07:38:49 +00:00
|
|
|
|
if "角色" in args:
|
|
|
|
|
pool_type = BannerType.CHARACTER1
|
|
|
|
|
elif "武器" in args:
|
2023-07-18 09:29:31 +00:00
|
|
|
|
pool_type = BannerType.WEAPON
|
2022-10-08 08:50:02 +00:00
|
|
|
|
elif "常驻" in args:
|
2023-07-18 09:29:31 +00:00
|
|
|
|
pool_type = BannerType.STANDARD
|
2024-03-13 07:38:49 +00:00
|
|
|
|
elif "集录" in args:
|
|
|
|
|
pool_type = BannerType.CHRONICLED
|
|
|
|
|
self.log_user(update, logger.info, "抽卡记录命令请求 || 参数 %s", pool_type.name if pool_type else None)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
try:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
player_id = await self.get_player_id(user_id, uid, offset)
|
2024-03-13 07:38:49 +00:00
|
|
|
|
if pool_type is None:
|
2024-06-12 11:59:16 +00:00
|
|
|
|
await self.wish_log_pool_choose(user_id, player_id, message)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
else:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await self.wish_log_pool_send(user_id, player_id, pool_type, message, context.bot.username)
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogNotFound:
|
2024-03-10 12:40:26 +00:00
|
|
|
|
self.log_user(update, logger.info, "未找到抽卡记录")
|
2022-10-22 13:54:04 +00:00
|
|
|
|
buttons = [
|
2022-11-28 08:38:49 +00:00
|
|
|
|
[InlineKeyboardButton("点我导入", url=create_deep_linked_url(context.bot.username, "gacha_log_import"))]
|
2022-10-22 13:54:04 +00:00
|
|
|
|
]
|
2024-06-07 15:22:30 +00:00
|
|
|
|
await message.reply_text(WISHLOG_NOT_FOUND, reply_markup=InlineKeyboardMarkup(buttons))
|
2022-10-08 08:50:02 +00:00
|
|
|
|
|
2024-03-13 07:38:49 +00:00
|
|
|
|
@handler.callback_query(pattern=r"^get_wish_log\|", block=False)
|
2024-09-08 14:45:03 +00:00
|
|
|
|
async def get_wish_log(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
|
2024-03-13 07:38:49 +00:00
|
|
|
|
callback_query = update.callback_query
|
|
|
|
|
user = callback_query.from_user
|
|
|
|
|
message = callback_query.message
|
|
|
|
|
|
|
|
|
|
async def get_wish_log_callback(
|
|
|
|
|
callback_query_data: str,
|
2024-03-13 10:14:03 +00:00
|
|
|
|
) -> Tuple[str, str, int, int]:
|
2024-03-13 07:38:49 +00:00
|
|
|
|
_data = callback_query_data.split("|")
|
|
|
|
|
_user_id = int(_data[1])
|
|
|
|
|
_uid = int(_data[2])
|
2024-03-13 10:14:03 +00:00
|
|
|
|
_t = _data[3]
|
|
|
|
|
_result = _data[4]
|
2024-03-13 07:38:49 +00:00
|
|
|
|
logger.debug(
|
2024-03-13 10:14:03 +00:00
|
|
|
|
"callback_query_data函数返回 result[%s] user_id[%s] uid[%s] show_type[%s]",
|
2024-03-13 07:38:49 +00:00
|
|
|
|
_result,
|
|
|
|
|
_user_id,
|
|
|
|
|
_uid,
|
2024-03-13 10:14:03 +00:00
|
|
|
|
_t,
|
2024-03-13 07:38:49 +00:00
|
|
|
|
)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
return _result, _t, _user_id, _uid
|
2024-03-13 07:38:49 +00:00
|
|
|
|
|
2024-03-13 10:14:03 +00:00
|
|
|
|
try:
|
|
|
|
|
pool, show_type, user_id, uid = await get_wish_log_callback(callback_query.data)
|
|
|
|
|
except IndexError:
|
|
|
|
|
await callback_query.answer("按钮数据已过期,请重新获取。", show_alert=True)
|
|
|
|
|
self.add_delete_message_job(message, delay=1)
|
|
|
|
|
return
|
2024-03-13 07:38:49 +00:00
|
|
|
|
if user.id != user_id:
|
|
|
|
|
await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True)
|
|
|
|
|
return
|
2024-03-13 10:14:03 +00:00
|
|
|
|
if show_type == "count":
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await self.get_wish_log_count(update, context, user_id, uid, pool)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
else:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await self.get_wish_log_log(update, context, user_id, uid, pool)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
|
2024-09-08 14:45:03 +00:00
|
|
|
|
async def get_wish_log_log(
|
|
|
|
|
self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", user_id: int, uid: int, pool: str
|
|
|
|
|
):
|
2024-03-13 10:14:03 +00:00
|
|
|
|
callback_query = update.callback_query
|
|
|
|
|
message = callback_query.message
|
|
|
|
|
|
2024-03-13 07:38:49 +00:00
|
|
|
|
pool_type = GACHA_TYPE_LIST_REVERSE.get(pool)
|
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
|
|
|
|
try:
|
|
|
|
|
png_data = await self.rander_wish_log_analysis(user_id, uid, pool_type)
|
|
|
|
|
except GachaLogNotFound:
|
|
|
|
|
png_data = "未找到抽卡记录"
|
|
|
|
|
if isinstance(png_data, str):
|
|
|
|
|
await callback_query.answer(png_data, show_alert=True)
|
|
|
|
|
self.add_delete_message_job(message, delay=1)
|
|
|
|
|
else:
|
|
|
|
|
await callback_query.answer(text="正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False)
|
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
if png_data.file_type == FileType.DOCUMENT:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png_data.reply_document(
|
|
|
|
|
message,
|
|
|
|
|
filename="抽卡统计.png",
|
|
|
|
|
reply_markup=self.gacha_log.get_web_upload_button(context.bot.username),
|
|
|
|
|
)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
self.add_delete_message_job(message, delay=1)
|
|
|
|
|
else:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png_data.edit_media(
|
|
|
|
|
message, reply_markup=self.gacha_log.get_web_upload_button(context.bot.username)
|
|
|
|
|
)
|
2024-03-13 07:38:49 +00:00
|
|
|
|
|
2024-09-08 14:45:03 +00:00
|
|
|
|
async def get_wish_log_count(
|
|
|
|
|
self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", user_id: int, uid: int, pool: str
|
|
|
|
|
):
|
2024-03-13 10:14:03 +00:00
|
|
|
|
callback_query = update.callback_query
|
|
|
|
|
message = callback_query.message
|
|
|
|
|
|
|
|
|
|
all_five = pool == "five"
|
|
|
|
|
group = filters.ChatType.GROUPS.filter(message)
|
|
|
|
|
pool_type = GACHA_TYPE_LIST_REVERSE.get(pool)
|
|
|
|
|
await message.reply_chat_action(ChatAction.TYPING)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
try:
|
2022-10-29 10:29:20 +00:00
|
|
|
|
if all_five:
|
2024-03-13 10:14:03 +00:00
|
|
|
|
png_data = await self.gacha_log.get_all_five_analysis(user_id, uid, self.assets_service)
|
2022-10-08 08:50:02 +00:00
|
|
|
|
else:
|
2024-03-13 10:14:03 +00:00
|
|
|
|
png_data = await self.gacha_log.get_pool_analysis(user_id, uid, pool_type, self.assets_service, group)
|
2022-10-21 11:34:49 +00:00
|
|
|
|
except GachaLogNotFound:
|
2024-03-13 10:14:03 +00:00
|
|
|
|
png_data = "未找到抽卡记录"
|
|
|
|
|
if isinstance(png_data, str):
|
|
|
|
|
await callback_query.answer(png_data, show_alert=True)
|
|
|
|
|
self.add_delete_message_job(message, delay=1)
|
|
|
|
|
else:
|
|
|
|
|
await callback_query.answer(text="正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False)
|
|
|
|
|
name_card = await self.player_info.get_name_card(uid, user_id)
|
|
|
|
|
document = False
|
|
|
|
|
if png_data["hasMore"] and not group:
|
|
|
|
|
document = True
|
|
|
|
|
png_data["hasMore"] = False
|
|
|
|
|
png_data["name_card"] = name_card
|
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_DOCUMENT if document else ChatAction.UPLOAD_PHOTO)
|
|
|
|
|
png = await self.template_service.render(
|
|
|
|
|
"genshin/wish_count/wish_count.jinja2",
|
|
|
|
|
png_data,
|
|
|
|
|
full_page=True,
|
|
|
|
|
query_selector=".body_box",
|
|
|
|
|
file_type=FileType.DOCUMENT if document else FileType.PHOTO,
|
|
|
|
|
)
|
|
|
|
|
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
|
|
|
|
if document:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png.reply_document(
|
|
|
|
|
message,
|
|
|
|
|
filename="抽卡统计.png",
|
|
|
|
|
reply_markup=self.gacha_log.get_web_upload_button(context.bot.username),
|
|
|
|
|
)
|
2024-03-13 10:14:03 +00:00
|
|
|
|
self.add_delete_message_job(message, delay=1)
|
|
|
|
|
else:
|
2024-09-08 14:45:03 +00:00
|
|
|
|
await png.edit_media(message, reply_markup=self.gacha_log.get_web_upload_button(context.bot.username))
|
|
|
|
|
|
|
|
|
|
@handler.command(command="wish_log_online_view", block=False)
|
|
|
|
|
@handler.command(command="gacha_log_online_view", block=False)
|
|
|
|
|
@handler.command(command="start", filters=filters.Regex(r"gacha_log_online_view$"), block=False)
|
|
|
|
|
async def command_start_upload_web(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE") -> None:
|
|
|
|
|
user_id = await self.get_real_user_id(update)
|
|
|
|
|
uid, offset = self.get_real_uid_or_offset(update)
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
self.log_user(update, logger.info, "抽卡记录在线浏览命令请求")
|
|
|
|
|
try:
|
|
|
|
|
player_id = await self.get_player_id(user_id, uid, offset)
|
|
|
|
|
url = await self.gacha_log.web_upload(user_id, str(player_id))
|
|
|
|
|
await message.reply_text(
|
|
|
|
|
WISHLOG_WEB,
|
|
|
|
|
parse_mode="html",
|
|
|
|
|
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("点我查看", url=url)]]),
|
|
|
|
|
)
|
|
|
|
|
except GachaLogNotFound:
|
|
|
|
|
self.log_user(update, logger.info, "未找到抽卡记录")
|
|
|
|
|
buttons = [
|
|
|
|
|
[InlineKeyboardButton("点我导入", url=create_deep_linked_url(context.bot.username, "gacha_log_import"))]
|
|
|
|
|
]
|
|
|
|
|
await message.reply_text(WISHLOG_NOT_FOUND, reply_markup=InlineKeyboardMarkup(buttons))
|
|
|
|
|
except GachaLogWebError as e:
|
|
|
|
|
logger.error("申请在线查看抽卡记录失败", exc_info=e)
|
|
|
|
|
await message.reply_text("申请在线查看抽卡记录失败,请联系管理员")
|
2023-12-16 10:01:27 +00:00
|
|
|
|
|
2024-09-12 13:13:05 +00:00
|
|
|
|
@handler.command(command="wish_log_rank_recount", block=False, admin=True)
|
|
|
|
|
async def wish_log_rank_recount(self, update: "Update", _: "ContextTypes.DEFAULT_TYPE") -> None:
|
|
|
|
|
user = update.effective_user
|
|
|
|
|
logger.info("用户 %s[%s] wish_log_rank_recount 命令请求", user.full_name, user.id)
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
reply = await message.reply_text("正在重新统计抽卡记录排行榜")
|
|
|
|
|
await self.gacha_log.recount_all_data(reply)
|
|
|
|
|
await reply.edit_text("重新统计完成")
|
|
|
|
|
|
2023-12-16 10:01:27 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
async def get_migrate_data(
|
|
|
|
|
old_user_id: int, new_user_id: int, old_players: List["Player"]
|
|
|
|
|
) -> Optional[GachaLogMigrate]:
|
|
|
|
|
return await GachaLogMigrate.create(old_user_id, new_user_id, old_players)
|
2024-06-19 08:29:47 +00:00
|
|
|
|
|
|
|
|
|
async def wish_log_use_by_inline(
|
|
|
|
|
self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", pool_type: "BannerType"
|
|
|
|
|
):
|
|
|
|
|
callback_query = update.callback_query
|
|
|
|
|
user = update.effective_user
|
|
|
|
|
user_id = user.id
|
|
|
|
|
uid = IInlineUseData.get_uid_from_context(context)
|
|
|
|
|
|
|
|
|
|
self.log_user(update, logger.info, "抽卡记录命令请求 || 参数 %s", pool_type.name if pool_type else None)
|
|
|
|
|
notice = None
|
|
|
|
|
try:
|
|
|
|
|
render_result = await self.rander_wish_log_analysis(user_id, uid, pool_type)
|
|
|
|
|
if isinstance(render_result, str):
|
|
|
|
|
notice = render_result
|
|
|
|
|
else:
|
|
|
|
|
await render_result.edit_inline_media(callback_query, filename="抽卡统计.png")
|
|
|
|
|
except GachaLogNotFound:
|
|
|
|
|
self.log_user(update, logger.info, "未找到抽卡记录")
|
|
|
|
|
notice = "未找到抽卡记录"
|
|
|
|
|
if notice:
|
|
|
|
|
await callback_query.answer(notice, show_alert=True)
|
|
|
|
|
|
|
|
|
|
async def get_inline_use_data(self) -> List[Optional[IInlineUseData]]:
|
|
|
|
|
types = {
|
|
|
|
|
"角色": BannerType.CHARACTER1,
|
|
|
|
|
"武器": BannerType.WEAPON,
|
|
|
|
|
"常驻": BannerType.STANDARD,
|
|
|
|
|
"集录": BannerType.CHRONICLED,
|
|
|
|
|
}
|
|
|
|
|
data = []
|
|
|
|
|
for k, v in types.items():
|
|
|
|
|
data.append(
|
|
|
|
|
IInlineUseData(
|
|
|
|
|
text=f"{k}祈愿",
|
|
|
|
|
hash=f"wish_log_{v.value}",
|
|
|
|
|
callback=partial(self.wish_log_use_by_inline, pool_type=v),
|
|
|
|
|
player=True,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return data
|