diff --git a/assets/planet_card.png b/assets/planet_card.png new file mode 100644 index 0000000..69fb1cd Binary files /dev/null and b/assets/planet_card.png differ diff --git a/assets/planet_dismiss.png b/assets/planet_dismiss.png new file mode 100644 index 0000000..d4cba09 Binary files /dev/null and b/assets/planet_dismiss.png differ diff --git a/assets/planet_progress_button.png b/assets/planet_progress_button.png new file mode 100644 index 0000000..b6a83de Binary files /dev/null and b/assets/planet_progress_button.png differ diff --git a/assets/planet_progress_title.png b/assets/planet_progress_title.png new file mode 100644 index 0000000..b824022 Binary files /dev/null and b/assets/planet_progress_title.png differ diff --git a/assets/planet_rank_title.png b/assets/planet_rank_title.png new file mode 100644 index 0000000..dd4c4e3 Binary files /dev/null and b/assets/planet_rank_title.png differ diff --git a/assets/planet_reward.png b/assets/planet_reward.png new file mode 100644 index 0000000..c707473 Binary files /dev/null and b/assets/planet_reward.png differ diff --git a/assets/planet_sweep.png b/assets/planet_sweep.png new file mode 100644 index 0000000..193a8f6 Binary files /dev/null and b/assets/planet_sweep.png differ diff --git a/assets/planet_sweep_dialog.png b/assets/planet_sweep_dialog.png new file mode 100644 index 0000000..7304bee Binary files /dev/null and b/assets/planet_sweep_dialog.png differ diff --git a/assets/planet_sweep_up.png b/assets/planet_sweep_up.png new file mode 100644 index 0000000..1cb6234 Binary files /dev/null and b/assets/planet_sweep_up.png differ diff --git a/assets/planet_title.png b/assets/planet_title.png new file mode 100644 index 0000000..892b66b Binary files /dev/null and b/assets/planet_title.png differ diff --git a/assets/play_hall_title.png b/assets/play_hall_title.png new file mode 100644 index 0000000..e9a965b Binary files /dev/null and b/assets/play_hall_title.png differ diff --git a/automation/planet_mine.py b/automation/planet_mine.py new file mode 100644 index 0000000..f4a6edf --- /dev/null +++ b/automation/planet_mine.py @@ -0,0 +1,35 @@ +"""玩法大厅星球矿场:排行榜奖励与扫荡上一层。""" +import time +from .engine import WorkflowError +class PlanetMineRunner: + def __init__(self,desktop,matcher,flow,region_provider,log=print,timeout=12):self.desktop,self.matcher,self.flow=desktop,matcher,flow;self.region_provider,self.log,self.timeout=region_provider,log,timeout + def wait(self,*names): + end=time.monotonic()+self.timeout;prev=None;stable=0 + while time.monotonic()=2:return found,shot,region,frame + time.sleep(.25) + raise WorkflowError('未识别到预期页面 '+ '/'.join(names)+',已停止。') + def action(self,name,obs): + _,shot,region,_=obs + if self.region_provider(shot)!=region:raise WorkflowError('识别后游戏窗口移动,已停止,请重新运行。') + self.desktop.click(self.flow['clicks'][name],region,shot.size,hold=.8);self.log('已执行:'+name) + def dot(self,frame,spec):return self.matcher.score(frame,self.flow[spec])>=self.flow[spec].get('threshold',.86) + def return_home(self,planet): + self.action('planet_back',planet);self.action('hall_close',self.wait('hall'));self.action('territory_back',self.wait('territory'));self.wait('home');self.log('已确认返回首页。') + def run(self,dry_run=False): + home=self.wait('home') + if dry_run:self.log('首页识别通过。计划:领地 → 玩法大厅 → 星球矿场 → 排行榜奖励与扫荡 → 返回首页。未点击。');return 'preview' + self.action('territory',home);self.action('hall',self.wait('territory'));self.action('planet',self.wait('hall'));planet=self.wait('planet') + if self.dot(planet[3],'rank_dot'): + self.action('rank',planet);rank=self.wait('rank');self.action('progress',rank);dialog=self.wait('progress_dialog') + spec=self.flow['progress_claim'];score,loc=self.matcher.locate(dialog[3],spec) + if score>=spec.get('threshold',.86): + x,y,w,h=loc;self.action('progress_claim',('x',dialog[1],dialog[2],dialog[3])) if False else self.desktop.click(((x+w/2)/562,(y+h/2)/1002),dialog[2],dialog[1].size,hold=.8) + reward=self.wait('reward');self.action('dismiss_reward',reward) + self.action('progress_close',self.wait('progress_dialog'));self.action('rank_back',self.wait('rank'));planet=self.wait('planet') + count=0 + while count<2 and self.matcher.matches(planet[3],self.flow['states']['sweep_available']): + self.action('sweep',planet);dialog=self.wait('sweep_dialog');self.action('sweep_up',dialog);reward=self.wait('reward');self.action('dismiss_reward',reward);planet=self.wait('planet');count+=1;self.log('已完成第 %s 次扫荡。'%count) + self.return_home(planet);return 'claimed' diff --git a/claim_planet_mine.py b/claim_planet_mine.py new file mode 100644 index 0000000..a5be66b --- /dev/null +++ b/claim_planet_mine.py @@ -0,0 +1,13 @@ +import argparse,sys,time +from pathlib import Path +from automation.engine import Matcher,load_flow +from automation.offers import MacGameDesktop +from automation.planet_mine import PlanetMineRunner +ROOT=Path(__file__).resolve().parent +def main(): + p=argparse.ArgumentParser(description='星球矿场:领取排行榜奖励并扫荡');p.add_argument('--dry-run',action='store_true');a=p.parse_args() + if sys.platform!='darwin':return 2 + try: + d=MacGameDesktop();d.activate();print('3 秒后开始;请保持游戏在前台。',flush=True);time.sleep(3);PlanetMineRunner(d,Matcher(ROOT/'assets'),load_flow(ROOT/'workflows/planet_mine.json'),d.region_for).run(a.dry_run);return 0 + except Exception as e:print('流程停止:'+str(e),file=sys.stderr);return 1 +if __name__=='__main__':raise SystemExit(main()) diff --git a/workflows/planet_mine.json b/workflows/planet_mine.json new file mode 100644 index 0000000..fd6503a --- /dev/null +++ b/workflows/planet_mine.json @@ -0,0 +1 @@ +{"name":"星球矿场收金币","states":{"home":[{"template":"home.png","search":[150,730,410,865]}],"territory":[{"template":"territory_rat_house.png","search":[15,440,220,570]}],"hall":[{"template":"play_hall_title.png","search":[140,140,420,260]}],"planet":[{"template":"planet_title.png","search":[150,35,420,140]}],"rank":[{"template":"planet_rank_title.png","search":[150,20,420,130]}],"progress_dialog":[{"template":"planet_progress_title.png","search":[140,70,420,190]}],"sweep_available":[{"template":"planet_title.png","search":[150,35,420,140]},{"template":"planet_sweep.png","search":[45,750,280,890]}],"sweep_dialog":[{"template":"planet_sweep_dialog.png","search":[150,250,410,390]},{"template":"planet_sweep_up.png","search":[270,560,520,710]}],"reward":[{"template":"planet_reward.png","search":[120,180,440,390],"threshold":0.8},{"template":"planet_dismiss.png","search":[145,600,420,730]}]},"rank_dot":{"template":"tasks_home_dot.png","search":[500,110,562,200]},"progress_claim":{"template":"tasks_home_dot.png","search":[380,180,520,360]},"clicks":{"territory":[0.68,0.94],"hall":[0.40,0.67],"planet":[0.50,0.37],"rank":[0.92,0.15],"progress":[0.85,0.81],"progress_close":[0.91,0.13],"rank_back":[0.12,0.94],"sweep":[0.29,0.82],"sweep_up":[0.71,0.63],"dismiss_reward":[0.50,0.67],"planet_back":[0.12,0.94],"hall_close":[0.94,0.19],"territory_back":[0.68,0.94]}}