type: 收敛测试 schemas 与协议层类型
This commit is contained in:
@@ -75,7 +75,9 @@ def generate_huya_password(prefix: str = "hy", random_length: int = 8) -> str:
|
||||
"""生成适合虎牙账号使用的随机密码。"""
|
||||
clean_prefix = "".join(ch for ch in str(prefix or "hy") if ch.isalnum())[:8] or "hy"
|
||||
alphabet = string.ascii_lowercase + string.digits
|
||||
suffix = "".join(random.SystemRandom().choice(alphabet) for _ in range(max(6, random_length)))
|
||||
suffix = "".join(
|
||||
random.SystemRandom().choice(alphabet) for _ in range(max(6, random_length))
|
||||
)
|
||||
return f"{clean_prefix}{suffix}"
|
||||
|
||||
|
||||
@@ -86,13 +88,15 @@ def encode_change_password_behavior(stage: str) -> str:
|
||||
actions: list[dict] = []
|
||||
|
||||
if stage in {"send", "submit"}:
|
||||
actions.append({
|
||||
"id": "pmodify.btn.getsms",
|
||||
"x": random.randint(470, 520),
|
||||
"y": random.randint(120, 145),
|
||||
"d": elapsed,
|
||||
"time": now,
|
||||
})
|
||||
actions.append(
|
||||
{
|
||||
"id": "pmodify.btn.getsms",
|
||||
"x": random.randint(470, 520),
|
||||
"y": random.randint(120, 145),
|
||||
"d": elapsed,
|
||||
"time": now,
|
||||
}
|
||||
)
|
||||
if stage == "submit":
|
||||
for action_id in ("pmodify.input.sms", "pmodify.input.pw", "pmodify.input.sms"):
|
||||
now += random.randint(600, 3200)
|
||||
@@ -100,20 +104,24 @@ def encode_change_password_behavior(stage: str) -> str:
|
||||
actions.append({"id": action_id, "d": elapsed, "time": now})
|
||||
now += random.randint(800, 2400)
|
||||
elapsed += random.randint(800, 2400)
|
||||
actions.append({
|
||||
"id": "pmodify.btn.submit",
|
||||
"x": random.randint(395, 445),
|
||||
"y": random.randint(220, 245),
|
||||
"d": elapsed,
|
||||
"time": now,
|
||||
})
|
||||
actions.append(
|
||||
{
|
||||
"id": "pmodify.btn.submit",
|
||||
"x": random.randint(395, 445),
|
||||
"y": random.randint(220, 245),
|
||||
"d": elapsed,
|
||||
"time": now,
|
||||
}
|
||||
)
|
||||
|
||||
value = {
|
||||
"furl": CHANGE_PASSWORD_FROM_URL,
|
||||
"curl": CHANGE_PASSWORD_PAGE_URL,
|
||||
"user_action": actions,
|
||||
}
|
||||
return quote(json.dumps(value, separators=(",", ":"), ensure_ascii=False), safe="~()*!.'")
|
||||
return quote(
|
||||
json.dumps(value, separators=(",", ":"), ensure_ascii=False), safe="~()*!.'"
|
||||
)
|
||||
|
||||
|
||||
def _sleep_or_stop(stop_event: threading.Event | None, seconds: float) -> bool:
|
||||
@@ -132,7 +140,13 @@ def _payload_data(payload: dict) -> dict:
|
||||
|
||||
def _session_data(payload: dict, fallback: str = "") -> str:
|
||||
data = _payload_data(payload)
|
||||
return str(data.get("sessionData") or data.get("sessiondata") or payload.get("sessionData") or fallback or "")
|
||||
return str(
|
||||
data.get("sessionData")
|
||||
or data.get("sessiondata")
|
||||
or payload.get("sessionData")
|
||||
or fallback
|
||||
or ""
|
||||
)
|
||||
|
||||
|
||||
class HuyaPasswordChanger:
|
||||
@@ -174,23 +188,25 @@ class HuyaPasswordChanger:
|
||||
self._setup_headers()
|
||||
|
||||
def _setup_headers(self) -> None:
|
||||
self.session.headers.update({
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9",
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"Origin": "https://udbreg.huya.com",
|
||||
"Pragma": "no-cache",
|
||||
"Referer": self.middle_url,
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-origin",
|
||||
"User-Agent": self.ua,
|
||||
"sec-ch-ua": '"Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"',
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": '"macOS"',
|
||||
})
|
||||
self.session.headers.update(
|
||||
{
|
||||
"Accept": "application/json, text/plain, */*",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9",
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"Origin": "https://udbreg.huya.com",
|
||||
"Pragma": "no-cache",
|
||||
"Referer": self.middle_url,
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-origin",
|
||||
"User-Agent": self.ua,
|
||||
"sec-ch-ua": '"Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"',
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": '"macOS"',
|
||||
}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _safe_url(url: str) -> str:
|
||||
@@ -199,7 +215,9 @@ class HuyaPasswordChanger:
|
||||
|
||||
def _request_json(self, method: str, url: str, source: str, **kwargs) -> dict:
|
||||
response = self.session.request(method, url, timeout=self.timeout, **kwargs)
|
||||
logger.debug(f"{method.upper()} {self._safe_url(url)} -> {response.status_code}")
|
||||
logger.debug(
|
||||
f"{method.upper()} {self._safe_url(url)} -> {response.status_code}"
|
||||
)
|
||||
response.raise_for_status()
|
||||
try:
|
||||
return response.json()
|
||||
@@ -216,20 +234,26 @@ class HuyaPasswordChanger:
|
||||
logger.debug(f"GET {self._safe_url(url)} -> {response.status_code}")
|
||||
except requests.RequestException as exc:
|
||||
logger.debug(f"虎牙改密 middle 初始化失败: {host}: {exc}")
|
||||
self.session.headers.update({
|
||||
"Origin": "https://udbreg.huya.com",
|
||||
"Referer": self.middle_url,
|
||||
})
|
||||
self.session.headers.update(
|
||||
{
|
||||
"Origin": "https://udbreg.huya.com",
|
||||
"Referer": self.middle_url,
|
||||
}
|
||||
)
|
||||
|
||||
def prepare_device(self) -> str:
|
||||
"""获取虎牙风控 sdid。"""
|
||||
token_payload = {"encryptVersion": "1.0.1", "fingerprintVersion": "1.2.41"}
|
||||
token_res = self._request_json("post", DF_TOKEN_URL, "获取虎牙 df token", json=token_payload)
|
||||
token_res = self._request_json(
|
||||
"post", DF_TOKEN_URL, "获取虎牙 df token", json=token_payload
|
||||
)
|
||||
token = token_res.get("data", {}).get("token")
|
||||
if not token:
|
||||
raise HuyaLoginError(f"获取虎牙 df token 失败: {token_res}")
|
||||
|
||||
collect_res = self._request_json("post", DF_COLLECT_URL, "获取虎牙 sdid", json={"token": token})
|
||||
collect_res = self._request_json(
|
||||
"post", DF_COLLECT_URL, "获取虎牙 sdid", json={"token": token}
|
||||
)
|
||||
self.sdid = collect_res.get("data", {}).get("sdid", "")
|
||||
if not self.sdid:
|
||||
raise HuyaLoginError(f"获取虎牙 sdid 失败: {collect_res}")
|
||||
@@ -240,7 +264,11 @@ class HuyaPasswordChanger:
|
||||
from .verification import HuyaVerificationSolver
|
||||
|
||||
solver = HuyaVerificationSolver(
|
||||
cookie=self.session.cookies.get_dict(),
|
||||
cookie={
|
||||
key: value
|
||||
for key, value in self.session.cookies.get_dict().items()
|
||||
if value is not None
|
||||
},
|
||||
ua=self.ua,
|
||||
sdid=self.sdid,
|
||||
session=self.session,
|
||||
@@ -402,12 +430,16 @@ class HuyaPasswordChanger:
|
||||
request_id=self.request_id,
|
||||
)
|
||||
|
||||
def submit_code(self, password: str, sms_code: str, session_data: str) -> HuyaChangePasswordResult:
|
||||
def submit_code(
|
||||
self, password: str, sms_code: str, session_data: str
|
||||
) -> HuyaChangePasswordResult:
|
||||
"""提交改密短信验证码。"""
|
||||
if not session_data:
|
||||
raise HuyaLoginError("缺少改密 sessionData,请先发送改密短信")
|
||||
|
||||
payload = self._submit_once(password=password, sms_code=sms_code, session_data=session_data)
|
||||
payload = self._submit_once(
|
||||
password=password, sms_code=sms_code, session_data=session_data
|
||||
)
|
||||
for index in range(3):
|
||||
return_code = int(payload.get("returnCode") or 0)
|
||||
if return_code == 0:
|
||||
@@ -436,7 +468,9 @@ class HuyaPasswordChanger:
|
||||
logger.info(f"虎牙短信改密触发风控: {return_code} ({index + 1}/3)")
|
||||
self._solve_verification(payload)
|
||||
time.sleep(0.5)
|
||||
payload = self._submit_once(password=password, sms_code=sms_code, session_data=session_data)
|
||||
payload = self._submit_once(
|
||||
password=password, sms_code=sms_code, session_data=session_data
|
||||
)
|
||||
|
||||
return HuyaChangePasswordResult(
|
||||
success=False,
|
||||
|
||||
Reference in New Issue
Block a user