def _match_target(self, target: TargetType): """ 探测货物,并搬运货物。 """ # 获取当前屏幕快照 screen = self.d.screenshot(format="opencv") # 由于 OpenCV 的模板匹配有时会智障,故我们探测次数实现冗余。 counter = 5 while counter != 0: counter = counter - 1 # 使用 OpenCV 探测货物。 result = UIMatcher.match(screen, target) # 若无探测到,终止对该货物的探测。 # 实现冗余的原因:返回的货物屏幕位置与实际位置存在偏差,导致移动失效 if result is None: break # 在 trainMode 下设置搬运成果。 if self.trainMode: self.isHarvest = True sx, sy = result # 获取货物目的地的屏幕位置。 ex, ey = self._get_target_position(target) # 搬运货物。 self.d.swipe(sx, sy, ex, ey)
def _match_target(self, target: TargetType): """ 探测货物,并搬运货物。 """ cargoPos = [[660, 1640], [0.771 * 1080, 0.815 * 1920], [0.895 * 1080, 0.77 * 1920]] for cargo in cargoPos: screen = self.d.screenshot(format="opencv") result = UIMatcher.match(screen) if result is None: return # 获取当前屏幕快照 # 由于 OpenCV 的模板匹配有时会智障,故我们探测次数实现冗余。 # 使用 OpenCV 探测货物。 # 若无探测到,终止对该货物的探测。 # 实现冗余的原因:返回的货物屏幕位置与实际位置存在偏差,导致移动失效 for i in range(3): sx, sy = cargo for cnt in range(9): ex, ey = self._get_position(cnt + 1) time.sleep(.3) self.d.swipe(sx, sy, ex, ey)
def _match_target(self, screen, target: TargetType): """ 探测货物,并搬运货物。 """ # 由于 OpenCV 的模板匹配有时会智障,故我们探测次数实现冗余。 counter = 6 logged = False while counter != 0: counter = counter - 1 # 使用 OpenCV 探测货物。 result = UIMatcher.match(screen, target) # 若无探测到,终止对该货物的探测。 # 实现冗余的原因:返回的货物屏幕位置与实际位置存在偏差,导致移动失效 if result is None: break rank = result[-1] result = result[:2] sx, sy = result # 获取货物目的地的屏幕位置。 ex, ey = self._get_target_position(target) if not logged: logger.info(f"Detect {target} at ({sx},{sy}), rank: {rank}") logged = True # 搬运货物。 self.d.swipe(sx, sy, ex, ey) # 侧面反映检测出货物 return logged
def _match_mission(self): screen = my_screenshot_with_cache(self.d, format="opencv") print(screen) result = UIMatcher.match(screen, TargetType.Mission_done) if result is None: return self.d.click(*prop.MISSION_BTN) time.sleep(1) self.d.click(*prop.MISSION_DONE_BTN) time.sleep(1) self.d.click(*prop.MISSION_CLOSE_BTN)
def _match_target(self, target: TargetType, screen): # 探测货物,并搬运货物。 result = UIMatcher.match(screen, target) if result is not None: sx, sy = result # 获取货物目的地的屏幕位置。 ex, ey = self._get_target_position(target) # 搬运货物。 for j in range(2): self.d.swipe(sx, sy, ex, ey) return True return False
def _is_good_to_go(self): """ 检测是否有排行图标来判断是否进入了游戏界面 """ screen = self._safe_screenshot() return UIMatcher.match(screen, TargetType.Rank_btn) is not None
def start(self): """ 启动脚本,请确保已进入游戏页面。 """ tmp_upgrade_last_time = time.time() logger.info("Start Working") while True: # 检查是否有键盘事件 if not self._need_continue(): break # 进入命令模式后不继续执行常规操作 if self.command_mode: continue # 更新配置文件 self.config.refresh() if self.config.debug_mode: logger.info("Debug mode") # 重启游戏法 # self._refresh_train_by_restart() # 重连 wifi 法 # self._refresh_train_by_reconnect() # 是否检测货物 if self.config.detect_goods: logger.info('-' * 30) logger.info("Start matching goods") # 获取当前屏幕快照 screen = self._safe_screenshot() # 判断是否出现货物。 has_goods = False refresh_flag = False for target in self.config.goods_2_building_seq.keys(): has_goods |= self._match_target(screen, target) # 如果需要刷新火车并且已送过目标货物 if has_goods and self.config.refresh_train: refresh_flag = True logger.info("All target goods delivered.") # 如果需要刷新火车并且未送过目标货物 elif self.config.refresh_train: for target in self.config.goods_2_building_seq_excpet_target.keys( ): if UIMatcher.match(screen, target) is not None: has_goods = True break if has_goods: refresh_flag = True logger.info("Train detected with no target goods.") else: logger.info("Train not detected.") if refresh_flag: # 刷新火车 logger.info("Refresh train.") logger.info("-" * 30) self.refresh_times += 1 if not self._refresh_train_by_restart(): # 重启不成功(超时)时中止脚本 logger.warn("Timed out waiting for restart!") break else: logger.info("End matching") # 简单粗暴的方式,处理 “XX之光” 的荣誉显示。 # 当然,也可以使用图像探测的模式。 self.d.click(550, 1650) # 滑动屏幕,收割金币。 logger.info("Collect coins") self._swipe() # 自动升级建筑 tmp_upgrade_interval = time.time() - tmp_upgrade_last_time if tmp_upgrade_interval >= self.config.upgrade_interval_sec: if self.config.upgrade_building is True: self._auto_upgrade_building() tmp_upgrade_last_time = time.time() else: logger.info( f"Left {round(self.config.upgrade_interval_sec - tmp_upgrade_interval, 2)}s to upgrade" ) time.sleep(self.config.swipe_interval_sec) self._print_summary() logger.info('Sub process end')
def _is_good_to_go(self): screen = self.d.screenshot(format="opencv") return UIMatcher.match(screen, TargetType.Rank_btn) is not None
def start(self): """ 启动脚本,请确保已进入游戏页面。 """ tmp_upgrade_last_time = time.time() logger.info("Start Working") while True: # 检查是否有键盘事件 if not self._need_continue(): logger.info('-' * 30) pass_time = time.time() - self.time_start_working logger.info(f"本次启动运行了 {int(pass_time // 3600)} 小时 {int(pass_time % 3600 // 60)} 分钟 {round(pass_time % 60, 2)} 秒") logger.info(f"重启了 {self.refresh_times} 次, 检测到 {self.delivered_times} 次货物(非总送货次数)") break # 进入命令模式后不继续执行常规操作 if self.command_mode: continue # 更新配置文件 self.config.refresh() if self.config.debug_mode: None # 重启游戏法 # self._refresh_train_by_restart() # 重连 wifi 法 # self._refresh_train_by_reconnect() # 是否检测货物 if self.config.detect_goods: logger.info('-' * 30) logger.info("Start matching goods") # 获取当前屏幕快照 screen = self.d.screenshot(format="opencv") # 判断是否出现货物。 has_goods = False refresh_flag = False for target in self.config.goods_2_building_seq.keys(): has_goods |= self._match_target(screen, target) # 如果需要刷新火车并且已送过目标货物 if has_goods and self.config.refresh_train: refresh_flag = True logger.info("All target goods delivered.") # 如果需要刷新火车并且未送过目标货物 elif self.config.refresh_train: for target in self.config.goods_2_building_seq_excpet_target.keys(): if UIMatcher.match(screen, target) is not None: has_goods = True break if has_goods: refresh_flag = True logger.info("Train detected with no target goods.") else: logger.info("Train not detected.") if refresh_flag: # 刷新火车 logger.info("Refresh train.") logger.info("-" * 30) self.refresh_times += 1 self._refresh_train_by_restart() else: logger.info("End matching") # 简单粗暴的方式,处理 “XX之光” 的荣誉显示。 # 当然,也可以使用图像探测的模式。 self.d.click(550, 1650) # 滑动屏幕,收割金币。 # logger.info("swipe") self._swipe() # 升级建筑 tmp_upgrade_interval = time.time() - tmp_upgrade_last_time if tmp_upgrade_interval >= self.config.upgrade_interval_sec: if self.config.upgrade_type_is_assign is True: self._assigned_uprade() else: self._upgrade() tmp_upgrade_last_time = time.time() else: logger.info(f"Left {round(self.config.upgrade_interval_sec - tmp_upgrade_interval, 2)}s to upgrade") time.sleep(self.config.swipe_interval_sec) logger.info('Sub process end')