"""Run from the project root: python claim_offer.py [--dry-run].""" import argparse import json import sys import time from pathlib import Path from automation.engine import Desktop, Matcher, Region, WorkflowError, load_flow from automation.offers import MacGameDesktop, OfferRunner ROOT = Path(__file__).resolve().parent def main(): parser = argparse.ArgumentParser(description='首页 → 特惠战令 → 一键领取 → 返回首页') parser.add_argument('--dry-run', action='store_true', help='只验证首页并显示计划,不点击') parser.add_argument('--region', nargs=4, type=int, metavar=('X', 'Y', 'WIDTH', 'HEIGHT'), help='游戏内容区域在主屏幕截图中的像素坐标,不含标题栏') args = parser.parse_args() try: if sys.platform == 'darwin' and not args.region: desktop = MacGameDesktop() provider = desktop.region_for if not args.dry_run: desktop.activate() else: desktop = Desktop() if args.region: region = Region(*args.region) else: config = ROOT / 'local/region.json' if not config.is_file(): raise WorkflowError('请先用 main.py 校准游戏区域,或提供 --region。') region = Region(**json.loads(config.read_text(encoding='utf-8'))) provider = lambda screenshot: region print('3 秒后开始;请保持游戏在前台。鼠标移到主屏幕左上角可紧急停止。', flush=True) time.sleep(3) runner = OfferRunner(desktop, Matcher(ROOT / 'assets'), load_flow(ROOT / 'workflows/offer_claim.json'), provider) runner.run(args.dry_run) return 0 except KeyboardInterrupt: print('已停止。', file=sys.stderr) return 130 except Exception as exc: print('流程停止:' + str(exc), file=sys.stderr) return 1 if __name__ == '__main__': raise SystemExit(main())