2024-07-30 09:44:44 +00:00
|
|
|
|
import contextlib
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from datetime import datetime
|
2024-07-30 09:44:44 +00:00
|
|
|
|
from typing import Dict, Optional, List
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2022-12-08 14:22:59 +00:00
|
|
|
|
from arkowrapper import ArkoWrapper
|
2024-12-09 10:21:07 +00:00
|
|
|
|
from simnet import ZZZClient, Game, Region
|
2023-07-18 09:29:31 +00:00
|
|
|
|
from simnet.errors import DataNotPublic, InvalidCookies, BadRequest as SimnetBadRequest
|
|
|
|
|
from simnet.models.lab.record import Account
|
2024-07-30 09:44:44 +00:00
|
|
|
|
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, TelegramObject, Update, Message
|
2022-12-01 11:54:40 +00:00
|
|
|
|
from telegram.ext import CallbackContext, ConversationHandler, filters
|
2022-08-05 13:23:04 +00:00
|
|
|
|
from telegram.helpers import escape_markdown
|
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from core.basemodel import RegionEnum
|
2022-12-01 11:54:40 +00:00
|
|
|
|
from core.plugin import Plugin, conversation, handler
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from core.services.cookies.models import CookiesDataBase as Cookies, CookiesStatusEnum
|
|
|
|
|
from core.services.cookies.services import CookiesService
|
|
|
|
|
from core.services.players.models import PlayersDataBase as Player, PlayerInfoSQLModel
|
|
|
|
|
from core.services.players.services import PlayersService, PlayerInfoService
|
2023-10-02 09:51:03 +00:00
|
|
|
|
from gram_core.services.devices import DevicesService
|
|
|
|
|
from gram_core.services.devices.models import DevicesDataBase as Devices
|
2023-02-22 04:47:44 +00:00
|
|
|
|
from modules.apihelper.models.genshin.cookies import CookiesModel
|
2024-05-31 02:02:44 +00:00
|
|
|
|
from modules.apihelper.utility.devices import devices_methods
|
2022-09-08 01:08:37 +00:00
|
|
|
|
from utils.log import logger
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
__all__ = ("AccountCookiesPlugin",)
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
|
|
class AccountIdNotFound(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
2023-10-02 09:51:03 +00:00
|
|
|
|
class AccountCookiesPluginDeviceData(TelegramObject):
|
|
|
|
|
device_id: str = ""
|
|
|
|
|
device_fp: str = ""
|
|
|
|
|
device_name: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
class AccountCookiesPluginData(TelegramObject):
|
2022-09-09 11:30:02 +00:00
|
|
|
|
region: RegionEnum = RegionEnum.NULL
|
2022-08-05 13:23:04 +00:00
|
|
|
|
cookies: dict = {}
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_id: int = 0
|
|
|
|
|
# player_id: int = 0
|
2023-07-18 09:29:31 +00:00
|
|
|
|
genshin_account: Optional[Account] = None
|
2024-07-30 09:44:44 +00:00
|
|
|
|
genshin_accounts: List[Account] = []
|
2023-10-02 09:51:03 +00:00
|
|
|
|
device: Optional[AccountCookiesPluginDeviceData] = None
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
|
self.region = RegionEnum.NULL
|
|
|
|
|
self.cookies = {}
|
|
|
|
|
self.account_id = 0
|
|
|
|
|
self.genshin_account = None
|
2024-07-30 09:44:44 +00:00
|
|
|
|
self.genshin_accounts = []
|
2023-10-02 09:51:03 +00:00
|
|
|
|
self.device = None
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
|
|
|
|
|
2024-07-30 09:44:44 +00:00
|
|
|
|
CHECK_SERVER, INPUT_COOKIES, INPUT_PLAYERS, COMMAND_RESULT = range(10100, 10104)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
class AccountCookiesPlugin(Plugin.Conversation):
|
2022-09-08 01:49:44 +00:00
|
|
|
|
"""Cookie绑定"""
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
def __init__(
|
|
|
|
|
self,
|
|
|
|
|
players_service: PlayersService = None,
|
|
|
|
|
cookies_service: CookiesService = None,
|
|
|
|
|
player_info_service: PlayerInfoService = None,
|
2023-10-02 09:51:03 +00:00
|
|
|
|
devices_service: DevicesService = None,
|
2023-03-14 01:27:22 +00:00
|
|
|
|
):
|
2022-08-05 13:23:04 +00:00
|
|
|
|
self.cookies_service = cookies_service
|
2023-03-14 01:27:22 +00:00
|
|
|
|
self.players_service = players_service
|
|
|
|
|
self.player_info_service = player_info_service
|
2023-10-02 09:51:03 +00:00
|
|
|
|
self.devices_service = devices_service
|
2024-05-31 02:02:44 +00:00
|
|
|
|
devices_methods.service = devices_service
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2022-12-08 14:22:59 +00:00
|
|
|
|
# noinspection SpellCheckingInspection
|
2022-11-27 10:42:49 +00:00
|
|
|
|
@staticmethod
|
2022-12-08 14:22:59 +00:00
|
|
|
|
def parse_cookie(cookie: Dict[str, str]) -> Dict[str, str]:
|
2022-11-27 10:42:49 +00:00
|
|
|
|
cookies = {}
|
2022-12-08 14:22:59 +00:00
|
|
|
|
|
2023-08-16 15:00:44 +00:00
|
|
|
|
v1_keys = [
|
|
|
|
|
"ltoken",
|
|
|
|
|
"ltuid",
|
|
|
|
|
"account_id",
|
|
|
|
|
"cookie_token",
|
|
|
|
|
"stoken",
|
|
|
|
|
"stuid",
|
|
|
|
|
"login_uid",
|
|
|
|
|
"login_ticket",
|
|
|
|
|
"mid",
|
|
|
|
|
]
|
2023-02-21 14:34:53 +00:00
|
|
|
|
v2_keys = ["ltoken_v2", "ltmid_v2", "ltuid_v2", "account_mid_v2", "cookie_token_v2", "account_id_v2"]
|
2024-12-09 10:21:07 +00:00
|
|
|
|
combo_token_keys = []
|
|
|
|
|
for g in Game:
|
|
|
|
|
g: "Game"
|
|
|
|
|
for r in Region:
|
|
|
|
|
r: "Region"
|
|
|
|
|
combo_token_keys.append(f"cg_combo_token_{g.value}_{r.value}")
|
|
|
|
|
|
|
|
|
|
for k in v1_keys + v2_keys + combo_token_keys:
|
2022-12-08 14:22:59 +00:00
|
|
|
|
cookies[k] = cookie.get(k)
|
|
|
|
|
|
|
|
|
|
return {k: v for k, v in cookies.items() if v is not None}
|
2022-11-27 10:42:49 +00:00
|
|
|
|
|
2023-10-02 09:51:03 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def parse_headers(headers: Dict[str, str]) -> AccountCookiesPluginDeviceData:
|
|
|
|
|
data = AccountCookiesPluginDeviceData()
|
|
|
|
|
must_keys = {"x-rpc-device_id": 36, "x-rpc-device_fp": 13}
|
|
|
|
|
optional_keys = ["x-rpc-device_name"]
|
|
|
|
|
for k, v in must_keys.items():
|
|
|
|
|
if (k not in headers) or (not headers.get(k)):
|
|
|
|
|
raise ValueError
|
|
|
|
|
if len(headers.get(k)) != v:
|
|
|
|
|
raise ValueError
|
|
|
|
|
for k in optional_keys:
|
|
|
|
|
if k not in headers:
|
|
|
|
|
continue
|
|
|
|
|
if headers.get(k) and len(headers.get(k)) > 64:
|
|
|
|
|
raise ValueError
|
|
|
|
|
data.device_id = headers.get("x-rpc-device_id")
|
|
|
|
|
data.device_fp = headers.get("x-rpc-device_fp")
|
|
|
|
|
data.device_name = headers.get("x-rpc-device_name")
|
|
|
|
|
return data
|
|
|
|
|
|
2023-12-18 16:51:36 +00:00
|
|
|
|
async def _parse_args(self, update: Update, context: CallbackContext) -> Optional[int]:
|
|
|
|
|
args = self.get_args(context)
|
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
|
|
|
|
if len(args) < 2:
|
|
|
|
|
return None
|
|
|
|
|
regions = {"米游社": RegionEnum.HYPERION, "HoYoLab": RegionEnum.HOYOLAB}
|
|
|
|
|
if args[0] not in regions:
|
|
|
|
|
return None
|
|
|
|
|
cookies = " ".join(args[1:])
|
|
|
|
|
account_cookies_plugin_data.region = regions[args[0]]
|
|
|
|
|
if ret := await self.parse_cookies(update, context, cookies):
|
|
|
|
|
return ret
|
|
|
|
|
return await self.check_cookies(update, context)
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
@conversation.entry_point
|
2023-03-15 12:36:57 +00:00
|
|
|
|
@handler.command(command="setcookie", filters=filters.ChatType.PRIVATE, block=False)
|
|
|
|
|
@handler.command(command="setcookies", filters=filters.ChatType.PRIVATE, block=False)
|
2023-12-24 13:26:36 +00:00
|
|
|
|
@handler.command(command="start", filters=filters.Regex("set_cookie$"), block=False)
|
2022-08-05 13:23:04 +00:00
|
|
|
|
async def command_start(self, update: Update, context: CallbackContext) -> int:
|
|
|
|
|
user = update.effective_user
|
2022-09-08 01:08:37 +00:00
|
|
|
|
message = update.effective_message
|
2022-12-25 13:26:08 +00:00
|
|
|
|
logger.info("用户 %s[%s] 绑定账号命令请求", user.full_name, user.id)
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
|
|
|
|
if account_cookies_plugin_data is None:
|
|
|
|
|
account_cookies_plugin_data = AccountCookiesPluginData()
|
|
|
|
|
context.chat_data["account_cookies_plugin_data"] = account_cookies_plugin_data
|
|
|
|
|
else:
|
|
|
|
|
account_cookies_plugin_data.reset()
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2023-12-18 16:51:36 +00:00
|
|
|
|
if ret := await self._parse_args(update, context):
|
|
|
|
|
return ret
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
text = f'你好 {user.mention_markdown_v2()} {escape_markdown("!请选择要绑定的服务器!或回复退出取消操作")}'
|
2022-08-05 13:23:04 +00:00
|
|
|
|
reply_keyboard = [["米游社", "HoYoLab"], ["退出"]]
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
|
|
|
|
|
return CHECK_SERVER
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
@conversation.state(state=CHECK_SERVER)
|
2023-03-15 12:36:57 +00:00
|
|
|
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
2022-08-05 13:23:04 +00:00
|
|
|
|
async def check_server(self, update: Update, context: CallbackContext) -> int:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
message = update.effective_message
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
2022-09-08 01:08:37 +00:00
|
|
|
|
if message.text == "退出":
|
|
|
|
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-03-14 01:27:22 +00:00
|
|
|
|
if message.text == "米游社":
|
2022-09-08 01:08:37 +00:00
|
|
|
|
region = RegionEnum.HYPERION
|
2022-08-05 13:23:04 +00:00
|
|
|
|
bbs_name = "米游社"
|
2022-09-08 01:08:37 +00:00
|
|
|
|
elif message.text == "HoYoLab":
|
2022-08-05 13:23:04 +00:00
|
|
|
|
bbs_name = "HoYoLab"
|
2022-09-08 01:08:37 +00:00
|
|
|
|
region = RegionEnum.HOYOLAB
|
2022-08-05 13:23:04 +00:00
|
|
|
|
else:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_text("选择错误,请重新选择")
|
|
|
|
|
return CHECK_SERVER
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data.region = region
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_text(f"请输入{bbs_name}的Cookies!或回复退出取消操作", reply_markup=ReplyKeyboardRemove())
|
2023-10-02 09:51:03 +00:00
|
|
|
|
await message.reply_html("<b>关于如何获取Cookies</b>\n\nhttps://telegra.ph/paigramteam-bot-setcookies-10-02")
|
2022-09-17 14:58:54 +00:00
|
|
|
|
return INPUT_COOKIES
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2022-09-17 14:58:54 +00:00
|
|
|
|
@conversation.state(state=INPUT_COOKIES)
|
2023-03-15 12:36:57 +00:00
|
|
|
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
2022-09-17 14:58:54 +00:00
|
|
|
|
async def input_cookies(self, update: Update, context: CallbackContext) -> int:
|
2022-09-08 01:08:37 +00:00
|
|
|
|
message = update.effective_message
|
|
|
|
|
if message.text == "退出":
|
|
|
|
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-12-18 16:51:36 +00:00
|
|
|
|
if ret := await self.parse_cookies(update, context, message.text):
|
|
|
|
|
return ret
|
|
|
|
|
return await self.check_cookies(update, context)
|
|
|
|
|
|
|
|
|
|
async def parse_cookies(self, update: Update, context: CallbackContext, text: str) -> Optional[int]:
|
|
|
|
|
user = update.effective_user
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
2022-11-27 10:42:49 +00:00
|
|
|
|
try:
|
2022-12-10 12:24:40 +00:00
|
|
|
|
# cookie str to dict
|
|
|
|
|
wrapped = (
|
2023-12-18 16:51:36 +00:00
|
|
|
|
ArkoWrapper(text.split(";"))
|
2022-12-11 06:00:12 +00:00
|
|
|
|
.filter(lambda x: x != "")
|
2022-12-10 12:24:40 +00:00
|
|
|
|
.map(lambda x: x.strip())
|
2023-02-21 14:19:28 +00:00
|
|
|
|
.map(lambda x: ((y := x.split("=", 1))[0], y[1]))
|
2022-12-10 12:24:40 +00:00
|
|
|
|
)
|
|
|
|
|
cookie = {x[0]: x[1] for x in wrapped}
|
2022-12-01 10:41:27 +00:00
|
|
|
|
cookies = self.parse_cookie(cookie)
|
2022-12-11 06:00:12 +00:00
|
|
|
|
except (AttributeError, ValueError, IndexError) as exc:
|
2022-12-10 12:24:40 +00:00
|
|
|
|
logger.info("用户 %s[%s] Cookies解析出现错误\ntext:%s", user.full_name, user.id, message.text)
|
2022-11-27 10:42:49 +00:00
|
|
|
|
logger.debug("解析Cookies出现错误", exc_info=exc)
|
|
|
|
|
await message.reply_text("解析Cookies出现错误,请检查是否正确", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
2023-10-02 09:51:03 +00:00
|
|
|
|
if account_cookies_plugin_data.region == RegionEnum.HYPERION:
|
|
|
|
|
try:
|
|
|
|
|
account_cookies_plugin_data.device = self.parse_headers(cookie)
|
|
|
|
|
except ValueError:
|
2023-10-19 10:58:00 +00:00
|
|
|
|
account_cookies_plugin_data.device = None
|
|
|
|
|
await message.reply_text("解析 Devices 出现错误,可能无法绕过风控,查询操作将需要通过验证。")
|
2022-08-06 06:22:37 +00:00
|
|
|
|
if not cookies:
|
2022-11-27 10:42:49 +00:00
|
|
|
|
logger.info("用户 %s[%s] Cookies格式有误", user.full_name, user.id)
|
2023-10-02 09:51:03 +00:00
|
|
|
|
await message.reply_text("Cookies格式有误,请检查后重新尝试绑定", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data.cookies = cookies
|
2022-09-17 14:58:54 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
async def check_cookies(self, update: Update, context: CallbackContext) -> int:
|
2022-09-17 14:58:54 +00:00
|
|
|
|
user = update.effective_user
|
|
|
|
|
message = update.effective_message
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
|
|
|
|
cookies = CookiesModel(**account_cookies_plugin_data.cookies)
|
|
|
|
|
if account_cookies_plugin_data.region == RegionEnum.HYPERION:
|
2023-07-18 09:29:31 +00:00
|
|
|
|
region = Region.CHINESE
|
2023-03-14 01:27:22 +00:00
|
|
|
|
elif account_cookies_plugin_data.region == RegionEnum.HOYOLAB:
|
2023-07-18 09:29:31 +00:00
|
|
|
|
region = Region.OVERSEAS
|
2022-08-05 13:23:04 +00:00
|
|
|
|
else:
|
2022-11-27 10:42:49 +00:00
|
|
|
|
logger.error("用户 %s[%s] region 异常", user.full_name, user.id)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_text("数据错误", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2024-07-04 11:09:48 +00:00
|
|
|
|
async with ZZZClient(cookies=cookies.to_dict(), region=region) as client:
|
2023-07-18 09:29:31 +00:00
|
|
|
|
check_cookie = cookies.check()
|
|
|
|
|
if cookies.login_ticket is not None:
|
|
|
|
|
try:
|
|
|
|
|
cookies.cookie_token = await client.get_cookie_token_by_login_ticket()
|
2023-07-18 15:35:37 +00:00
|
|
|
|
cookies.account_id = client.account_id
|
|
|
|
|
cookies.ltuid = client.account_id
|
2023-07-18 09:29:31 +00:00
|
|
|
|
logger.success("用户 %s[%s] 绑定时获取 cookie_token 成功", user.full_name, user.id)
|
|
|
|
|
cookies.stoken = await client.get_stoken_by_login_ticket()
|
|
|
|
|
logger.success("用户 %s[%s] 绑定时获取 stoken 成功", user.full_name, user.id)
|
|
|
|
|
check_cookie = True
|
|
|
|
|
except SimnetBadRequest as exc:
|
|
|
|
|
logger.warning(
|
|
|
|
|
"用户 %s[%s] 获取账号信息发生错误 [%s]%s", user.full_name, user.id, exc.ret_code, exc.original
|
|
|
|
|
)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.error("绑定时获取新Cookie失败 [%s]", (str(exc)))
|
|
|
|
|
finally:
|
|
|
|
|
cookies.login_ticket = None
|
|
|
|
|
cookies.login_uid = None
|
|
|
|
|
if not check_cookie:
|
|
|
|
|
await message.reply_text("检测到Cookie不完整,可能会出现问题。", reply_markup=ReplyKeyboardRemove())
|
2023-09-09 14:10:58 +00:00
|
|
|
|
if not cookies.stoken:
|
|
|
|
|
await message.reply_text(
|
|
|
|
|
"检测到缺少 stoken,请尝试添加 stoken 后重新绑定。", reply_markup=ReplyKeyboardRemove()
|
2024-03-16 01:44:15 +00:00
|
|
|
|
)
|
2023-09-09 14:10:58 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-08-16 15:00:44 +00:00
|
|
|
|
if cookies.stoken and cookies.stoken.startswith("v2") and cookies.mid is None:
|
2023-09-09 14:10:58 +00:00
|
|
|
|
await message.reply_text(
|
|
|
|
|
"检测到缺少 mid,请尝试添加 mid 后重新绑定。", reply_markup=ReplyKeyboardRemove()
|
2024-03-16 01:44:15 +00:00
|
|
|
|
)
|
2023-08-16 15:00:44 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-09-25 12:45:33 +00:00
|
|
|
|
try:
|
2023-11-04 11:43:27 +00:00
|
|
|
|
if region == Region.CHINESE:
|
|
|
|
|
cookies.stoken, cookies.mid = await client.get_stoken_v2_and_mid_by_by_stoken(
|
|
|
|
|
cookies.stoken, cookies.account_id
|
|
|
|
|
)
|
|
|
|
|
logger.success("用户 %s[%s] 绑定时获取 stoken_v2, mid 成功", user.full_name, user.id)
|
|
|
|
|
cookies.cookie_token = await client.get_cookie_token_by_stoken(cookies.stoken, mid=cookies.mid)
|
|
|
|
|
logger.success("用户 %s[%s] 绑定时获取 cookie_token 成功", user.full_name, user.id)
|
|
|
|
|
cookies.ltoken = await client.get_ltoken_by_stoken()
|
|
|
|
|
logger.success("用户 %s[%s] 绑定时获取 ltoken 成功", user.full_name, user.id)
|
|
|
|
|
else:
|
|
|
|
|
cookies_model = await client.get_all_token_by_stoken(cookies.stoken, cookies.account_id)
|
2024-04-06 08:14:41 +00:00
|
|
|
|
cookies.set_by_dict(cookies_model.dict())
|
2023-11-04 11:43:27 +00:00
|
|
|
|
logger.success(
|
|
|
|
|
"用户 %s[%s] 绑定时获取 stoken_v2, mid, ltoken, cookie_token 成功", user.full_name, user.id
|
|
|
|
|
)
|
2023-09-25 12:45:33 +00:00
|
|
|
|
except SimnetBadRequest as exc:
|
|
|
|
|
logger.warning(
|
|
|
|
|
"用户 %s[%s] 获取账号信息发生错误 [%s]%s", user.full_name, user.id, exc.ret_code, exc.original
|
|
|
|
|
)
|
|
|
|
|
await message.reply_text("Stoken 无效,请重新绑定。", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
2023-11-16 06:09:54 +00:00
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
|
await message.reply_text("Stoken 非法,请重新绑定。", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
2023-11-03 14:02:06 +00:00
|
|
|
|
except ValueError as e:
|
|
|
|
|
if "account_id" in str(e):
|
|
|
|
|
await message.reply_text("account_id 未找到,请检查输入是否有误。")
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
raise e
|
2023-03-14 14:03:21 +00:00
|
|
|
|
try:
|
2023-10-10 09:55:06 +00:00
|
|
|
|
if cookies.account_id is None:
|
|
|
|
|
logger.info("正在尝试获取用户 %s[%s] account_id", user.full_name, user.id)
|
2023-07-18 15:35:37 +00:00
|
|
|
|
account_info = await client.get_user_info()
|
|
|
|
|
account_id = account_info.accident_id
|
|
|
|
|
account_cookies_plugin_data.account_id = account_id
|
2023-10-10 09:55:06 +00:00
|
|
|
|
if cookies.is_v2:
|
|
|
|
|
cookies.set_v2_uid(account_id)
|
|
|
|
|
else:
|
|
|
|
|
cookies.set_uid(account_id)
|
2023-07-18 15:35:37 +00:00
|
|
|
|
logger.success("获取用户 %s[%s] account_id[%s] 成功", user.full_name, user.id, account_id)
|
2023-07-18 09:29:31 +00:00
|
|
|
|
else:
|
|
|
|
|
account_cookies_plugin_data.account_id = client.account_id
|
2024-07-04 11:09:48 +00:00
|
|
|
|
genshin_accounts = await client.get_zzz_accounts()
|
2023-07-18 09:29:31 +00:00
|
|
|
|
except DataNotPublic:
|
|
|
|
|
logger.info("用户 %s[%s] 账号疑似被注销", user.full_name, user.id)
|
|
|
|
|
await message.reply_text("账号疑似被注销,请检查账号状态", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
except InvalidCookies:
|
|
|
|
|
logger.info("用户 %s[%s] Cookies已经过期", user.full_name, user.id)
|
|
|
|
|
await message.reply_text(
|
|
|
|
|
"获取账号信息失败,返回Cookies已经过期,请尝试在无痕浏览器中登录获取Cookies。",
|
|
|
|
|
reply_markup=ReplyKeyboardRemove(),
|
|
|
|
|
)
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
except SimnetBadRequest as exc:
|
|
|
|
|
logger.info(
|
|
|
|
|
"用户 %s[%s] 获取账号信息发生错误 [%s]%s", user.full_name, user.id, exc.ret_code, exc.original
|
|
|
|
|
)
|
|
|
|
|
await message.reply_text(
|
|
|
|
|
f"获取账号信息发生错误,错误信息为 {exc.original},请检查Cookie或者账号是否正常",
|
|
|
|
|
reply_markup=ReplyKeyboardRemove(),
|
|
|
|
|
)
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
except AccountIdNotFound:
|
|
|
|
|
logger.info("用户 %s[%s] 无法获取账号ID", user.full_name, user.id)
|
|
|
|
|
await message.reply_text("无法获取账号ID,请检查Cookie是否正常", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
except (AttributeError, ValueError) as exc:
|
|
|
|
|
logger.warning("用户 %s[%s] Cookies错误", user.full_name, user.id)
|
|
|
|
|
logger.debug("用户 %s[%s] Cookies错误", user.full_name, user.id, exc_info=exc)
|
|
|
|
|
await message.reply_text("Cookies错误,请检查是否正确", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
2023-03-16 03:03:24 +00:00
|
|
|
|
if account_cookies_plugin_data.account_id is None:
|
|
|
|
|
await message.reply_text("无法获取账号ID,请检查Cookie是否正确或请稍后重试")
|
|
|
|
|
return ConversationHandler.END
|
2024-07-30 09:44:44 +00:00
|
|
|
|
if not genshin_accounts:
|
|
|
|
|
await message.reply_text("未找到游戏账号,请确认账号信息无误。")
|
2022-11-19 13:41:12 +00:00
|
|
|
|
return ConversationHandler.END
|
2024-07-30 09:44:44 +00:00
|
|
|
|
account_cookies_plugin_data.cookies = cookies.to_dict()
|
|
|
|
|
account_cookies_plugin_data.genshin_accounts = genshin_accounts
|
|
|
|
|
await self.send_choose_players_message(message, genshin_accounts)
|
|
|
|
|
return INPUT_PLAYERS
|
|
|
|
|
|
|
|
|
|
async def choose_to_save_player(
|
|
|
|
|
self, update: "Update", account_cookies_plugin_data: AccountCookiesPluginData
|
|
|
|
|
) -> int:
|
|
|
|
|
user = update.effective_user
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
genshin_account = account_cookies_plugin_data.genshin_account
|
2023-03-14 01:27:22 +00:00
|
|
|
|
player_info = await self.players_service.get(
|
2023-03-14 05:43:02 +00:00
|
|
|
|
user.id, player_id=genshin_account.uid, region=account_cookies_plugin_data.region
|
2023-03-14 01:27:22 +00:00
|
|
|
|
)
|
|
|
|
|
if player_info:
|
|
|
|
|
cookies_database = await self.cookies_service.get(
|
|
|
|
|
user.id, player_info.account_id, account_cookies_plugin_data.region
|
|
|
|
|
)
|
|
|
|
|
if cookies_database:
|
|
|
|
|
await message.reply_text("警告,你已经绑定Cookie,如果继续操作会覆盖当前Cookie。")
|
2022-08-05 13:23:04 +00:00
|
|
|
|
reply_keyboard = [["确认", "退出"]]
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_text("获取角色基础信息成功,请检查是否正确!")
|
2023-03-14 01:27:22 +00:00
|
|
|
|
logger.info(
|
|
|
|
|
"用户 %s[%s] 获取账号 %s[%s] 信息成功",
|
|
|
|
|
user.full_name,
|
|
|
|
|
user.id,
|
|
|
|
|
genshin_account.nickname,
|
|
|
|
|
genshin_account.uid,
|
|
|
|
|
)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
text = (
|
|
|
|
|
f"*角色信息*\n"
|
2023-03-14 01:27:22 +00:00
|
|
|
|
f"角色名称:{escape_markdown(genshin_account.nickname, version=2)}\n"
|
|
|
|
|
f"角色等级:{genshin_account.level}\n"
|
|
|
|
|
f"UID:`{genshin_account.uid}`\n"
|
|
|
|
|
f"服务器名称:`{genshin_account.server_name}`\n"
|
2022-10-10 11:07:28 +00:00
|
|
|
|
)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
|
|
|
|
|
return COMMAND_RESULT
|
2022-08-05 13:23:04 +00:00
|
|
|
|
|
2024-07-30 09:44:44 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
async def send_choose_players_message(message: "Message", genshin_accounts: List["Account"]):
|
|
|
|
|
text = "请选择要绑定的角色!"
|
|
|
|
|
reply_keyboard = [[f"{escape_markdown(x.nickname, version=2)} - {x.uid}"] for x in genshin_accounts]
|
|
|
|
|
reply_keyboard.append(["退出"])
|
|
|
|
|
await message.reply_text(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
|
|
|
|
|
|
|
|
|
|
@conversation.state(state=INPUT_PLAYERS)
|
|
|
|
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
|
|
|
|
async def input_players(self, update: Update, context: CallbackContext) -> int:
|
|
|
|
|
message = update.effective_message
|
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
|
|
|
|
if message.text == "退出":
|
|
|
|
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
uid = None
|
|
|
|
|
with contextlib.suppress(ValueError, IndexError):
|
|
|
|
|
uid = int(message.text.split("-")[-1].strip())
|
|
|
|
|
if not uid:
|
|
|
|
|
await message.reply_text("选择错误,请重新选择")
|
|
|
|
|
return INPUT_PLAYERS
|
|
|
|
|
genshin_account = next((x for x in account_cookies_plugin_data.genshin_accounts if x.uid == uid), None)
|
|
|
|
|
if not genshin_account:
|
|
|
|
|
await message.reply_text("选择错误,请重新选择")
|
|
|
|
|
return INPUT_PLAYERS
|
|
|
|
|
account_cookies_plugin_data.genshin_account = genshin_account
|
|
|
|
|
return await self.choose_to_save_player(update, account_cookies_plugin_data)
|
|
|
|
|
|
2023-10-02 09:51:03 +00:00
|
|
|
|
async def update_devices(self, account_id: int, device: AccountCookiesPluginDeviceData):
|
|
|
|
|
if not device:
|
|
|
|
|
return
|
|
|
|
|
device_model = await self.devices_service.get(account_id)
|
|
|
|
|
if device_model:
|
|
|
|
|
device_model.device_id = device.device_id
|
|
|
|
|
device_model.device_fp = device.device_fp
|
|
|
|
|
device_model.device_name = device.device_name
|
2023-10-19 10:58:00 +00:00
|
|
|
|
device_model.is_valid = True
|
2023-10-02 09:51:03 +00:00
|
|
|
|
await self.devices_service.update(device_model)
|
|
|
|
|
else:
|
|
|
|
|
device_model = Devices(
|
|
|
|
|
account_id=account_id,
|
|
|
|
|
device_id=device.device_id,
|
|
|
|
|
device_fp=device.device_fp,
|
|
|
|
|
device_name=device.device_name,
|
2023-10-19 10:58:00 +00:00
|
|
|
|
is_valid=True,
|
2023-10-02 09:51:03 +00:00
|
|
|
|
)
|
|
|
|
|
await self.devices_service.add(device_model)
|
|
|
|
|
|
|
|
|
|
async def update_player(self, uid: int, genshin_account: Account, region: RegionEnum, account_id: int):
|
|
|
|
|
player = await self.players_service.get(uid, player_id=genshin_account.uid, region=region)
|
|
|
|
|
if player:
|
2024-04-06 08:14:41 +00:00
|
|
|
|
if player.account_id != account_id:
|
|
|
|
|
player.account_id = account_id
|
|
|
|
|
await self.players_service.update(player)
|
2023-10-02 09:51:03 +00:00
|
|
|
|
else:
|
|
|
|
|
player_model = Player(
|
|
|
|
|
user_id=uid,
|
|
|
|
|
account_id=account_id,
|
|
|
|
|
player_id=genshin_account.uid,
|
|
|
|
|
region=region,
|
|
|
|
|
is_chosen=True, # todo 多账号
|
|
|
|
|
)
|
|
|
|
|
await self.players_service.add(player_model)
|
2024-07-04 11:09:48 +00:00
|
|
|
|
player = player_model
|
|
|
|
|
await self.update_player_info(player, genshin_account.nickname)
|
2023-10-02 09:51:03 +00:00
|
|
|
|
|
|
|
|
|
async def update_player_info(self, player: Player, nickname: str):
|
|
|
|
|
player_info = await self.player_info_service.get(player)
|
2024-07-04 11:09:48 +00:00
|
|
|
|
if player_info is None or player_info.create_time is None:
|
2023-10-02 09:51:03 +00:00
|
|
|
|
player_info = PlayerInfoSQLModel(
|
|
|
|
|
user_id=player.user_id,
|
|
|
|
|
player_id=player.player_id,
|
|
|
|
|
nickname=nickname,
|
|
|
|
|
create_time=datetime.now(),
|
|
|
|
|
is_update=True,
|
|
|
|
|
) # 不添加更新时间
|
|
|
|
|
await self.player_info_service.add(player_info)
|
|
|
|
|
|
|
|
|
|
async def update_cookies(self, uid: int, account_id: int, region: RegionEnum, cookies: Dict):
|
|
|
|
|
cookies_data_base = await self.cookies_service.get(uid, account_id, region)
|
|
|
|
|
if cookies_data_base:
|
|
|
|
|
cookies_data_base.data = cookies
|
|
|
|
|
cookies_data_base.status = CookiesStatusEnum.STATUS_SUCCESS
|
|
|
|
|
await self.cookies_service.update(cookies_data_base)
|
|
|
|
|
else:
|
|
|
|
|
cookies = Cookies(
|
|
|
|
|
user_id=uid,
|
|
|
|
|
account_id=account_id,
|
|
|
|
|
data=cookies,
|
|
|
|
|
region=region,
|
|
|
|
|
status=CookiesStatusEnum.STATUS_SUCCESS,
|
|
|
|
|
is_share=True, # todo 用户可以自行选择是否将Cookies加入公共池
|
|
|
|
|
)
|
|
|
|
|
await self.cookies_service.add(cookies)
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
@conversation.state(state=COMMAND_RESULT)
|
2023-03-15 12:36:57 +00:00
|
|
|
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
2022-08-05 13:23:04 +00:00
|
|
|
|
async def command_result(self, update: Update, context: CallbackContext) -> int:
|
|
|
|
|
user = update.effective_user
|
2022-09-08 01:08:37 +00:00
|
|
|
|
message = update.effective_message
|
2023-03-14 01:27:22 +00:00
|
|
|
|
account_cookies_plugin_data: AccountCookiesPluginData = context.chat_data.get("account_cookies_plugin_data")
|
2022-09-08 01:08:37 +00:00
|
|
|
|
if message.text == "退出":
|
|
|
|
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-03-14 01:27:22 +00:00
|
|
|
|
if message.text == "确认":
|
|
|
|
|
genshin_account = account_cookies_plugin_data.genshin_account
|
2023-10-02 09:51:03 +00:00
|
|
|
|
await self.update_player(
|
|
|
|
|
user.id, genshin_account, account_cookies_plugin_data.region, account_cookies_plugin_data.account_id
|
|
|
|
|
)
|
|
|
|
|
await self.update_cookies(
|
|
|
|
|
user.id,
|
|
|
|
|
account_cookies_plugin_data.account_id,
|
|
|
|
|
account_cookies_plugin_data.region,
|
|
|
|
|
account_cookies_plugin_data.cookies,
|
|
|
|
|
)
|
|
|
|
|
await self.update_devices(account_cookies_plugin_data.account_id, account_cookies_plugin_data.device)
|
|
|
|
|
logger.info("用户 %s[%s] 绑定账号成功", user.full_name, user.id)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
await message.reply_text("保存成功", reply_markup=ReplyKeyboardRemove())
|
2022-08-05 13:23:04 +00:00
|
|
|
|
return ConversationHandler.END
|
2023-03-14 01:27:22 +00:00
|
|
|
|
await message.reply_text("回复错误,请重新输入")
|
|
|
|
|
return COMMAND_RESULT
|