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'
|
RECEIVE_URL = f'{DRAW_BASE_URL}/post_my_draw'
|
||||||
BS_INDEX_URL = f'{DRAW_BASE_URL}/index'
|
BS_INDEX_URL = f'{DRAW_BASE_URL}/index'
|
||||||
|
|
||||||
|
GET_FP_URL = 'https://public-data-api.mihoyo.com/device-fp/api/getFp'
|
||||||
|
|
||||||
_API = locals()
|
_API = locals()
|
||||||
|
@ -14,6 +14,7 @@ from typing import Any, Dict, List, Tuple, Union, Literal, Optional, cast
|
|||||||
from aiohttp import TCPConnector, ClientSession, ContentTypeError
|
from aiohttp import TCPConnector, ClientSession, ContentTypeError
|
||||||
|
|
||||||
from gsuid_core.logger import logger
|
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 gsuid_core.utils.plugins_config.gs_config import core_plugins_config
|
||||||
|
|
||||||
from .api import _API
|
from .api import _API
|
||||||
@ -88,6 +89,7 @@ class BaseMysApi:
|
|||||||
is_sr = False
|
is_sr = False
|
||||||
RECOGNIZE_SERVER = RECOGNIZE_SERVER
|
RECOGNIZE_SERVER = RECOGNIZE_SERVER
|
||||||
chs = {}
|
chs = {}
|
||||||
|
dbsqla: DBSqla = DBSqla()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def _upass(self, header: Dict) -> str:
|
async def _upass(self, header: Dict) -> str:
|
||||||
@ -109,6 +111,59 @@ class BaseMysApi:
|
|||||||
async def get_stoken(self, uid: str) -> Optional[str]:
|
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(
|
async def simple_mys_req(
|
||||||
self,
|
self,
|
||||||
URL: str,
|
URL: str,
|
||||||
@ -200,8 +255,15 @@ class BaseMysApi:
|
|||||||
connector=TCPConnector(verify_ssl=ssl_verify)
|
connector=TCPConnector(verify_ssl=ssl_verify)
|
||||||
) as client:
|
) as client:
|
||||||
raw_data = {}
|
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):
|
for _ in range(2):
|
||||||
if 'Cookie' in header and header['Cookie'] in self.chs:
|
if 'Cookie' in header and header['Cookie'] in self.chs:
|
||||||
|
# header['x-rpc-challenge']=self.chs.pop(header['Cookie'])
|
||||||
if self.is_sr:
|
if self.is_sr:
|
||||||
header['x-rpc-challenge'] = self.chs.pop(
|
header['x-rpc-challenge'] = self.chs.pop(
|
||||||
header['Cookie']
|
header['Cookie']
|
||||||
@ -216,6 +278,7 @@ class BaseMysApi:
|
|||||||
header['x-rpc-page'] = (
|
header['x-rpc-page'] = (
|
||||||
'3.1.3_#/rpg' if self.is_sr else '3.1.3_#/ys'
|
'3.1.3_#/rpg' if self.is_sr else '3.1.3_#/ys'
|
||||||
)
|
)
|
||||||
|
|
||||||
async with client.request(
|
async with client.request(
|
||||||
method,
|
method,
|
||||||
url=url,
|
url=url,
|
||||||
@ -244,6 +307,11 @@ class BaseMysApi:
|
|||||||
if retcode == 1034:
|
if retcode == 1034:
|
||||||
ch = await self._upass(header)
|
ch = await self._upass(header)
|
||||||
self.chs[header['Cookie']] = ch
|
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:
|
elif retcode != 0:
|
||||||
return retcode
|
return retcode
|
||||||
else:
|
else:
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Literal, Optional
|
||||||
|
|
||||||
from gsuid_core.utils.api.mys import MysApi
|
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
|
from gsuid_core.utils.plugins_config.gs_config import core_plugins_config
|
||||||
|
|
||||||
gsconfig = core_plugins_config
|
gsconfig = core_plugins_config
|
||||||
|
|
||||||
|
|
||||||
class _MysApi(MysApi):
|
class _MysApi(MysApi):
|
||||||
dbsqla: DBSqla = DBSqla()
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@ -24,5 +21,23 @@ class _MysApi(MysApi):
|
|||||||
async def get_stoken(self, uid: str) -> Optional[str]:
|
async def get_stoken(self, uid: str) -> Optional[str]:
|
||||||
return await self.dbsqla.get_sqla('TEMP').get_user_stoken(uid)
|
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()
|
mys_api = _MysApi()
|
||||||
|
@ -236,8 +236,16 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
|
|||||||
if uid is None:
|
if uid is None:
|
||||||
uid = '0'
|
uid = '0'
|
||||||
|
|
||||||
|
device_id = mys_api.get_device_id()
|
||||||
|
fp = await mys_api.generate_fp_by_uid(uid)
|
||||||
await sqla.insert_user_data(
|
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(
|
im_list.append(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
import asyncio
|
import asyncio
|
||||||
import contextlib
|
|
||||||
from typing import Dict, List, Literal, Optional
|
from typing import Dict, List, Literal, Optional
|
||||||
|
|
||||||
from sqlmodel import SQLModel
|
from sqlmodel import SQLModel
|
||||||
@ -43,13 +42,17 @@ class SQLA:
|
|||||||
'ALTER TABLE GsBind ADD COLUMN sr_uid TEXT',
|
'ALTER TABLE GsBind ADD COLUMN sr_uid TEXT',
|
||||||
'ALTER TABLE GsUser 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 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',
|
'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT',
|
||||||
]
|
]
|
||||||
with contextlib.suppress(Exception):
|
|
||||||
async with self.async_session() as session:
|
async with self.async_session() as session:
|
||||||
for _t in exec_list:
|
for _t in exec_list:
|
||||||
|
try:
|
||||||
await session.execute(text(_t))
|
await session.execute(text(_t))
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
except: # noqa: E722
|
||||||
|
pass
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# GsBind 部分 #
|
# GsBind 部分 #
|
||||||
@ -244,6 +247,14 @@ class SQLA:
|
|||||||
await session.execute(sql)
|
await session.execute(sql)
|
||||||
return True
|
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(
|
async def insert_cache_data(
|
||||||
self,
|
self,
|
||||||
cookie: str,
|
cookie: str,
|
||||||
@ -267,6 +278,8 @@ class SQLA:
|
|||||||
sr_uid: Optional[str] = None,
|
sr_uid: Optional[str] = None,
|
||||||
cookie: Optional[str] = None,
|
cookie: Optional[str] = None,
|
||||||
stoken: Optional[str] = None,
|
stoken: Optional[str] = None,
|
||||||
|
fp: Optional[str] = None,
|
||||||
|
device_id: Optional[str] = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
async with self.async_session() as session:
|
async with self.async_session() as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
@ -281,6 +294,7 @@ class SQLA:
|
|||||||
bot_id=self.bot_id,
|
bot_id=self.bot_id,
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
sr_uid=sr_uid,
|
sr_uid=sr_uid,
|
||||||
|
fp=fp,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await session.execute(sql)
|
await session.execute(sql)
|
||||||
@ -295,6 +309,7 @@ class SQLA:
|
|||||||
bot_id=self.bot_id,
|
bot_id=self.bot_id,
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
uid=uid,
|
uid=uid,
|
||||||
|
fp=fp,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await session.execute(sql)
|
await session.execute(sql)
|
||||||
@ -321,6 +336,8 @@ class SQLA:
|
|||||||
sr_region=SR_SERVER.get(sr_uid[0], None)
|
sr_region=SR_SERVER.get(sr_uid[0], None)
|
||||||
if sr_uid
|
if sr_uid
|
||||||
else None,
|
else None,
|
||||||
|
fp=fp,
|
||||||
|
device_id=device_id,
|
||||||
)
|
)
|
||||||
session.add(user_data)
|
session.add(user_data)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
@ -330,13 +347,9 @@ class SQLA:
|
|||||||
async with self.async_session() as session:
|
async with self.async_session() as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
sql = (
|
sql = (
|
||||||
update(GsUser).where(
|
update(GsUser).where(GsUser.sr_uid == uid)
|
||||||
GsUser.sr_uid == uid, GsUser.bot_id == self.bot_id
|
|
||||||
)
|
|
||||||
if self.is_sr
|
if self.is_sr
|
||||||
else update(GsUser).where(
|
else update(GsUser).where(GsUser.uid == uid)
|
||||||
GsUser.uid == uid, GsUser.bot_id == self.bot_id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
if data is not None:
|
if data is not None:
|
||||||
query = sql.values(**data)
|
query = sql.values(**data)
|
||||||
|
@ -29,6 +29,8 @@ class GsUser(SQLModel, table=True):
|
|||||||
sign_switch: str = Field(title='自动签到')
|
sign_switch: str = Field(title='自动签到')
|
||||||
bbs_switch: str = Field(title='自动米游币')
|
bbs_switch: str = Field(title='自动米游币')
|
||||||
status: Optional[str] = Field(default=None, 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):
|
class GsCache(SQLModel, table=True):
|
||||||
|
6
poetry.lock
generated
6
poetry.lock
generated
@ -1486,14 +1486,14 @@ reference = "mirrors"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodeenv"
|
name = "nodeenv"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
description = "Node.js virtual environment builder"
|
description = "Node.js virtual environment builder"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
|
||||||
files = [
|
files = [
|
||||||
{file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
|
{file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"},
|
||||||
{file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"},
|
{file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user