mirror of
https://github.com/PaiGramTeam/PaiGram.git
synced 2024-11-16 04:35:49 +00:00
✨ Support custom device
This commit is contained in:
parent
b5f16b76f2
commit
a36aeef9c3
38
alembic/versions/a1c10da5704b_devices.py
Normal file
38
alembic/versions/a1c10da5704b_devices.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
"""devices
|
||||||
|
|
||||||
|
Revision ID: a1c10da5704b
|
||||||
|
Revises: ddcfba3c7d5c
|
||||||
|
Create Date: 2023-06-13 19:34:47.189846
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
import sqlmodel
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "a1c10da5704b"
|
||||||
|
down_revision = "ddcfba3c7d5c"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
"devices",
|
||||||
|
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column("account_id", sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column("device_id", sqlmodel.AutoString(), nullable=False),
|
||||||
|
sa.Column("device_fp", sqlmodel.AutoString(), nullable=False),
|
||||||
|
sa.Column("device_name", sqlmodel.AutoString(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
mysql_collate="utf8mb4_general_ci",
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table("devices")
|
||||||
|
# ### end Alembic commands ###
|
5
core/services/devices/__init__.py
Normal file
5
core/services/devices/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
"""DeviceService"""
|
||||||
|
|
||||||
|
from core.services.devices.services import DevicesService
|
||||||
|
|
||||||
|
__all__ = "DevicesService"
|
23
core/services/devices/models.py
Normal file
23
core/services/devices/models.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from sqlmodel import SQLModel, Field, Column, Integer, BigInteger
|
||||||
|
|
||||||
|
__all__ = ("Devices", "DevicesDataBase")
|
||||||
|
|
||||||
|
|
||||||
|
class Devices(SQLModel):
|
||||||
|
__table_args__ = dict(mysql_charset="utf8mb4", mysql_collate="utf8mb4_general_ci")
|
||||||
|
id: Optional[int] = Field(default=None, sa_column=Column(Integer, primary_key=True, autoincrement=True))
|
||||||
|
account_id: int = Field(
|
||||||
|
default=None,
|
||||||
|
sa_column=Column(
|
||||||
|
BigInteger(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
device_id: str = Field()
|
||||||
|
device_fp: str = Field()
|
||||||
|
device_name: Optional[str] = Field(default=None)
|
||||||
|
|
||||||
|
|
||||||
|
class DevicesDataBase(Devices, table=True):
|
||||||
|
__tablename__ = "devices"
|
41
core/services/devices/repositories.py
Normal file
41
core/services/devices/repositories.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from sqlmodel import select
|
||||||
|
|
||||||
|
from core.base_service import BaseService
|
||||||
|
from core.dependence.database import Database
|
||||||
|
from core.services.devices.models import DevicesDataBase as Devices
|
||||||
|
from core.sqlmodel.session import AsyncSession
|
||||||
|
|
||||||
|
__all__ = ("DevicesRepository",)
|
||||||
|
|
||||||
|
|
||||||
|
class DevicesRepository(BaseService.Component):
|
||||||
|
def __init__(self, database: Database):
|
||||||
|
self.engine = database.engine
|
||||||
|
|
||||||
|
async def get(
|
||||||
|
self,
|
||||||
|
account_id: int,
|
||||||
|
) -> Optional[Devices]:
|
||||||
|
async with AsyncSession(self.engine) as session:
|
||||||
|
statement = select(Devices).where(Devices.account_id == account_id)
|
||||||
|
results = await session.exec(statement)
|
||||||
|
return results.first()
|
||||||
|
|
||||||
|
async def add(self, devices: Devices) -> None:
|
||||||
|
async with AsyncSession(self.engine) as session:
|
||||||
|
session.add(devices)
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
async def update(self, devices: Devices) -> Devices:
|
||||||
|
async with AsyncSession(self.engine) as session:
|
||||||
|
session.add(devices)
|
||||||
|
await session.commit()
|
||||||
|
await session.refresh(devices)
|
||||||
|
return devices
|
||||||
|
|
||||||
|
async def delete(self, devices: Devices) -> None:
|
||||||
|
async with AsyncSession(self.engine) as session:
|
||||||
|
await session.delete(devices)
|
||||||
|
await session.commit()
|
25
core/services/devices/services.py
Normal file
25
core/services/devices/services.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from core.base_service import BaseService
|
||||||
|
from core.services.devices.repositories import DevicesRepository
|
||||||
|
from core.services.devices.models import DevicesDataBase as Devices
|
||||||
|
|
||||||
|
|
||||||
|
class DevicesService(BaseService):
|
||||||
|
def __init__(self, devices_repository: DevicesRepository) -> None:
|
||||||
|
self._repository: DevicesRepository = devices_repository
|
||||||
|
|
||||||
|
async def update(self, devices: Devices):
|
||||||
|
await self._repository.update(devices)
|
||||||
|
|
||||||
|
async def add(self, devices: Devices):
|
||||||
|
await self._repository.add(devices)
|
||||||
|
|
||||||
|
async def get(
|
||||||
|
self,
|
||||||
|
account_id: int,
|
||||||
|
) -> Optional[Devices]:
|
||||||
|
return await self._repository.get(account_id)
|
||||||
|
|
||||||
|
async def delete(self, devices: Devices) -> None:
|
||||||
|
return await self._repository.delete(devices)
|
@ -11,7 +11,8 @@ from qrcode.image.pure import PyPNGImage
|
|||||||
|
|
||||||
from ...logger import logger
|
from ...logger import logger
|
||||||
from ...models.genshin.cookies import CookiesModel
|
from ...models.genshin.cookies import CookiesModel
|
||||||
from ...utility.helpers import get_device_id, get_ds, update_device_headers
|
from ...utility.devices import devices_methods
|
||||||
|
from ...utility.helpers import get_device_id, get_ds
|
||||||
|
|
||||||
__all__ = ("AuthClient",)
|
__all__ = ("AuthClient",)
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ class AuthClient:
|
|||||||
"x-rpc-app_id": "bll8iq97cem8",
|
"x-rpc-app_id": "bll8iq97cem8",
|
||||||
"User-Agent": "okhttp/4.8.0",
|
"User-Agent": "okhttp/4.8.0",
|
||||||
}
|
}
|
||||||
update_device_headers(self.user_id, headers)
|
await devices_methods.update_device_headers(self.user_id, headers)
|
||||||
app_version, client_type, ds_sign = get_ds(new_ds=True, data=data)
|
app_version, client_type, ds_sign = get_ds(new_ds=True, data=data)
|
||||||
headers["x-rpc-app_version"] = app_version
|
headers["x-rpc-app_version"] = app_version
|
||||||
headers["x-rpc-client_type"] = client_type
|
headers["x-rpc-client_type"] = client_type
|
||||||
|
@ -4,7 +4,8 @@ import time
|
|||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from ..base.hyperionrequest import HyperionRequest
|
from ..base.hyperionrequest import HyperionRequest
|
||||||
from ...utility.helpers import get_ua, get_ds, update_device_headers
|
from ...utility.devices import devices_methods
|
||||||
|
from ...utility.helpers import get_ua, get_ds
|
||||||
|
|
||||||
__all__ = ("Verify",)
|
__all__ = ("Verify",)
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ class Verify:
|
|||||||
headers["Referer"] = referer
|
headers["Referer"] = referer
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
def get_headers(self, data: dict = None, params: dict = None):
|
async def get_headers(self, data: dict = None, params: dict = None):
|
||||||
headers = self.BBS_HEADERS.copy()
|
headers = self.BBS_HEADERS.copy()
|
||||||
app_version, client_type, ds = get_ds(new_ds=True, data=data, params=params)
|
app_version, client_type, ds = get_ds(new_ds=True, data=data, params=params)
|
||||||
headers["x-rpc-app_version"] = app_version
|
headers["x-rpc-app_version"] = app_version
|
||||||
@ -53,7 +54,7 @@ class Verify:
|
|||||||
headers["DS"] = ds
|
headers["DS"] = ds
|
||||||
headers["x-rpc-challenge_path"] = f"https://{self.HOST}{self.REFERER_URL}"
|
headers["x-rpc-challenge_path"] = f"https://{self.HOST}{self.REFERER_URL}"
|
||||||
headers["x-rpc-challenge_game"] = self.GAME
|
headers["x-rpc-challenge_game"] = self.GAME
|
||||||
update_device_headers(self.account_id, headers)
|
await devices_methods.update_device_headers(self.account_id, headers)
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -63,7 +64,7 @@ class Verify:
|
|||||||
async def create(self, is_high: bool = False):
|
async def create(self, is_high: bool = False):
|
||||||
url = self.get_url(self.HOST, self.CREATE_VERIFICATION_URL)
|
url = self.get_url(self.HOST, self.CREATE_VERIFICATION_URL)
|
||||||
params = {"is_high": "true" if is_high else "false"}
|
params = {"is_high": "true" if is_high else "false"}
|
||||||
headers = self.get_headers(params=params)
|
headers = await self.get_headers(params=params)
|
||||||
response = await self.client.get(url, params=params, headers=headers)
|
response = await self.client.get(url, params=params, headers=headers)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ class Verify:
|
|||||||
url = self.get_url(self.HOST, self.VERIFY_VERIFICATION_URL)
|
url = self.get_url(self.HOST, self.VERIFY_VERIFICATION_URL)
|
||||||
data = {"geetest_challenge": challenge, "geetest_validate": validate, "geetest_seccode": f"{validate}|jordan"}
|
data = {"geetest_challenge": challenge, "geetest_validate": validate, "geetest_seccode": f"{validate}|jordan"}
|
||||||
|
|
||||||
headers = self.get_headers(data=data)
|
headers = await self.get_headers(data=data)
|
||||||
response = await self.client.post(url, json=data, headers=headers)
|
response = await self.client.post(url, json=data, headers=headers)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
33
modules/apihelper/utility/devices.py
Normal file
33
modules/apihelper/utility/devices.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from typing import Optional, Dict
|
||||||
|
|
||||||
|
from core.services.devices import DevicesService
|
||||||
|
from modules.apihelper.utility.helpers import get_device_id, hex_digest
|
||||||
|
|
||||||
|
|
||||||
|
class DevicesMethods:
|
||||||
|
def __init__(self):
|
||||||
|
self.service: Optional[DevicesService] = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_default_device_header(account_id: int, headers: Dict = None) -> Dict[str, str]:
|
||||||
|
headers = headers or {}
|
||||||
|
headers["x-rpc-device_id"] = get_device_id(str(account_id))
|
||||||
|
headers["x-rpc-device_fp"] = hex_digest(headers["x-rpc-device_id"])[:13]
|
||||||
|
headers["x-rpc-device_name"] = "Xiaomi"
|
||||||
|
return headers
|
||||||
|
|
||||||
|
async def update_device_headers(self, account_id: int, headers: Dict = None) -> Dict[str, str]:
|
||||||
|
account_id = account_id or 0
|
||||||
|
if not self.service:
|
||||||
|
return self.get_default_device_header(account_id, headers)
|
||||||
|
device = await self.service.get(account_id)
|
||||||
|
if not device:
|
||||||
|
return self.get_default_device_header(account_id, headers)
|
||||||
|
headers = headers or {}
|
||||||
|
headers["x-rpc-device_id"] = device.device_id
|
||||||
|
headers["x-rpc-device_fp"] = device.device_fp
|
||||||
|
headers["x-rpc-device_name"] = device.device_name or "Xiaomi"
|
||||||
|
return headers
|
||||||
|
|
||||||
|
|
||||||
|
devices_methods = DevicesMethods()
|
@ -4,9 +4,9 @@ import random
|
|||||||
import string
|
import string
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Any, Mapping, Optional, Dict
|
from typing import Any, Mapping, Optional
|
||||||
|
|
||||||
__all__ = ("get_device_id", "hex_digest", "get_ds", "get_recognize_server", "get_ua", "update_device_headers")
|
__all__ = ("get_device_id", "hex_digest", "get_ds", "get_recognize_server", "get_ua")
|
||||||
|
|
||||||
RECOGNIZE_SERVER = {
|
RECOGNIZE_SERVER = {
|
||||||
"1": "cn_gf01",
|
"1": "cn_gf01",
|
||||||
@ -23,14 +23,6 @@ def get_device_id(name: str = ""):
|
|||||||
return str(uuid.uuid3(uuid.NAMESPACE_URL, name))
|
return str(uuid.uuid3(uuid.NAMESPACE_URL, name))
|
||||||
|
|
||||||
|
|
||||||
def update_device_headers(account_id: int, headers: Dict = None) -> Dict[str, str]:
|
|
||||||
account_id = account_id or 0
|
|
||||||
headers = headers or {}
|
|
||||||
headers["x-rpc-device_id"] = get_device_id(str(account_id))
|
|
||||||
headers["x-rpc-device_fp"] = hex_digest(headers["x-rpc-device_id"])[:13]
|
|
||||||
return headers
|
|
||||||
|
|
||||||
|
|
||||||
def hex_digest(text):
|
def hex_digest(text):
|
||||||
_md5 = hashlib.md5() # nosec B303
|
_md5 = hashlib.md5() # nosec B303
|
||||||
_md5.update(text.encode())
|
_md5.update(text.encode())
|
||||||
|
187
plugins/account/devices.py
Normal file
187
plugins/account/devices.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, TelegramObject, Update
|
||||||
|
from telegram.ext import CallbackContext, ConversationHandler, filters
|
||||||
|
from telegram.helpers import escape_markdown
|
||||||
|
|
||||||
|
from core.basemodel import RegionEnum
|
||||||
|
from core.plugin import Plugin, conversation, handler
|
||||||
|
from core.services.cookies.services import CookiesService
|
||||||
|
from core.services.devices import DevicesService
|
||||||
|
from core.services.devices.models import DevicesDataBase as Devices
|
||||||
|
from core.services.players.services import PlayersService
|
||||||
|
from modules.apihelper.utility.devices import devices_methods
|
||||||
|
from utils.log import logger
|
||||||
|
|
||||||
|
__all__ = ("AccountDevicesPlugin",)
|
||||||
|
|
||||||
|
|
||||||
|
class AccountDevicesPluginData(TelegramObject):
|
||||||
|
device_id: str = ""
|
||||||
|
device_fp: str = ""
|
||||||
|
device_name: Optional[str] = None
|
||||||
|
account_id: int = 0
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.device_id = ""
|
||||||
|
self.device_fp = ""
|
||||||
|
self.device_name = None
|
||||||
|
self.account_id = 0
|
||||||
|
|
||||||
|
|
||||||
|
CHECK_SERVER, INPUT_DEVICES, COMMAND_RESULT = range(10100, 10103)
|
||||||
|
|
||||||
|
|
||||||
|
class AccountDevicesPlugin(Plugin.Conversation):
|
||||||
|
"""设备绑定"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
players_service: PlayersService = None,
|
||||||
|
cookies_service: CookiesService = None,
|
||||||
|
devices_service: DevicesService = None,
|
||||||
|
):
|
||||||
|
self.cookies_service = cookies_service
|
||||||
|
self.players_service = players_service
|
||||||
|
self.devices_service = devices_service
|
||||||
|
devices_methods.service = devices_service
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_headers(data: AccountDevicesPluginData, headers_text: str) -> None:
|
||||||
|
headers = {}
|
||||||
|
for line in headers_text.splitlines():
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
k, v = line.split(":", 1)
|
||||||
|
headers[k.strip()] = v.strip()
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
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")
|
||||||
|
|
||||||
|
@conversation.entry_point
|
||||||
|
@handler.command(command="setdevice", filters=filters.ChatType.PRIVATE, block=False)
|
||||||
|
@handler.command(command="setdevices", filters=filters.ChatType.PRIVATE, block=False)
|
||||||
|
async def command_start(self, update: Update, context: CallbackContext) -> int:
|
||||||
|
user = update.effective_user
|
||||||
|
message = update.effective_message
|
||||||
|
logger.info("用户 %s[%s] 绑定设备命令请求", user.full_name, user.id)
|
||||||
|
account_devices_plugin_data: AccountDevicesPluginData = context.chat_data.get("account_devices_plugin_data")
|
||||||
|
if account_devices_plugin_data is None:
|
||||||
|
account_devices_plugin_data = AccountDevicesPluginData()
|
||||||
|
context.chat_data["account_devices_plugin_data"] = account_devices_plugin_data
|
||||||
|
else:
|
||||||
|
account_devices_plugin_data.reset()
|
||||||
|
|
||||||
|
text = f'你好 {user.mention_markdown_v2()} {escape_markdown("!请选择要绑定的服务器!或回复退出取消操作")}'
|
||||||
|
reply_keyboard = [["米游社"], ["退出"]]
|
||||||
|
await message.reply_markdown_v2(text, reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
|
||||||
|
return CHECK_SERVER
|
||||||
|
|
||||||
|
@conversation.state(state=CHECK_SERVER)
|
||||||
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
||||||
|
async def check_server(self, update: Update, context: CallbackContext) -> int:
|
||||||
|
user = update.effective_user
|
||||||
|
message = update.effective_message
|
||||||
|
account_devices_plugin_data: AccountDevicesPluginData = context.chat_data.get("account_devices_plugin_data")
|
||||||
|
if message.text == "退出":
|
||||||
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return ConversationHandler.END
|
||||||
|
if message.text == "米游社":
|
||||||
|
region = RegionEnum.HYPERION
|
||||||
|
bbs_name = "米游社"
|
||||||
|
else:
|
||||||
|
await message.reply_text("选择错误,请重新选择")
|
||||||
|
return CHECK_SERVER
|
||||||
|
player_info = await self.players_service.get(user.id, region=region)
|
||||||
|
if player_info:
|
||||||
|
cookies_database = await self.cookies_service.get(user.id, player_info.account_id, region)
|
||||||
|
if not cookies_database:
|
||||||
|
await message.reply_text(f"你还没有绑定 {bbs_name} 的Cookies,请先绑定Cookies")
|
||||||
|
return ConversationHandler.END
|
||||||
|
account_devices_plugin_data.account_id = player_info.account_id
|
||||||
|
else:
|
||||||
|
await message.reply_text(f"你还没有绑定 {bbs_name} 的Cookies,请先绑定Cookies")
|
||||||
|
return ConversationHandler.END
|
||||||
|
help_message = (
|
||||||
|
"<b>关于如何获取Device</b>\n"
|
||||||
|
"<b>此操作只能在PC上进行。</b>\n\n"
|
||||||
|
"PC:\n"
|
||||||
|
"1、打开<a href='https://user.mihoyo.com/'>通行证</a>并登录\n"
|
||||||
|
"2、进入通行证按F12打开开发者工具\n"
|
||||||
|
"3、将开发者工具切换至网络(Network)并点击过滤栏中的 Fetch/XHR 并刷新页面\n"
|
||||||
|
"4、在请求列表中找到 login_by_cookie\n"
|
||||||
|
"5、右键并复制请求标头(Request Headers)\n"
|
||||||
|
"<u>如发现没有此请求大概因为缓存的存在需要你点击禁用缓存(Disable Cache)再次刷新页面</u>"
|
||||||
|
)
|
||||||
|
await message.reply_html(help_message, disable_web_page_preview=True)
|
||||||
|
await message.reply_text(f"请输入{bbs_name}的请求标头!或回复退出取消操作", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return INPUT_DEVICES
|
||||||
|
|
||||||
|
@conversation.state(state=INPUT_DEVICES)
|
||||||
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
||||||
|
async def input_cookies(self, update: Update, context: CallbackContext) -> int:
|
||||||
|
message = update.effective_message
|
||||||
|
user = update.effective_user
|
||||||
|
account_devices_plugin_data: AccountDevicesPluginData = context.chat_data.get("account_devices_plugin_data")
|
||||||
|
if message.text == "退出":
|
||||||
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return ConversationHandler.END
|
||||||
|
try:
|
||||||
|
self.parse_headers(account_devices_plugin_data, message.text)
|
||||||
|
except ValueError as exc:
|
||||||
|
logger.info("用户 %s[%s] Devices解析出现错误\ntext:%s", user.full_name, user.id, message.text)
|
||||||
|
logger.debug("解析Devices出现错误", exc_info=exc)
|
||||||
|
await message.reply_text("解析Devices出现错误,请检查是否正确", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return ConversationHandler.END
|
||||||
|
reply_keyboard = [["确认", "退出"]]
|
||||||
|
await message.reply_markdown_v2(
|
||||||
|
"请确认修改!", reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
|
||||||
|
)
|
||||||
|
return COMMAND_RESULT
|
||||||
|
|
||||||
|
@conversation.state(state=COMMAND_RESULT)
|
||||||
|
@handler.message(filters=filters.TEXT & ~filters.COMMAND, block=False)
|
||||||
|
async def command_result(self, update: Update, context: CallbackContext) -> int:
|
||||||
|
user = update.effective_user
|
||||||
|
message = update.effective_message
|
||||||
|
account_devices_plugin_data: AccountDevicesPluginData = context.chat_data.get("account_devices_plugin_data")
|
||||||
|
if message.text == "退出":
|
||||||
|
await message.reply_text("退出任务", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return ConversationHandler.END
|
||||||
|
if message.text == "确认":
|
||||||
|
device = await self.devices_service.get(account_devices_plugin_data.account_id)
|
||||||
|
if device:
|
||||||
|
device.device_id = account_devices_plugin_data.device_id
|
||||||
|
device.device_fp = account_devices_plugin_data.device_fp
|
||||||
|
device.device_name = account_devices_plugin_data.device_name
|
||||||
|
await self.devices_service.update(device)
|
||||||
|
logger.success("用户 %s[%s] 更新Devices", user.full_name, user.id)
|
||||||
|
else:
|
||||||
|
device = Devices(
|
||||||
|
account_id=account_devices_plugin_data.account_id,
|
||||||
|
device_id=account_devices_plugin_data.device_id,
|
||||||
|
device_fp=account_devices_plugin_data.device_fp,
|
||||||
|
device_name=account_devices_plugin_data.device_name,
|
||||||
|
)
|
||||||
|
await self.devices_service.add(device)
|
||||||
|
logger.info("用户 %s[%s] 绑定Devices成功", user.full_name, user.id)
|
||||||
|
await message.reply_text("保存成功", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return ConversationHandler.END
|
||||||
|
await message.reply_text("回复错误,请重新输入")
|
||||||
|
return COMMAND_RESULT
|
@ -4,7 +4,8 @@ from genshin import Client
|
|||||||
from genshin.client.routes import InternationalRoute # noqa F401
|
from genshin.client.routes import InternationalRoute # noqa F401
|
||||||
from genshin.utility import recognize_genshin_server
|
from genshin.utility import recognize_genshin_server
|
||||||
|
|
||||||
from modules.apihelper.utility.helpers import hex_digest, get_ds, update_device_headers
|
from modules.apihelper.utility.devices import devices_methods
|
||||||
|
from modules.apihelper.utility.helpers import hex_digest, get_ds
|
||||||
|
|
||||||
AUTHKEY_API = "https://api-takumi.mihoyo.com/binding/api/genAuthKey"
|
AUTHKEY_API = "https://api-takumi.mihoyo.com/binding/api/genAuthKey"
|
||||||
HK4E_LOGIN_URL = InternationalRoute(
|
HK4E_LOGIN_URL = InternationalRoute(
|
||||||
@ -37,7 +38,7 @@ async def get_authkey_by_stoken(client: Client) -> Optional[str]:
|
|||||||
}
|
}
|
||||||
device_id = hex_digest(str(client.uid))
|
device_id = hex_digest(str(client.uid))
|
||||||
device = f"Paimon Build {device_id[:5]}"
|
device = f"Paimon Build {device_id[:5]}"
|
||||||
update_device_headers(client.hoyolab_id, headers)
|
await devices_methods.update_device_headers(client.hoyolab_id, headers)
|
||||||
headers["x-rpc-device_name"] = device
|
headers["x-rpc-device_name"] = device
|
||||||
headers["x-rpc-device_model"] = device
|
headers["x-rpc-device_model"] = device
|
||||||
app_version, client_type, ds_sign = get_ds()
|
app_version, client_type, ds_sign = get_ds()
|
||||||
|
@ -9,8 +9,8 @@ from genshin import constants, types, utility
|
|||||||
from genshin.client import routes
|
from genshin.client import routes
|
||||||
from genshin.utility import generate_dynamic_secret, ds
|
from genshin.utility import generate_dynamic_secret, ds
|
||||||
|
|
||||||
from modules.apihelper.utility.helpers import get_ds, get_ua, get_device_id, hex_digest, update_device_headers
|
from modules.apihelper.utility.devices import devices_methods
|
||||||
from utils.log import logger
|
from modules.apihelper.utility.helpers import get_ds, get_ua, get_device_id, hex_digest
|
||||||
from utils.patch.methods import patch, patchable
|
from utils.patch.methods import patch, patchable
|
||||||
|
|
||||||
DEVICE_ID = get_device_id()
|
DEVICE_ID = get_device_id()
|
||||||
@ -156,7 +156,7 @@ class BaseClient:
|
|||||||
"x-rpc-client_type": client_type,
|
"x-rpc-client_type": client_type,
|
||||||
"ds": ds_sign,
|
"ds": ds_sign,
|
||||||
}
|
}
|
||||||
update_device_headers(self.hoyolab_id, headers)
|
await devices_methods.update_device_headers(self.hoyolab_id, headers)
|
||||||
else:
|
else:
|
||||||
raise TypeError(f"{region!r} is not a valid region.")
|
raise TypeError(f"{region!r} is not a valid region.")
|
||||||
|
|
||||||
@ -190,8 +190,7 @@ class BaseClient:
|
|||||||
|
|
||||||
headers = dict(headers or {})
|
headers = dict(headers or {})
|
||||||
headers.setdefault("User-Agent", self.USER_AGENT)
|
headers.setdefault("User-Agent", self.USER_AGENT)
|
||||||
update_device_headers(self.hoyolab_id, headers)
|
await devices_methods.update_device_headers(self.hoyolab_id, headers)
|
||||||
logger.debug("Account ID: %s Header: %s" % (self.hoyolab_id, headers))
|
|
||||||
|
|
||||||
if method is None:
|
if method is None:
|
||||||
method = "POST" if data else "GET"
|
method = "POST" if data else "GET"
|
||||||
@ -264,7 +263,7 @@ class BaseClient:
|
|||||||
"ds": ds_sign,
|
"ds": ds_sign,
|
||||||
}
|
}
|
||||||
headers.update(add_headers)
|
headers.update(add_headers)
|
||||||
update_device_headers(self.hoyolab_id, headers)
|
await devices_methods.update_device_headers(self.hoyolab_id, headers)
|
||||||
elif self.region == types.Region.OVERSEAS:
|
elif self.region == types.Region.OVERSEAS:
|
||||||
headers.update(ds.get_ds_headers(data=data, params=params, region=region, lang=lang or self.lang))
|
headers.update(ds.get_ds_headers(data=data, params=params, region=region, lang=lang or self.lang))
|
||||||
headers["Referer"] = str(routes.BBS_REFERER_URL.get_url(self.region))
|
headers["Referer"] = str(routes.BBS_REFERER_URL.get_url(self.region))
|
||||||
@ -349,7 +348,7 @@ class DailyRewardClient:
|
|||||||
headers["x-rpc-challenge"] = challenge
|
headers["x-rpc-challenge"] = challenge
|
||||||
headers["x-rpc-validate"] = validate
|
headers["x-rpc-validate"] = validate
|
||||||
headers["x-rpc-seccode"] = f"{validate}|jordan"
|
headers["x-rpc-seccode"] = f"{validate}|jordan"
|
||||||
update_device_headers(self.hoyolab_id, headers)
|
await devices_methods.update_device_headers(self.hoyolab_id, headers)
|
||||||
else:
|
else:
|
||||||
raise TypeError(f"{self.region!r} is not a valid region.")
|
raise TypeError(f"{self.region!r} is not a valid region.")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user