v0 plus附加功能
- 新增 unlockmusic.py:解锁(解禁)歌曲 + 解禁 Master / Re:Master 难度,整个流程复用 upsert.py 的 run() - 买票前置闸门 api/ChargeGuard.py:必须先跑过 GetUserCharge,且同进程只允许买一次 - buy_ticket.py 票源改为 GetUserCharge,不再调用 GetGameCharge - UpsertUserAll 与买票的冷却统一为 15 秒 - api/ 文件名统一 PascalCase(文件名 = 函数名) - 项目改名 Astral,README 加 Logo、鸣谢与开发者说明 - 自检 284 项
This commit is contained in:
@@ -29,9 +29,12 @@ upsert.py —— 主脚本:扫码登录 → 上传成绩 → 登出
|
||||
python upsert.py <二维码> # 预检:登录 + 抓快照 + 组包,不发包
|
||||
python upsert.py <二维码> --send # 真实上传成绩(★ 有副作用,不可撤销)
|
||||
python upsert.py <二维码> --send --debug # 同上,日志里带完整收发报文
|
||||
python upsert.py <二维码> --send --cooldown 0 # 跳过发包前的 60 秒冷却
|
||||
python upsert.py <二维码> --send --cooldown 0 # 跳过发包前的 15 秒冷却
|
||||
python upsert.py <二维码> --send --no-verify # 跳过上传后的落库回查
|
||||
|
||||
# ★ 解锁(解禁)歌曲请用另一个主脚本(它复用本脚本的整套流程)
|
||||
python unlockmusic.py <二维码> --send --music 11414
|
||||
|
||||
# ★ 额外塞节点(--extra-data,可重复,后给的覆盖先给的)
|
||||
python upsert.py <二维码> --send --extra-data extra.json
|
||||
python upsert.py <二维码> --send --extra-data '{"isNewMapList":"1"}'
|
||||
@@ -83,6 +86,17 @@ upsert.py —— 主脚本:扫码登录 → 上传成绩 → 登出
|
||||
新增条目请显式传 "1","0" 表示存量更新。
|
||||
★ JSON 在**扫码之前**就校验,写错了直接退出,不会浪费二维码。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
★ 这个文件同时是一个可复用的模块
|
||||
--------------------------------------------------------------------------------
|
||||
`run(opts, ...)` 就是整套流程(扫码 → 预览 → 登录 → UpsertUserAll → 登出),
|
||||
`main()` 只做参数解析然后调它。所以别的主脚本可以直接:
|
||||
|
||||
import upsert
|
||||
sys.exit(upsert.run({"qr": qr, "send": True, ...}, log_name="unlockmusic"))
|
||||
|
||||
unlockmusic.py 就是这么写的 —— 它只多了一个"要解锁哪些歌"的入参。
|
||||
|
||||
── 在代码里直接调 api 的等价写法 ──
|
||||
|
||||
UpsertUserAll(
|
||||
@@ -146,19 +160,24 @@ def parse_args(argv):
|
||||
return opts
|
||||
|
||||
|
||||
def main() -> int:
|
||||
opts = parse_args(sys.argv[1:])
|
||||
if not opts["qr"]:
|
||||
def run(opts, *, unlock_music=None, unlock_master=True, unlock_remaster=True,
|
||||
log_name="upsert") -> int:
|
||||
"""跑完整套流程。upsert.py 自己用,unlockmusic.py 也复用它。
|
||||
|
||||
opts 里必须有的键:qr / send / debug / no_verify / cooldown / extra_data
|
||||
unlock_music / unlock_master / unlock_remaster 三个是解锁用的,upsert.py 不传。
|
||||
"""
|
||||
if not opts.get("qr"):
|
||||
print(__doc__)
|
||||
return 1
|
||||
|
||||
# --debug 只影响本次运行,不改 config.py
|
||||
if opts["debug"]:
|
||||
if opts.get("debug"):
|
||||
import config as _cfg
|
||||
_cfg.LOG_LEVEL = "debug"
|
||||
|
||||
# 日志会话:开头一句。之后每次 api 调用都会自动记录,主脚本不用再写日志
|
||||
setup_logging("upsert")
|
||||
setup_logging(log_name)
|
||||
|
||||
# ---- ★ 先解析 --extra-data(放在扫码之前:JSON 写错就别浪费二维码了)----
|
||||
extra = None
|
||||
@@ -186,6 +205,13 @@ def main() -> int:
|
||||
extra = merged
|
||||
log_info("--extra-data 合计 " + str(len(extra)) + " 个节点:" + ", ".join(extra))
|
||||
|
||||
# ---- 解锁参数校验(同样放在扫码之前)----
|
||||
if unlock_music:
|
||||
log_info("要解锁 " + str(len(unlock_music)) + " 首:"
|
||||
+ ", ".join(str(m) for m in unlock_music)
|
||||
+ "(Master=" + str(unlock_master)
|
||||
+ " / Re:Master=" + str(unlock_remaster) + ")")
|
||||
|
||||
# 会话状态:保证异常时也能登出(否则账号会卡在 isLogin=True,下次登录 returnCode=100)
|
||||
session = {"user_id": 0, "token": "", "login_dt": 0, "logged_in": False}
|
||||
try:
|
||||
@@ -210,6 +236,9 @@ def main() -> int:
|
||||
auth_date_time=login.dateTime,
|
||||
token=token,
|
||||
extra_data=extra,
|
||||
unlock_music_ids=unlock_music or None,
|
||||
unlock_master=unlock_master,
|
||||
unlock_remaster=unlock_remaster,
|
||||
dry_run=not opts["send"],
|
||||
confirm=opts["send"],
|
||||
cooldown_sec=opts["cooldown"],
|
||||
@@ -235,5 +264,9 @@ def main() -> int:
|
||||
teardown_logging()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
return run(parse_args(sys.argv[1:]), log_name="upsert")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
||||
Reference in New Issue
Block a user