feat: add mining collection automation
No files matched your search
@@ -33,6 +33,16 @@
|
|||||||
|
|
||||||
当前仅适配本次“赏金战令”领取,支持从“超值月卡”切换到“战令”,不会购买战令或遍历其他特惠标签。无法识别的页面样式或标签会使流程停止。macOS 自动读取已打开游戏窗口位置,每次识别重新定位,识别后窗口移动则停止;窗口标题栏高度按本次验证的 44 逻辑点处理,需收起微信侧栏。运行时保持游戏完整可见。Windows 使用 `main.py` 已校准的区域或 `--region X Y WIDTH HEIGHT`,实机尚未验证。
|
当前仅适配本次“赏金战令”领取,支持从“超值月卡”切换到“战令”,不会购买战令或遍历其他特惠标签。无法识别的页面样式或标签会使流程停止。macOS 自动读取已打开游戏窗口位置,每次识别重新定位,识别后窗口移动则停止;窗口标题栏高度按本次验证的 44 逻辑点处理,需收起微信侧栏。运行时保持游戏完整可见。Windows 使用 `main.py` 已校准的区域或 `--region X Y WIDTH HEIGHT`,实机尚未验证。
|
||||||
|
|
||||||
|
### 已验证的狂鼠之家收矿脚本
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python claim_mining.py
|
||||||
|
```
|
||||||
|
|
||||||
|
流程为:首页 → 领地 → 狂鼠之家 → 发现“一键收矿”时收矿 → 关闭奖励弹框 → 等待 10 秒 → 一键雇佣。雇佣弹框按白银罗盘、黄金罗盘、彩虹探测仪的顺序选择第一个可用项;三者均不可用时关闭弹框。最后返回首页。
|
||||||
|
|
||||||
|
已在 2026-10-04 实机验证收矿、10 秒等待、白银罗盘雇佣和返回首页。找不到“一键收矿”时,脚本不雇佣并直接返回首页。使用 `--dry-run` 可只验证首页而不点击。
|
||||||
|
|
||||||
需要 Python 3.9 或更新版本,以及带 Tk 支持的 Python。macOS 若当前 Python 缺少 Tk,可使用 python.org 官方安装包。
|
需要 Python 3.9 或更新版本,以及带 Tk 支持的 Python。macOS 若当前 Python 缺少 Tk,可使用 python.org 官方安装包。
|
||||||
|
|
||||||
macOS:
|
macOS:
|
||||||
|
|||||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,87 @@
|
|||||||
|
"""狂鼠之家收矿与雇佣流程。"""
|
||||||
|
import time
|
||||||
|
|
||||||
|
from .engine import WorkflowError
|
||||||
|
|
||||||
|
|
||||||
|
class MiningRunner:
|
||||||
|
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, timeout=None):
|
||||||
|
deadline = time.monotonic() + (timeout or 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):
|
||||||
|
_, screenshot, region = observation
|
||||||
|
if self.region_provider(screenshot) != region:
|
||||||
|
raise WorkflowError('识别后游戏窗口移动,已停止,请重新运行。')
|
||||||
|
self.desktop.click(self.flow['clicks'][action], region, screenshot.size)
|
||||||
|
self.log('已执行:' + action)
|
||||||
|
|
||||||
|
def pause(self, seconds):
|
||||||
|
self.log('等待 %s 秒后执行一键雇佣。' % seconds)
|
||||||
|
time.sleep(seconds)
|
||||||
|
|
||||||
|
def run(self, dry_run=False):
|
||||||
|
home = self.wait('home')
|
||||||
|
if dry_run:
|
||||||
|
self.log('首页识别通过。计划:领地 → 狂鼠之家 → 收矿 → 等待 10 秒 → 雇佣 → 返回首页。未点击。')
|
||||||
|
return 'preview'
|
||||||
|
|
||||||
|
self.click('territory', home)
|
||||||
|
territory = self.wait('territory')
|
||||||
|
self.click('rat_house', territory)
|
||||||
|
rat = self.wait('collect', 'rat_house')
|
||||||
|
if rat[0] == 'rat_house':
|
||||||
|
self.log('未发现一键收矿,本次不执行雇佣。')
|
||||||
|
self.click('rat_back', rat)
|
||||||
|
self.click('territory_back', self.wait('territory'))
|
||||||
|
self.wait('home')
|
||||||
|
self.log('已确认返回首页。')
|
||||||
|
return 'no_collection'
|
||||||
|
self.click('collect', rat)
|
||||||
|
reward = self.wait('reward')
|
||||||
|
self.log('已确认收矿奖励弹框。')
|
||||||
|
self.click('dismiss_reward', reward)
|
||||||
|
self.pause(self.flow['wait_after_collect_seconds'])
|
||||||
|
# This position is only used after a verified collection result was
|
||||||
|
# dismissed, when the button changes from 一键收矿 to 一键雇佣.
|
||||||
|
self.click('hire_open', self.wait('rat_house'))
|
||||||
|
dialog = self.wait('white_compass', 'gold_compass', 'rainbow_detector', 'hire_dialog')
|
||||||
|
if dialog[0] == 'hire_dialog':
|
||||||
|
self.log('没有可用罗盘或探测仪,关闭雇佣弹框。')
|
||||||
|
self.click('close_dialog', dialog)
|
||||||
|
else:
|
||||||
|
priority = {
|
||||||
|
'white_compass': 'select_white',
|
||||||
|
'gold_compass': 'select_gold',
|
||||||
|
'rainbow_detector': 'select_rainbow',
|
||||||
|
}
|
||||||
|
self.click(priority[dialog[0]], dialog)
|
||||||
|
self.click('hire_confirm', self.wait('hire_dialog'))
|
||||||
|
self.wait('rat_house')
|
||||||
|
self.log('已完成一键雇佣。')
|
||||||
|
|
||||||
|
self.click('rat_back', self.wait('rat_house'))
|
||||||
|
self.click('territory_back', self.wait('territory'))
|
||||||
|
self.wait('home')
|
||||||
|
self.log('收矿流程完成,已确认返回首页。')
|
||||||
|
return 'completed'
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"""Run from the project root: python claim_mining.py [--dry-run]."""
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from automation.engine import Matcher, WorkflowError, load_flow
|
||||||
|
from automation.mining import MiningRunner
|
||||||
|
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()
|
||||||
|
# Focusing the empty WeChat title area prevents the first capture from
|
||||||
|
# observing another foreground surface. It does not touch game content.
|
||||||
|
desktop.activate()
|
||||||
|
print('3 秒后开始;请保持游戏在前台。鼠标移到主屏幕左上角可紧急停止。', flush=True)
|
||||||
|
time.sleep(3)
|
||||||
|
runner = MiningRunner(desktop, Matcher(ROOT / 'assets'),
|
||||||
|
load_flow(ROOT / 'workflows/mining_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: 第7次
|
revision: 第8次
|
||||||
revisions:
|
revisions:
|
||||||
- time: 2026-10-04 16:07:56 CST
|
- time: 2026-10-04 16:07:56 CST
|
||||||
version: 第1次
|
version: 第1次
|
||||||
@@ -31,7 +31,11 @@ revisions:
|
|||||||
version: 第7次
|
version: 第7次
|
||||||
author: GPT-6
|
author: GPT-6
|
||||||
content: 实机完成特惠赏金战令一键领取及返回首页,新增脚本、奖励结果和已领取状态的识别逻辑。
|
content: 实机完成特惠赏金战令一键领取及返回首页,新增脚本、奖励结果和已领取状态的识别逻辑。
|
||||||
summary: 记录首页、商城、领地和公会的日常任务入口及待完善流程。入口红点表示内部有奖励可领取。特惠赏金战令一键领取已实机验证并写成脚本;开发先验证本地流程,再打包独立程序,商城关卡礼包和钻石暂不处理。
|
- time: 2026-10-04 18:17:58 CST
|
||||||
|
version: 第8次
|
||||||
|
author: gpt-5
|
||||||
|
content: 补充狂鼠之家一键收矿与优先罗盘雇佣的实机验证流程、脚本、无可收矿分支和测试状态。
|
||||||
|
summary: 记录首页、商城、领地和公会的日常任务入口及待完善流程。入口红点表示内部有奖励可领取。特惠赏金战令领取、狂鼠之家收矿与优先罗盘雇佣均已实机验证并写成脚本;开发先验证本地流程,再打包独立程序,商城关卡礼包和钻石暂不处理。
|
||||||
---
|
---
|
||||||
|
|
||||||
# 首页、商城、领地与公会功能及日常任务梳理
|
# 首页、商城、领地与公会功能及日常任务梳理
|
||||||
@@ -157,7 +161,7 @@ summary: 记录首页、商城、领地和公会的日常任务入口及待完
|
|||||||
|
|
||||||
| 栏目 | 截图中的大致位置 | 自动化流程状态 |
|
| 栏目 | 截图中的大致位置 | 自动化流程状态 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 狂鼠之家 | 左侧中下部,矿洞建筑 | 用户确认有固定流程,具体步骤待补充 |
|
| 狂鼠之家 | 左侧中下部,矿洞建筑 | 一键收矿与优先罗盘一键雇佣已实机验证并有脚本;其他内部功能待补充 |
|
||||||
| 玩法大厅 | 下方偏左,带喇叭的建筑 | 用户确认有固定流程,具体步骤待补充 |
|
| 玩法大厅 | 下方偏左,带喇叭的建筑 | 用户确认有固定流程,具体步骤待补充 |
|
||||||
| 图鉴 | 下方偏右,书本建筑 | 用户确认有固定流程,具体步骤待补充 |
|
| 图鉴 | 下方偏右,书本建筑 | 用户确认有固定流程,具体步骤待补充 |
|
||||||
| 食堂 | 中部,带食物的建筑 | 用户确认有固定流程,具体步骤待补充 |
|
| 食堂 | 中部,带食物的建筑 | 用户确认有固定流程,具体步骤待补充 |
|
||||||
@@ -174,6 +178,20 @@ summary: 记录首页、商城、领地和公会的日常任务入口及待完
|
|||||||
|
|
||||||
后续逐栏目补充日常目标、进入与返回路径、操作顺序、执行次数、奖励领取、资源消耗,以及已完成、条件不足等状态的识别方式。目前尚未确认任一栏目的内部按钮和完成标志,也未据此确定脚本或 AI 的具体实现方式。
|
后续逐栏目补充日常目标、进入与返回路径、操作顺序、执行次数、奖励领取、资源消耗,以及已完成、条件不足等状态的识别方式。目前尚未确认任一栏目的内部按钮和完成标志,也未据此确定脚本或 AI 的具体实现方式。
|
||||||
|
|
||||||
|
### 狂鼠之家:一键收矿与一键雇佣(已实机验证)
|
||||||
|
|
||||||
|
2026-10-04 已在当前账号完成:**首页 → 领地 → 狂鼠之家 → 一键收矿 → 确认收矿奖励弹框 → 关闭弹框 → 等待 10 秒 → 一键雇佣 → 返回首页**。本次收矿获得 930 矿石;雇佣弹框中白银罗盘数量为 59,脚本优先选择白银罗盘并完成一键雇佣,完成后数量变为 53。
|
||||||
|
|
||||||
|
对应脚本为项目根目录的 `claim_mining.py`,配置在 `workflows/mining_claim.json`。运行方式:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python claim_mining.py
|
||||||
|
```
|
||||||
|
|
||||||
|
脚本仅在识别到“一键收矿”时收矿,识别奖励弹框后才关闭;随后严格等待 10 秒。雇佣弹框按 **白银罗盘 → 黄金罗盘 → 彩虹探测仪** 的优先级选择第一个可用项,三者均不可用时关闭弹框。若未发现“一键收矿”,本次跳过雇佣并返回首页。每次关键点击前后都会识别页面状态;不匹配、超时或窗口移动时停止,不重复执行不确定的领取操作。
|
||||||
|
|
||||||
|
该流程使用截图模板识别与相对坐标点击,macOS 已实机验证;Windows 仍需在对应环境校准并验证。可使用 `--dry-run` 只检查首页和执行计划,不点击游戏内容。
|
||||||
|
|
||||||
## 公会页面
|
## 公会页面
|
||||||
|
|
||||||
### 入口与栏目
|
### 入口与栏目
|
||||||
@@ -213,7 +231,8 @@ summary: 记录首页、商城、领地和公会的日常任务入口及待完
|
|||||||
| 任务、好友、邮件、返利 | 暂不确定 | 尚未查看内部内容和日常规则 |
|
| 任务、好友、邮件、返利 | 暂不确定 | 尚未查看内部内容和日常规则 |
|
||||||
| 商城:英雄招募、图腾寻宝、每日商店、金币 | 后续确定 | 已记录区域结构,日常目标、执行次数、资源消耗与完成判定尚未明确 |
|
| 商城:英雄招募、图腾寻宝、每日商店、金币 | 后续确定 | 已记录区域结构,日常目标、执行次数、资源消耗与完成判定尚未明确 |
|
||||||
| 商城:关卡礼包、钻石 | 暂不处理 | 用户明确排除 |
|
| 商城:关卡礼包、钻石 | 暂不处理 | 用户明确排除 |
|
||||||
| 领地:狂鼠之家、玩法大厅、图鉴、食堂、排行榜、巅峰决斗、合作模式、城墙 | 待完善固定流程后确定 | 用户确认八个栏目均有固定自动化流程,具体步骤、执行条件、消耗和完成判定尚未补充 |
|
| 领地:狂鼠之家 | 已验证脚本:一键收矿、等待 10 秒、按白银/黄金/彩虹顺序一键雇佣、返回首页 | 当前仅覆盖该日常流程;其他内部功能、重置规律和 Windows 适配待验证 |
|
||||||
|
| 领地:玩法大厅、图鉴、食堂、排行榜、巅峰决斗、合作模式、城墙 | 待完善固定流程后确定 | 用户确认各栏目均有固定自动化流程,具体步骤、执行条件、消耗和完成判定尚未补充 |
|
||||||
| 公会:公会商城、远征大厅、公会任务、公会祝福、每日捐献、成员大厅、公会 Boss、右下角红色角色入口 | 待完善固定流程后确定 | 用户确认八个入口均有固定自动化流程;右下角入口名称及各流程的具体步骤、消耗和完成判定待补充 |
|
| 公会:公会商城、远征大厅、公会任务、公会祝福、每日捐献、成员大厅、公会 Boss、右下角红色角色入口 | 待完善固定流程后确定 | 用户确认八个入口均有固定自动化流程;右下角入口名称及各流程的具体步骤、消耗和完成判定待补充 |
|
||||||
|
|
||||||
初步方向是让脚本执行已验证的重复步骤,让 AI 辅助识别变化页面或异常。是否每次调用 AI、调用到哪一步,待明确任务完成标志与变化范围后再决定。
|
初步方向是让脚本执行已验证的重复步骤,让 AI 辅助识别变化页面或异常。是否每次调用 AI、调用到哪一步,待明确任务完成标志与变化范围后再决定。
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import copy
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
from automation.engine import Matcher, Region, load_flow
|
||||||
|
from automation.mining import MiningRunner
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
class MiningDesktop:
|
||||||
|
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):
|
||||||
|
self.clicks.append(point)
|
||||||
|
self.index += 1
|
||||||
|
|
||||||
|
|
||||||
|
class MiningTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.flow = load_flow(ROOT / 'workflows/mining_claim.json')
|
||||||
|
self.flow['wait_after_collect_seconds'] = 0
|
||||||
|
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 = MiningDesktop([self.image(state) for state in states])
|
||||||
|
return desktop, MiningRunner(desktop, self.matcher, copy.deepcopy(self.flow),
|
||||||
|
lambda _: self.region, log=lambda _: None, timeout=0.8)
|
||||||
|
|
||||||
|
def test_white_compass_is_selected_first(self):
|
||||||
|
desktop, runner = self.runner([
|
||||||
|
'home', 'territory', 'collect', 'reward', 'rat_house',
|
||||||
|
'white_compass', 'hire_dialog', 'rat_house', 'territory', 'home',
|
||||||
|
])
|
||||||
|
self.assertEqual(runner.run(), 'completed')
|
||||||
|
expected = ('territory', 'rat_house', 'collect', 'dismiss_reward', 'hire_open',
|
||||||
|
'select_white', 'hire_confirm', 'rat_back', 'territory_back')
|
||||||
|
self.assertEqual(desktop.clicks, [self.flow['clicks'][name] for name in expected])
|
||||||
|
|
||||||
|
def test_no_collect_skips_hiring_and_returns(self):
|
||||||
|
desktop, runner = self.runner(['home', 'territory', 'rat_house', 'territory', 'home'])
|
||||||
|
self.assertEqual(runner.run(), 'no_collection')
|
||||||
|
expected = ('territory', 'rat_house', 'rat_back', 'territory_back')
|
||||||
|
self.assertEqual(desktop.clicks, [self.flow['clicks'][name] for name in expected])
|
||||||
|
|
||||||
|
def test_no_compass_closes_dialog(self):
|
||||||
|
desktop, runner = self.runner([
|
||||||
|
'home', 'territory', 'collect', 'reward', 'rat_house',
|
||||||
|
'hire_dialog', 'rat_house', 'territory', 'home',
|
||||||
|
])
|
||||||
|
self.assertEqual(runner.run(), 'completed')
|
||||||
|
self.assertIn(self.flow['clicks']['close_dialog'], desktop.clicks)
|
||||||
|
self.assertNotIn(self.flow['clicks']['hire_confirm'], desktop.clicks)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "狂鼠之家一键收矿与雇佣",
|
||||||
|
"wait_after_collect_seconds": 10,
|
||||||
|
"states": {
|
||||||
|
"home": [{"template": "home.png", "search": [150, 730, 410, 865]}],
|
||||||
|
"territory": [{"template": "territory_rat_house.png", "search": [15, 440, 220, 570]}],
|
||||||
|
"rat_house": [{"template": "rat_house_page.png", "search": [315, 80, 550, 235]}],
|
||||||
|
"collect": [{"template": "rat_collect.png", "search": [195, 760, 370, 925]}],
|
||||||
|
"reward": [
|
||||||
|
{"template": "rat_reward.png", "search": [120, 220, 440, 370], "threshold": 0.8},
|
||||||
|
{"template": "rat_dismiss.png", "search": [145, 610, 420, 730]}
|
||||||
|
],
|
||||||
|
"hire_dialog": [{"template": "rat_hire_dialog.png", "search": [135, 220, 430, 360]}],
|
||||||
|
"white_compass": [
|
||||||
|
{"template": "rat_hire_dialog.png", "search": [135, 220, 430, 360]},
|
||||||
|
{"template": "rat_white_compass.png", "search": [35, 340, 235, 565]}
|
||||||
|
],
|
||||||
|
"gold_compass": [
|
||||||
|
{"template": "rat_hire_dialog.png", "search": [135, 220, 430, 360]},
|
||||||
|
{"template": "rat_gold_compass.png", "search": [185, 340, 375, 565]}
|
||||||
|
],
|
||||||
|
"rainbow_detector": [
|
||||||
|
{"template": "rat_hire_dialog.png", "search": [135, 220, 430, 360]},
|
||||||
|
{"template": "rat_rainbow_detector.png", "search": [320, 340, 530, 565]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clicks": {
|
||||||
|
"territory": [0.68, 0.94],
|
||||||
|
"rat_house": [0.20, 0.52],
|
||||||
|
"collect": [0.50, 0.858],
|
||||||
|
"dismiss_reward": [0.50, 0.67],
|
||||||
|
"hire_open": [0.50, 0.858],
|
||||||
|
"select_white": [0.285, 0.43],
|
||||||
|
"select_gold": [0.50, 0.43],
|
||||||
|
"select_rainbow": [0.72, 0.43],
|
||||||
|
"hire_confirm": [0.50, 0.595],
|
||||||
|
"close_dialog": [0.905, 0.293],
|
||||||
|
"rat_back": [0.12, 0.94],
|
||||||
|
"territory_back": [0.68, 0.94]
|
||||||
|
}
|
||||||
|
}
|
||||||