兼容虎牙四段账号格式
支持虎牙号、密码、手机号、验证码链接导入,并补充美国等国际手机号格式处理。
This commit is contained in:
@@ -351,7 +351,7 @@ def create_auto_register_batch(
|
||||
_require_huya_perm(current, "huya:import")
|
||||
sms_lines = parse_sms_lines(req.text)
|
||||
if not sms_lines:
|
||||
raise HTTPException(status_code=400, detail="没有识别到有效手机号,格式为:手机号----短信查询URL")
|
||||
raise HTTPException(status_code=400, detail="没有识别到有效手机号,格式为:手机号----短信查询URL 或 虎牙号----密码----手机号----短信查询URL")
|
||||
|
||||
proxy_config = db.query(ProxyConfig).first() if req.use_proxy else None
|
||||
runner = huya_register_registry.create(
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
import csv
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -94,8 +96,25 @@ def parse_huya_cookie_line(line: str) -> dict | None:
|
||||
}
|
||||
|
||||
|
||||
def split_huya_password_line(line: str) -> tuple[str, str, str] | None:
|
||||
"""拆分虎牙账号密码行,返回账号、密码、预置 Cookie。"""
|
||||
@dataclass
|
||||
class HuyaPasswordLine:
|
||||
"""虎牙账号密码导入行。"""
|
||||
|
||||
username: str
|
||||
password: str
|
||||
cookie: str = ""
|
||||
phone: str = ""
|
||||
sms_url: str = ""
|
||||
|
||||
|
||||
def _looks_like_url(value: str) -> bool:
|
||||
"""判断文本是否像 URL。"""
|
||||
parsed = urlparse(str(value or "").strip())
|
||||
return parsed.scheme in {"http", "https"} and bool(parsed.netloc)
|
||||
|
||||
|
||||
def split_huya_password_line(line: str) -> HuyaPasswordLine | None:
|
||||
"""拆分虎牙账号密码行,兼容账号----密码----手机号----验证码链接。"""
|
||||
raw = (line or "").strip()
|
||||
if not raw or raw.startswith("#"):
|
||||
return None
|
||||
@@ -116,10 +135,29 @@ def split_huya_password_line(line: str) -> tuple[str, str, str] | None:
|
||||
|
||||
username = parts[0].strip()
|
||||
password = parts[1].strip()
|
||||
cookie = "----".join(part.strip() for part in parts[2:] if part.strip())
|
||||
cookie = ""
|
||||
phone = ""
|
||||
sms_url = ""
|
||||
extra = [part.strip() for part in parts[2:] if part.strip()]
|
||||
if len(extra) >= 2 and _looks_like_url(extra[1]):
|
||||
phone = extra[0]
|
||||
sms_url = extra[1]
|
||||
cookie = "----".join(extra[2:])
|
||||
elif extra and _looks_like_url(extra[-1]) and len(extra) >= 2:
|
||||
phone = extra[-2]
|
||||
sms_url = extra[-1]
|
||||
cookie = "----".join(extra[:-2])
|
||||
elif extra:
|
||||
cookie = "----".join(extra)
|
||||
if not username or not password:
|
||||
return None
|
||||
return username, password, cookie
|
||||
return HuyaPasswordLine(
|
||||
username=username,
|
||||
password=password,
|
||||
cookie=cookie,
|
||||
phone=phone,
|
||||
sms_url=sms_url,
|
||||
)
|
||||
|
||||
|
||||
def import_huya_password_accounts(db: Session, text: str, tag: str = "") -> tuple[int, int]:
|
||||
@@ -135,7 +173,9 @@ def import_huya_password_accounts(db: Session, text: str, tag: str = "") -> tupl
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
username, password, cookie = parsed
|
||||
username = parsed.username
|
||||
password = parsed.password
|
||||
cookie = parsed.cookie
|
||||
account = db.query(HuyaAccount).filter(HuyaAccount.username == username).first()
|
||||
if account is None:
|
||||
account = HuyaAccount(
|
||||
@@ -144,6 +184,7 @@ def import_huya_password_accounts(db: Session, text: str, tag: str = "") -> tupl
|
||||
username=username,
|
||||
account_password=password,
|
||||
cookie=normalize_huya_cookie(cookie) if cookie else "",
|
||||
game_phone=parsed.phone,
|
||||
tag=tag,
|
||||
status="password_imported",
|
||||
)
|
||||
@@ -152,6 +193,8 @@ def import_huya_password_accounts(db: Session, text: str, tag: str = "") -> tupl
|
||||
account.account_password = password
|
||||
if cookie:
|
||||
account.cookie = normalize_huya_cookie(cookie)
|
||||
if parsed.phone:
|
||||
account.game_phone = parsed.phone
|
||||
if tag:
|
||||
account.tag = tag
|
||||
if not account.cookie:
|
||||
|
||||
@@ -716,7 +716,7 @@ export default function HuyaAccountsPage() {
|
||||
rows={10}
|
||||
value={passwordImportText}
|
||||
onChange={(e) => setPasswordImportText(e.target.value)}
|
||||
placeholder="每行一条:账号----密码;如需预置 Cookie:账号----密码----Cookie"
|
||||
placeholder="每行一条:账号----密码;也支持:虎牙号----密码----手机号----验证码链接"
|
||||
disabled={passwordImporting}
|
||||
/>
|
||||
<Select
|
||||
@@ -730,7 +730,7 @@ export default function HuyaAccountsPage() {
|
||||
disabled={passwordImporting}
|
||||
/>
|
||||
<Paragraph type="secondary" style={{ marginBottom: 0 }}>
|
||||
导入后账号会出现在列表里,勾选需要登录的账号再点“登录选中”。
|
||||
四段格式会保存手机号;验证码链接用于接码池兼容,不会写入账号表。
|
||||
</Paragraph>
|
||||
</Space>
|
||||
</Modal>
|
||||
|
||||
@@ -97,12 +97,7 @@ function readStoredBatchId() {
|
||||
}
|
||||
|
||||
export default function HuyaRegisterPage() {
|
||||
const initialFormRef = useRef<StoredRegisterForm | null>(null);
|
||||
if (initialFormRef.current === null) {
|
||||
initialFormRef.current = readStoredForm();
|
||||
}
|
||||
const initialForm = initialFormRef.current;
|
||||
|
||||
const [initialForm] = useState(readStoredForm);
|
||||
const [text, setText] = useState(initialForm.text);
|
||||
const [tag, setTag] = useState(initialForm.tag);
|
||||
const [concurrency, setConcurrency] = useState(initialForm.concurrency);
|
||||
@@ -311,7 +306,7 @@ export default function HuyaRegisterPage() {
|
||||
rows={9}
|
||||
value={text}
|
||||
onChange={(event) => setText(event.target.value)}
|
||||
placeholder="手机号----短信查询URL"
|
||||
placeholder="手机号----短信查询URL;也支持:虎牙号----密码----手机号----验证码链接"
|
||||
disabled={isRunning}
|
||||
/>
|
||||
<Row gutter={[12, 12]}>
|
||||
|
||||
Reference in New Issue
Block a user