"""狂鼠之家收矿与雇佣流程。""" 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'