mirror of
https://github.com/Genshin-bots/gsuid_core.git
synced 2025-05-12 06:55:49 +08:00
🍻 实验性加入fp
和deviceid
支持
This commit is contained in:
parent
ed846b5851
commit
23c499c82b
@ -134,4 +134,6 @@ CALENDAR_URL = f'{DRAW_BASE_URL}/calendar'
|
||||
RECEIVE_URL = f'{DRAW_BASE_URL}/post_my_draw'
|
||||
BS_INDEX_URL = f'{DRAW_BASE_URL}/index'
|
||||
|
||||
GET_FP_URL = 'https://public-data-api.mihoyo.com/device-fp/api/getFp'
|
||||
|
||||
_API = locals()
|
||||
|
@ -14,6 +14,7 @@ from typing import Any, Dict, List, Tuple, Union, Literal, Optional, cast
|
||||
from aiohttp import TCPConnector, ClientSession, ContentTypeError
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
from gsuid_core.utils.database.api import DBSqla
|
||||
from gsuid_core.utils.plugins_config.gs_config import core_plugins_config
|
||||
|
||||
from .api import _API
|
||||
@ -88,6 +89,7 @@ class BaseMysApi:
|
||||
is_sr = False
|
||||
RECOGNIZE_SERVER = RECOGNIZE_SERVER
|
||||
chs = {}
|
||||
dbsqla: DBSqla = DBSqla()
|
||||
|
||||
@abstractmethod
|
||||
async def _upass(self, header: Dict) -> str:
|
||||
@ -109,6 +111,59 @@ class BaseMysApi:
|
||||
async def get_stoken(self, uid: str) -> Optional[str]:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def get_user_fp(self, uid: str) -> Optional[str]:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
async def get_user_device_id(self, uid: str) -> Optional[str]:
|
||||
...
|
||||
|
||||
def get_device_id(self) -> str:
|
||||
device_id = uuid.uuid4().hex
|
||||
return device_id
|
||||
|
||||
def generate_seed(self, length: int):
|
||||
characters = '0123456789abcdef'
|
||||
result = ''.join(random.choices(characters, k=length))
|
||||
return result
|
||||
|
||||
async def generate_fp_by_uid(self, uid: str) -> str:
|
||||
seed_id = self.generate_seed(16)
|
||||
seed_time = str(int(time.time() * 1000))
|
||||
ext_fields = f'{{"userAgent":"{self._HEADER["User-Agent"]}",\
|
||||
"browserScreenSize":281520,"maxTouchPoints":5,\
|
||||
"isTouchSupported":true,"browserLanguage":"zh-CN","browserPlat":"iPhone",\
|
||||
"browserTimeZone":"Asia/Shanghai","webGlRender":"Apple GPU",\
|
||||
"webGlVendor":"Apple Inc.",\
|
||||
"numOfPlugins":0,"listOfPlugins":"unknown","screenRatio":3,"deviceMemory":"unknown",\
|
||||
"hardwareConcurrency":"4","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":0,\
|
||||
"hasLiedResolution":1,"hasLiedOs":0,"hasLiedBrowser":0}}'
|
||||
body = {
|
||||
'seed_id': seed_id,
|
||||
'device_id': await self.get_user_device_id(uid),
|
||||
'platform': '5',
|
||||
'seed_time': seed_time,
|
||||
'ext_fields': ext_fields,
|
||||
'app_name': 'account_cn',
|
||||
'device_fp': '38d7ee834d1e9',
|
||||
}
|
||||
HEADER = copy.deepcopy(self._HEADER)
|
||||
res = await self._mys_request(
|
||||
url=self.MAPI['GET_FP_URL'],
|
||||
method='POST',
|
||||
header=HEADER,
|
||||
data=body,
|
||||
)
|
||||
if not isinstance(res, Dict):
|
||||
logger.error(f"获取fp连接失败{res}")
|
||||
return random_hex(13).lower()
|
||||
elif res["data"]["code"] != 200:
|
||||
logger.error(f"获取fp参数不正确{res['data']['msg']}")
|
||||
return random_hex(13).lower()
|
||||
else:
|
||||
return res["data"]["device_fp"]
|
||||
|
||||
async def simple_mys_req(
|
||||
self,
|
||||
URL: str,
|
||||
@ -200,8 +255,15 @@ class BaseMysApi:
|
||||
connector=TCPConnector(verify_ssl=ssl_verify)
|
||||
) as client:
|
||||
raw_data = {}
|
||||
uid = None
|
||||
if params and 'role_id' in params:
|
||||
uid = params['role_id']
|
||||
header['x-rpc-device_id'] = await self.get_user_device_id(uid)
|
||||
header['x-rpc-device_fp'] = await self.get_user_fp(uid)
|
||||
|
||||
for _ in range(2):
|
||||
if 'Cookie' in header and header['Cookie'] in self.chs:
|
||||
# header['x-rpc-challenge']=self.chs.pop(header['Cookie'])
|
||||
if self.is_sr:
|
||||
header['x-rpc-challenge'] = self.chs.pop(
|
||||
header['Cookie']
|
||||
@ -216,6 +278,7 @@ class BaseMysApi:
|
||||
header['x-rpc-page'] = (
|
||||
'3.1.3_#/rpg' if self.is_sr else '3.1.3_#/ys'
|
||||
)
|
||||
|
||||
async with client.request(
|
||||
method,
|
||||
url=url,
|
||||
@ -244,6 +307,11 @@ class BaseMysApi:
|
||||
if retcode == 1034:
|
||||
ch = await self._upass(header)
|
||||
self.chs[header['Cookie']] = ch
|
||||
elif retcode == -10001 and uid:
|
||||
sqla = self.dbsqla.get_sqla('TEMP')
|
||||
new_fp = await self.generate_fp_by_uid(uid)
|
||||
await sqla.update_user_data(uid, {'fp': new_fp})
|
||||
header['x-rpc-device_fp'] = new_fp
|
||||
elif retcode != 0:
|
||||
return retcode
|
||||
else:
|
||||
|
@ -1,15 +1,12 @@
|
||||
from typing import Literal, Optional
|
||||
|
||||
from gsuid_core.utils.api.mys import MysApi
|
||||
from gsuid_core.utils.database.api import DBSqla
|
||||
from gsuid_core.utils.plugins_config.gs_config import core_plugins_config
|
||||
|
||||
gsconfig = core_plugins_config
|
||||
|
||||
|
||||
class _MysApi(MysApi):
|
||||
dbsqla: DBSqla = DBSqla()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@ -24,5 +21,23 @@ class _MysApi(MysApi):
|
||||
async def get_stoken(self, uid: str) -> Optional[str]:
|
||||
return await self.dbsqla.get_sqla('TEMP').get_user_stoken(uid)
|
||||
|
||||
async def get_user_fp(self, uid: str) -> Optional[str]:
|
||||
data = await self.dbsqla.get_sqla('TEMP').get_user_fp(uid)
|
||||
if data is None:
|
||||
data = await self.generate_fp_by_uid(uid)
|
||||
await self.dbsqla.get_sqla('TEMP').update_user_data(
|
||||
uid, {'fp': data}
|
||||
)
|
||||
return data
|
||||
|
||||
async def get_user_device_id(self, uid: str) -> Optional[str]:
|
||||
data = await self.dbsqla.get_sqla('TEMP').get_user_device_id(uid)
|
||||
if data is None:
|
||||
data = self.get_device_id()
|
||||
await self.dbsqla.get_sqla('TEMP').update_user_data(
|
||||
uid, {'device_id': data}
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
mys_api = _MysApi()
|
||||
|
@ -236,8 +236,16 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
|
||||
if uid is None:
|
||||
uid = '0'
|
||||
|
||||
device_id = mys_api.get_device_id()
|
||||
fp = await mys_api.generate_fp_by_uid(uid)
|
||||
await sqla.insert_user_data(
|
||||
user_id, uid_bind, sr_uid_bind, account_cookie, app_cookie
|
||||
user_id,
|
||||
uid_bind,
|
||||
sr_uid_bind,
|
||||
account_cookie,
|
||||
app_cookie,
|
||||
fp,
|
||||
device_id,
|
||||
)
|
||||
|
||||
im_list.append(
|
||||
|
@ -1,6 +1,5 @@
|
||||
import re
|
||||
import asyncio
|
||||
import contextlib
|
||||
from typing import Dict, List, Literal, Optional
|
||||
|
||||
from sqlmodel import SQLModel
|
||||
@ -43,13 +42,17 @@ class SQLA:
|
||||
'ALTER TABLE GsBind ADD COLUMN sr_uid TEXT',
|
||||
'ALTER TABLE GsUser ADD COLUMN sr_uid TEXT',
|
||||
'ALTER TABLE GsUser ADD COLUMN sr_region TEXT',
|
||||
'ALTER TABLE GsUser ADD COLUMN fp TEXT',
|
||||
'ALTER TABLE GsUser ADD COLUMN device_id TEXT',
|
||||
'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT',
|
||||
]
|
||||
with contextlib.suppress(Exception):
|
||||
async with self.async_session() as session:
|
||||
for _t in exec_list:
|
||||
async with self.async_session() as session:
|
||||
for _t in exec_list:
|
||||
try:
|
||||
await session.execute(text(_t))
|
||||
await session.commit()
|
||||
await session.commit()
|
||||
except: # noqa: E722
|
||||
pass
|
||||
|
||||
#####################
|
||||
# GsBind 部分 #
|
||||
@ -244,6 +247,14 @@ class SQLA:
|
||||
await session.execute(sql)
|
||||
return True
|
||||
|
||||
async def get_user_fp(self, uid: str) -> Optional[str]:
|
||||
data = await self.select_user_data(uid)
|
||||
return data.fp if data else None
|
||||
|
||||
async def get_user_device_id(self, uid: str) -> Optional[str]:
|
||||
data = await self.select_user_data(uid)
|
||||
return data.device_id if data else None
|
||||
|
||||
async def insert_cache_data(
|
||||
self,
|
||||
cookie: str,
|
||||
@ -267,6 +278,8 @@ class SQLA:
|
||||
sr_uid: Optional[str] = None,
|
||||
cookie: Optional[str] = None,
|
||||
stoken: Optional[str] = None,
|
||||
fp: Optional[str] = None,
|
||||
device_id: Optional[str] = None,
|
||||
) -> bool:
|
||||
async with self.async_session() as session:
|
||||
async with session.begin():
|
||||
@ -281,6 +294,7 @@ class SQLA:
|
||||
bot_id=self.bot_id,
|
||||
user_id=user_id,
|
||||
sr_uid=sr_uid,
|
||||
fp=fp,
|
||||
)
|
||||
)
|
||||
await session.execute(sql)
|
||||
@ -295,6 +309,7 @@ class SQLA:
|
||||
bot_id=self.bot_id,
|
||||
user_id=user_id,
|
||||
uid=uid,
|
||||
fp=fp,
|
||||
)
|
||||
)
|
||||
await session.execute(sql)
|
||||
@ -321,6 +336,8 @@ class SQLA:
|
||||
sr_region=SR_SERVER.get(sr_uid[0], None)
|
||||
if sr_uid
|
||||
else None,
|
||||
fp=fp,
|
||||
device_id=device_id,
|
||||
)
|
||||
session.add(user_data)
|
||||
await session.commit()
|
||||
@ -330,13 +347,9 @@ class SQLA:
|
||||
async with self.async_session() as session:
|
||||
async with session.begin():
|
||||
sql = (
|
||||
update(GsUser).where(
|
||||
GsUser.sr_uid == uid, GsUser.bot_id == self.bot_id
|
||||
)
|
||||
update(GsUser).where(GsUser.sr_uid == uid)
|
||||
if self.is_sr
|
||||
else update(GsUser).where(
|
||||
GsUser.uid == uid, GsUser.bot_id == self.bot_id
|
||||
)
|
||||
else update(GsUser).where(GsUser.uid == uid)
|
||||
)
|
||||
if data is not None:
|
||||
query = sql.values(**data)
|
||||
|
@ -29,6 +29,8 @@ class GsUser(SQLModel, table=True):
|
||||
sign_switch: str = Field(title='自动签到')
|
||||
bbs_switch: str = Field(title='自动米游币')
|
||||
status: Optional[str] = Field(default=None, title='状态')
|
||||
fp: Optional[str] = Field(default=None, title='Fingerprint')
|
||||
device_id: Optional[str] = Field(default=None, title='设备ID')
|
||||
|
||||
|
||||
class GsCache(SQLModel, table=True):
|
||||
|
6
poetry.lock
generated
6
poetry.lock
generated
@ -1486,14 +1486,14 @@ reference = "mirrors"
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
description = "Node.js virtual environment builder"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
|
||||
files = [
|
||||
{file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
|
||||
{file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"},
|
||||
{file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"},
|
||||
{file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
Loading…
x
Reference in New Issue
Block a user