feat: add idle reward claim automation
This commit is contained in:
1 parent
48d5f63e36
commit
8479cf4981
12 files changed
+228
-12
No files matched your search
@@ -5,16 +5,24 @@
|
|||||||
## 已实现
|
## 已实现
|
||||||
|
|
||||||
- 桌面界面:主屏幕截图、框选游戏内容区域、流程预览、执行日志与停止。
|
- 桌面界面:主屏幕截图、框选游戏内容区域、流程预览、执行日志与停止。
|
||||||
- 小金猪流程:首页识别 → 打开挂机奖励 → 检查标题和领取按钮 → 点击领取一次 → 等待按钮变化 → 关闭弹框 → 确认回到首页。
|
- 小金猪流程:首页识别 → 打开挂机奖励 → 仅在金色领取按钮出现时长按领取 → 确认奖励弹框与灰色按钮 → 关闭弹框并回到首页。
|
||||||
- 脚本与识别模板分离,后续任务通过 `workflows/` 扩展。
|
- 脚本与识别模板分离,后续任务通过 `workflows/` 扩展。
|
||||||
- 截图像素与鼠标坐标分别换算,覆盖主屏幕 Retina 缩放的坐标情况。
|
- 截图像素与鼠标坐标分别换算,覆盖主屏幕 Retina 缩放的坐标情况。
|
||||||
|
|
||||||
小金猪流程只领取挂机奖励,不执行消耗体力的快速扫荡。完成日志只表示已点击领取、按钮变化并返回首页,奖励实际到账仍需首次运行时人工核对。当前模板来自用户提供的界面截图,尚需实机验证。
|
小金猪流程只领取挂机奖励,不执行消耗体力的快速扫荡。已于 2026-10-04 实机验证:领取后出现“恭喜获得”弹框、按钮变灰、挂机计时重置,并确认返回首页。灰色领取按钮时脚本不会点击领取。
|
||||||
|
|
||||||
红点规则:按钮右上角有红点表示其内部有奖励可领取。后续入口任务可以据此进入,但领取成功还需验证内部状态。当前第一条小金猪流程不依赖红点,红点检测尚未实现。
|
红点规则:按钮右上角有红点表示其内部有奖励可领取。后续入口任务可以据此进入,但领取成功还需验证内部状态。当前第一条小金猪流程不依赖红点,红点检测尚未实现。
|
||||||
|
|
||||||
## 本地启动
|
## 本地启动
|
||||||
|
|
||||||
|
### 已验证的小金猪挂机奖励脚本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python claim_idle.py
|
||||||
|
```
|
||||||
|
|
||||||
|
流程为:首页 → 小金猪 → 判断右侧领取按钮。金色时长按领取,确认“恭喜获得”弹框和领取按钮变灰后关闭;灰色时不领取,直接关闭弹框。两种情况都会返回首页。使用 `--dry-run` 可只验证首页而不点击。
|
||||||
|
|
||||||
### 已验证的特惠一键领取脚本
|
### 已验证的特惠一键领取脚本
|
||||||
|
|
||||||
在首页执行:
|
在首页执行:
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -87,7 +87,7 @@ class Desktop:
|
|||||||
def screenshot(self):
|
def screenshot(self):
|
||||||
return self.api.screenshot()
|
return self.api.screenshot()
|
||||||
|
|
||||||
def click(self, point, region, screenshot_size):
|
def click(self, point, region, screenshot_size, hold=0.2):
|
||||||
from .permissions import mouse_permission_granted
|
from .permissions import mouse_permission_granted
|
||||||
if not mouse_permission_granted():
|
if not mouse_permission_granted():
|
||||||
raise WorkflowError(
|
raise WorkflowError(
|
||||||
@@ -100,7 +100,7 @@ class Desktop:
|
|||||||
self.api.mouseDown()
|
self.api.mouseDown()
|
||||||
try:
|
try:
|
||||||
# The game did not react to instant down/up in the live test.
|
# The game did not react to instant down/up in the live test.
|
||||||
time.sleep(0.2)
|
time.sleep(hold)
|
||||||
finally:
|
finally:
|
||||||
# Always release, including if the pointer moved to a failsafe
|
# Always release, including if the pointer moved to a failsafe
|
||||||
# corner during the hold. Restore the guard immediately afterward.
|
# corner during the hold. Restore the guard immediately afterward.
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
"""首页小金猪挂机奖励领取流程。"""
|
||||||
|
import time
|
||||||
|
|
||||||
|
from .engine import WorkflowError
|
||||||
|
|
||||||
|
|
||||||
|
class IdleRunner:
|
||||||
|
def __init__(self, desktop, matcher, flow, region_provider, log=print, timeout=12):
|
||||||
|
self.desktop = desktop
|
||||||
|
self.matcher = matcher
|
||||||
|
self.flow = flow
|
||||||
|
self.region_provider = region_provider
|
||||||
|
self.log = log
|
||||||
|
self.timeout = timeout
|
||||||
|
|
||||||
|
def wait(self, *names):
|
||||||
|
deadline = time.monotonic() + self.timeout
|
||||||
|
previous, stable = None, 0
|
||||||
|
while time.monotonic() < deadline:
|
||||||
|
screenshot = self.desktop.screenshot()
|
||||||
|
region = self.region_provider(screenshot)
|
||||||
|
frame = self.matcher.frame(screenshot, region)
|
||||||
|
found = next((name for name in names
|
||||||
|
if self.matcher.matches(frame, self.flow['states'][name])), None)
|
||||||
|
stable = stable + 1 if found and found == previous else 1 if found else 0
|
||||||
|
previous = found
|
||||||
|
if stable >= 2:
|
||||||
|
return found, screenshot, region
|
||||||
|
time.sleep(0.25)
|
||||||
|
raise WorkflowError('未识别到预期页面 ' + '/'.join(names) + ',已停止。')
|
||||||
|
|
||||||
|
def click(self, action, observation, hold=0.2):
|
||||||
|
_, screenshot, region = observation
|
||||||
|
if self.region_provider(screenshot) != region:
|
||||||
|
raise WorkflowError('识别后游戏窗口移动,已停止,请重新运行。')
|
||||||
|
self.desktop.click(self.flow['clicks'][action], region, screenshot.size, hold=hold)
|
||||||
|
self.log('已执行:' + action)
|
||||||
|
|
||||||
|
def close(self, idle):
|
||||||
|
self.click('close', idle)
|
||||||
|
self.wait('home')
|
||||||
|
self.log('已确认返回首页。')
|
||||||
|
|
||||||
|
def run(self, dry_run=False):
|
||||||
|
home = self.wait('home')
|
||||||
|
if dry_run:
|
||||||
|
self.log('首页识别通过。计划:小金猪 → 检查领取按钮 → 可领取时领取 → 关闭弹框。未点击。')
|
||||||
|
return 'preview'
|
||||||
|
|
||||||
|
self.click('open_pig', home)
|
||||||
|
idle = self.wait('available', 'claimed')
|
||||||
|
if idle[0] == 'claimed':
|
||||||
|
self.log('领取按钮为灰色,本次没有可领取挂机奖励。')
|
||||||
|
self.close(idle)
|
||||||
|
return 'no_reward'
|
||||||
|
|
||||||
|
# A 0.8-second press was required by the live WeChat game window.
|
||||||
|
self.click('claim', idle, hold=0.8)
|
||||||
|
reward = self.wait('reward')
|
||||||
|
self.log('已确认“恭喜获得”挂机奖励弹框。')
|
||||||
|
self.click('dismiss_reward', reward)
|
||||||
|
claimed = self.wait('claimed')
|
||||||
|
self.log('已确认领取按钮变灰。')
|
||||||
|
self.close(claimed)
|
||||||
|
return 'claimed'
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
"""Run from the project root: python claim_idle.py [--dry-run]."""
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from automation.engine import Matcher, WorkflowError, load_flow
|
||||||
|
from automation.idle import IdleRunner
|
||||||
|
from automation.offers import MacGameDesktop
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='首页小金猪:领取挂机奖励并关闭弹框')
|
||||||
|
parser.add_argument('--dry-run', action='store_true', help='只验证首页并显示计划,不点击')
|
||||||
|
args = parser.parse_args()
|
||||||
|
if sys.platform != 'darwin':
|
||||||
|
print('当前脚本已验证 macOS;Windows 版将在校准入口完成后接入。', file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
try:
|
||||||
|
desktop = MacGameDesktop()
|
||||||
|
desktop.activate()
|
||||||
|
print('3 秒后开始;请保持游戏在前台。鼠标移到主屏幕左上角可紧急停止。', flush=True)
|
||||||
|
time.sleep(3)
|
||||||
|
runner = IdleRunner(desktop, Matcher(ROOT / 'assets'),
|
||||||
|
load_flow(ROOT / 'workflows/idle_claim.json'), desktop.region_for)
|
||||||
|
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())
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
created_at: 2026-10-04 16:07:56 CST
|
created_at: 2026-10-04 16:07:56 CST
|
||||||
type: 永远的蔚蓝星球首页、商城、领地与公会入口、日常任务与自动化适配记录
|
type: 永远的蔚蓝星球首页、商城、领地与公会入口、日常任务与自动化适配记录
|
||||||
revision: 第10次
|
revision: 第11次
|
||||||
revisions:
|
revisions:
|
||||||
- time: 2026-10-04 16:07:56 CST
|
- time: 2026-10-04 16:07:56 CST
|
||||||
version: 第1次
|
version: 第1次
|
||||||
@@ -43,7 +43,11 @@ revisions:
|
|||||||
version: 第10次
|
version: 第10次
|
||||||
author: gpt-5
|
author: gpt-5
|
||||||
content: 补充食堂一键领取体力的实机验证流程、无可领取分支、脚本和汇总表条目。
|
content: 补充食堂一键领取体力的实机验证流程、无可领取分支、脚本和汇总表条目。
|
||||||
summary: 记录首页、商城、领地和公会的日常任务入口、待完善流程及已实现脚本汇总。入口红点表示内部有奖励可领取;特惠赏金战令领取、狂鼠之家收矿与雇佣、食堂领体力均已实机验证并写成脚本。
|
- time: 2026-10-04 18:48:40 CST
|
||||||
|
version: 第11次
|
||||||
|
author: gpt-5
|
||||||
|
content: 补充小金猪挂机奖励的实机领取与灰色跳过分支,新增独立脚本及汇总表条目。
|
||||||
|
summary: 记录首页、商城、领地和公会的日常任务入口、待完善流程及已实现脚本汇总。入口红点表示内部有奖励可领取;特惠赏金战令领取、小金猪挂机奖励、狂鼠之家收矿与雇佣、食堂领体力均已实机验证并写成脚本。
|
||||||
---
|
---
|
||||||
|
|
||||||
# 首页、商城、领地与公会功能及日常任务梳理
|
# 首页、商城、领地与公会功能及日常任务梳理
|
||||||
@@ -62,7 +66,7 @@ summary: 记录首页、商城、领地和公会的日常任务入口、待完
|
|||||||
|
|
||||||
用户确定的开发顺序:**先在本地实现部分自动化流程,逐项验证后再打包成独立程序**,最终目标仍是 macOS 与 Windows。模型 Key 由用户以后在程序设置中填写。
|
用户确定的开发顺序:**先在本地实现部分自动化流程,逐项验证后再打包成独立程序**,最终目标仍是 macOS 与 Windows。模型 Key 由用户以后在程序设置中填写。
|
||||||
|
|
||||||
第一条本地原型流程为“小金猪 → 挂机奖励 → 领取 → 返回首页”,使用局部截图模板识别,执行前校准游戏区域,提供预览、日志和停止功能。当前不执行快速扫荡,也尚未加入红点检测或模型 API。奖励到账数量、领取后弹框和双平台操作需实机验证;超时停止,不重复领取。启动方法与验证命令见项目 README。
|
小金猪、特惠战令、狂鼠之家、食堂均已有实机验证脚本,使用局部截图模板识别并在关键状态变化后确认结果。当前不执行快速扫荡,也尚未加入红点检测或模型 API。Windows 双平台操作仍需实机验证;页面不匹配或超时会停止,不重复领取。启动方法与验证命令见项目 README。
|
||||||
|
|
||||||
## 首页
|
## 首页
|
||||||
|
|
||||||
@@ -118,12 +122,22 @@ summary: 记录首页、商城、领地和公会的日常任务入口、待完
|
|||||||
| 点击小金猪 | 打开挂机奖励弹框 | 不同窗口大小下的识别方式 |
|
| 点击小金猪 | 打开挂机奖励弹框 | 不同窗口大小下的识别方式 |
|
||||||
| 查看挂机奖励 | 当前截图提示“已达到最长时间”,最大挂机 12 小时 | 未满 12 小时时的显示、领取后的计时变化 |
|
| 查看挂机奖励 | 当前截图提示“已达到最长时间”,最大挂机 12 小时 | 未满 12 小时时的显示、领取后的计时变化 |
|
||||||
| 快速扫荡 | 按钮标注消耗 10 体力 | 每日次数、后续次数的消耗、确认弹框、奖励与完成状态 |
|
| 快速扫荡 | 按钮标注消耗 10 体力 | 每日次数、后续次数的消耗、确认弹框、奖励与完成状态 |
|
||||||
| 领取 | 可领取挂机奖励,按钮未显示消耗 | 实际领取结果、是否有二次确认、领取成功标志 |
|
| 领取 | 金色按钮时可领取挂机奖励,按钮未显示消耗;灰色时不可领取 | 领取频率和跨日重置规律 |
|
||||||
| 点击空白处关闭 | 截图底部明确显示该提示 | 关闭后是否稳定回到首页 |
|
| 点击空白处关闭 | 截图底部明确显示该提示 | 关闭后是否稳定回到首页 |
|
||||||
|
|
||||||
“快速扫荡”和“领取”应作为两个独立操作记录。前者有明确的体力消耗,后续自动化需要可配置是否执行及次数;后者仍需实际走查确认成功判定。
|
“快速扫荡”和“领取”应作为两个独立操作记录。前者有明确的体力消耗,后续自动化需要可配置是否执行及次数;后者仍需实际走查确认成功判定。
|
||||||
|
|
||||||
建议走查路径:**首页 → 小金猪 → 挂机奖励 → 查看领取条件 → 执行指定操作 → 确认奖励结果 → 返回首页**。目前仅确认入口和弹框,不代表已完成领取验证。
|
### 小金猪挂机奖励领取(已实机验证)
|
||||||
|
|
||||||
|
2026-10-04 已在当前账号完成:**首页 → 小金猪 → 右侧领取 → 恭喜获得弹框 → 领取按钮变灰 → 关闭弹框 → 首页**。领取前挂机时间已达最长 12 小时;领取后按钮变灰,挂机时间重置为 00:00:00,随后开始重新累积。实机观察到钻石从 2392 变为 2423、金币从 49964 变为 56626。
|
||||||
|
|
||||||
|
对应脚本为项目根目录的 `claim_idle.py`,配置在 `workflows/idle_claim.json`。运行方式:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python claim_idle.py
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本仅在右侧领取按钮识别为金色时执行 0.8 秒长按;必须识别“恭喜获得”弹框和变灰按钮才判定成功。按钮已灰时跳过领取,直接关闭弹框并回到首页。左侧“快速扫荡”消耗体力,不在脚本范围内。
|
||||||
|
|
||||||
### 主界面其他可见内容
|
### 主界面其他可见内容
|
||||||
|
|
||||||
@@ -247,7 +261,7 @@ summary: 记录首页、商城、领地和公会的日常任务入口、待完
|
|||||||
| 观影、寻宝 | 先识别活动是否出现,再执行固定流程 | 活动不一定存在,但用户确认出现后的流程稳定 |
|
| 观影、寻宝 | 先识别活动是否出现,再执行固定流程 | 活动不一定存在,但用户确认出现后的流程稳定 |
|
||||||
| 试炼、三类冲刺 | 共用流程,并为不同页面设置识别规则;必要时由 AI 辅助判断 | 基本逻辑一致,页面外观或活动条件会变化 |
|
| 试炼、三类冲刺 | 共用流程,并为不同页面设置识别规则;必要时由 AI 辅助判断 | 基本逻辑一致,页面外观或活动条件会变化 |
|
||||||
| 金沙游记等左上角大活动、英雄集结 | 先识别活动名称与分活动,再逐项评估 | 活动名称、数量和内部结构可能变化,当前缺少完整流程 |
|
| 金沙游记等左上角大活动、英雄集结 | 先识别活动名称与分活动,再逐项评估 | 活动名称、数量和内部结构可能变化,当前缺少完整流程 |
|
||||||
| 小金猪挂机奖励 | 固定流程与结果识别;快速扫荡另设资源配置 | 入口和弹框清晰,但领取与体力消耗操作需要区分 |
|
| 小金猪挂机奖励 | 已验证脚本:金色领取按钮时领取、验证奖励弹框与灰色按钮、返回首页 | 不执行快速扫荡;领取频率和 Windows 适配待验证 |
|
||||||
| 任务、好友、邮件、返利 | 暂不确定 | 尚未查看内部内容和日常规则 |
|
| 任务、好友、邮件、返利 | 暂不确定 | 尚未查看内部内容和日常规则 |
|
||||||
| 商城:英雄招募、图腾寻宝、每日商店、金币 | 后续确定 | 已记录区域结构,日常目标、执行次数、资源消耗与完成判定尚未明确 |
|
| 商城:英雄招募、图腾寻宝、每日商店、金币 | 后续确定 | 已记录区域结构,日常目标、执行次数、资源消耗与完成判定尚未明确 |
|
||||||
| 商城:关卡礼包、钻石 | 暂不处理 | 用户明确排除 |
|
| 商城:关卡礼包、钻石 | 暂不处理 | 用户明确排除 |
|
||||||
@@ -280,5 +294,6 @@ summary: 记录首页、商城、领地和公会的日常任务入口、待完
|
|||||||
| 序号 | 脚本名字 | 入口页面 | 入口位置 | 实现功能简介 | 脚本更新时间 |
|
| 序号 | 脚本名字 | 入口页面 | 入口位置 | 实现功能简介 | 脚本更新时间 |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 1 | 战令领取(`claim_offer.py`) | 首页 | 首页 → 左侧特惠 → 战令 | 识别“超值月卡”时先切换战令;领取赏金战令奖励,确认奖励弹框和按钮变灰后返回首页;已领取时跳过。 | 2026-10-04 17:45 CST |
|
| 1 | 战令领取(`claim_offer.py`) | 首页 | 首页 → 左侧特惠 → 战令 | 识别“超值月卡”时先切换战令;领取赏金战令奖励,确认奖励弹框和按钮变灰后返回首页;已领取时跳过。 | 2026-10-04 17:45 CST |
|
||||||
| 2 | 收矿与雇佣(`claim_mining.py`) | 领地 | 首页 → 底部领地 → 狂鼠之家 | 发现“一键收矿”后收矿、关闭奖励弹框、等待 10 秒;按白银罗盘、黄金罗盘、彩虹探测仪顺序一键雇佣,无可用道具时关闭弹框,最后返回首页。 | 2026-10-04 18:17 CST |
|
| 2 | 挂机奖励领取(`claim_idle.py`) | 首页 | 首页 → 小金猪 | 仅在右侧领取按钮为金色时长按领取,确认“恭喜获得”弹框和按钮变灰后关闭;灰色时跳过,最终返回首页。 | 2026-10-04 18:48 CST |
|
||||||
| 3 | 领体力(`claim_stamina.py`) | 领地 | 首页 → 底部领地 → 食堂 | 发现“一键领取”时领取体力,确认“恭喜获得”弹框和烤肉库存 0/60 后返回首页;无可领体力时跳过。 | 2026-10-04 18:32 CST |
|
| 3 | 收矿与雇佣(`claim_mining.py`) | 领地 | 首页 → 底部领地 → 狂鼠之家 | 发现“一键收矿”后收矿、关闭奖励弹框、等待 10 秒;按白银罗盘、黄金罗盘、彩虹探测仪顺序一键雇佣,无可用道具时关闭弹框,最后返回首页。 | 2026-10-04 18:17 CST |
|
||||||
|
| 4 | 领体力(`claim_stamina.py`) | 领地 | 首页 → 底部领地 → 食堂 | 发现“一键领取”时领取体力,确认“恭喜获得”弹框和烤肉库存 0/60 后返回首页;无可领体力时跳过。 | 2026-10-04 18:32 CST |
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
from automation.engine import Matcher, Region, load_flow
|
||||||
|
from automation.idle import IdleRunner
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
class IdleDesktop:
|
||||||
|
def __init__(self, images):
|
||||||
|
self.images = images
|
||||||
|
self.index = 0
|
||||||
|
self.clicks = []
|
||||||
|
|
||||||
|
def screenshot(self):
|
||||||
|
return self.images[min(self.index, len(self.images) - 1)]
|
||||||
|
|
||||||
|
def click(self, point, region, size, hold=0.2):
|
||||||
|
self.clicks.append((point, hold))
|
||||||
|
self.index += 1
|
||||||
|
|
||||||
|
|
||||||
|
class IdleTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.flow = load_flow(ROOT / 'workflows/idle_claim.json')
|
||||||
|
self.matcher = Matcher(ROOT / 'assets')
|
||||||
|
self.region = Region(0, 0, 562, 1002)
|
||||||
|
|
||||||
|
def image(self, state):
|
||||||
|
image = Image.new('RGB', (562, 1002), (42, 58, 73))
|
||||||
|
for spec in self.flow['states'][state]:
|
||||||
|
template = Image.open(ROOT / 'assets' / spec['template']).convert('RGB')
|
||||||
|
x, y, _, _ = spec['search']
|
||||||
|
image.paste(template, (x + 5, y + 5))
|
||||||
|
return image
|
||||||
|
|
||||||
|
def runner(self, states):
|
||||||
|
desktop = IdleDesktop([self.image(state) for state in states])
|
||||||
|
return desktop, IdleRunner(desktop, self.matcher, self.flow,
|
||||||
|
lambda _: self.region, log=lambda _: None, timeout=0.8)
|
||||||
|
|
||||||
|
def test_claims_reward_with_long_press_and_returns_home(self):
|
||||||
|
desktop, runner = self.runner(['home', 'available', 'reward', 'claimed', 'home'])
|
||||||
|
self.assertEqual(runner.run(), 'claimed')
|
||||||
|
self.assertEqual(desktop.clicks, [
|
||||||
|
(self.flow['clicks']['open_pig'], 0.2),
|
||||||
|
(self.flow['clicks']['claim'], 0.8),
|
||||||
|
(self.flow['clicks']['dismiss_reward'], 0.2),
|
||||||
|
(self.flow['clicks']['close'], 0.2),
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_grey_button_skips_claim_and_returns_home(self):
|
||||||
|
desktop, runner = self.runner(['home', 'claimed', 'home'])
|
||||||
|
self.assertEqual(runner.run(), 'no_reward')
|
||||||
|
self.assertEqual(desktop.clicks, [
|
||||||
|
(self.flow['clicks']['open_pig'], 0.2),
|
||||||
|
(self.flow['clicks']['close'], 0.2),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "小金猪挂机奖励领取",
|
||||||
|
"states": {
|
||||||
|
"home": [{"template": "home.png", "search": [150, 730, 410, 865]}],
|
||||||
|
"available": [
|
||||||
|
{"template": "idle_dialog_title.png", "search": [170, 260, 400, 380]},
|
||||||
|
{"template": "idle_claim_available.png", "search": [270, 645, 535, 825]}
|
||||||
|
],
|
||||||
|
"claimed": [
|
||||||
|
{"template": "idle_dialog_title.png", "search": [170, 260, 400, 380]},
|
||||||
|
{"template": "idle_claimed.png", "search": [270, 645, 535, 825]}
|
||||||
|
],
|
||||||
|
"reward": [
|
||||||
|
{"template": "idle_reward.png", "search": [120, 220, 440, 370], "threshold": 0.8},
|
||||||
|
{"template": "idle_dismiss.png", "search": [145, 610, 420, 730]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clicks": {
|
||||||
|
"open_pig": [0.135, 0.607],
|
||||||
|
"claim": [0.72, 0.73],
|
||||||
|
"dismiss_reward": [0.50, 0.67],
|
||||||
|
"close": [0.50, 0.94]
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user