예제 #1
0
    def provoke_enemy(self):
        adb = self.adb
        # 这里要多等待几秒, 因为经常会有个动画影响寻敌
        time.sleep(3)

        if PageUtils.in_stage_page():  # 关卡已经结束
            return False

        # 弹药为空且当前是第一队时切换队伍
        if self.current_team_num == 1 and adb.check(
                'temp_images/stage/bullet-empty.png'):
            self.switch()

        # 页面滑动工具类
        slider = Slider()
        # 敌人的模板列表
        image_rel_path_list = PathUtils.get_temp_rel_path_list(
            'temp_images/enemy')
        while True:
            print('寻找敌人 ... ')
            enemy_loc = adb.get_location(*image_rel_path_list)
            if enemy_loc is None:
                # 有时没找到敌人是已经进入确认界面了
                if adb.check('temp_images/fight/fight.png'):
                    return True
                # 滑动界面寻找敌人
                slider.slide()
                continue

            # 如果当前是第一队, 且找到的是boss, 则切换到第二队开始寻找敌人
            if self.current_team_num == 1 and 'boss' in enemy_loc.temp_rel_path:
                self.switch()
                continue

            # 有时敌人离状态栏太近,这时加大Y轴
            if enemy_loc.pos_y < 65:
                enemy_loc.pos_y = 65
            # 点击敌人位置
            enemy_loc.click()
            # 等待进击按钮出现, 期间会不断处理意外情况, 如果指定时间内出现按钮, 则执行结束, 否则再次循环
            res = adb.wait('temp_images/fight/fight.png',
                           max_wait_time=8,
                           episode=self.accident_when_run).is_valuable()
            if res:
                return True
            else:
                # 如果点击后未进入确认界面, 说明那里不可到达, 此时去除image_rel_path_list中的值
                image_rel_path_list.remove(enemy_loc.temp_rel_path)
                # 如果list为空了,则恢复到原有列表
                if len(image_rel_path_list) == 0:
                    image_rel_path_list = PathUtils.get_temp_rel_path_list(
                        'temp_images/enemy')
예제 #2
0
def run():
    StageFight.wind_up_stage_fight()

    adb = AutoAdb(test_device=True)
    temp_list = PathUtils.get_temp_rel_path_list(
        'temp_images/target-stage-hard')
    while True:
        # 如果发现次数为0,则终止
        if adb.click('temp_images/stage/no-chance-for-hard.png'):
            print('困难关卡机会已用尽,程序终止')
            break
        StageFight.fight_stage(temp_list)
    print('困难关卡已经结束')
예제 #3
0
def run():
    # 计数
    num = 0
    # 最大通关次数
    max_stage_fight_times = int(ConfigUtils.get('max_stage_fight_times'))
    # 循环战斗
    while True:
        # 选择关卡 开始战斗
        target_stage_list = PathUtils.get_temp_rel_path_list('temp_images/target-stage')
        StageFight.fight_stage(target_stage_list)
        # 计数
        num += 1
        print('通关次数累计:%d' % num, end='\n\n')
        if max_stage_fight_times is not None and num >= max_stage_fight_times:
            print('已达最大通关次数 %d,结束运行' % max_stage_fight_times)
            exit()
예제 #4
0
    def __init__(self):
        # 读取配置文件
        config_file = PathUtils.get_work_dir() + '/config.ini'
        if not os.path.isfile(config_file):
            print(
                '配置文件 config.ini 不存在,请将程序根目录的 config_temp.ini 文件拷贝一份并命名为 config.ini。注意要自行调整其中的配置项。'
            )
            exit(1)
        if not os.access(config_file, os.R_OK):
            print(
                '配置文件 config.ini 不可读,请将程序根目录的 config_temp.ini 文件拷贝一份并命名为 config.ini。注意要自行调整其中的配置项。'
            )
            exit(1)

        cp = ConfigParser()
        cp.read(config_file, encoding='utf-8')
        self._cp = cp
예제 #5
0
    def get_location(self, *temp_rel_path_list, threshold=threshold):
        self.screen_cap()
        sp_gray = cv2.imread(self.screen_pic_path, cv2.COLOR_BGR2BGRA)

        for temp_rel_path in temp_rel_path_list:
            temp_abs_path = PathUtils.get_abs_path(temp_rel_path)
            temp_gray = cv2.imread(temp_abs_path, cv2.COLOR_BGR2BGRA)

            res = cv2.matchTemplate(sp_gray, temp_gray, cv2.TM_CCOEFF_NORMED)
            _, max_val, _, max_loc = cv2.minMaxLoc(res)
            if max_val < threshold:
                continue

            h, w, _ = cv2.imread(temp_abs_path).shape
            x = max_loc[0] + w / 2
            y = max_loc[1] + h / 2
            return Location(self, temp_rel_path, x, y)
        return None
예제 #6
0
def run():
    # 计数
    fight_recorder = FightRecorder()
    # 最大通关次数
    max_stage_fight_times = int(ConfigUtils.get('max_stage_fight_times'))
    # 循环战斗
    while True:
        # 选择关卡 开始战斗
        target_stage_list = PathUtils.get_temp_rel_path_list('temp_images/target-stage')
        fight_result = StageFight.fight_stage(target_stage_list)
        # 计数
        fight_recorder.append(fight_result)
        fight_recorder.print_recorder()
        # 连续失败两次就停止战斗
        if fight_recorder.get_last_fail_count() >= 2:
            print('连续 2 次关卡战斗失败, 为了避免更多损失脚本自动退出')
            exit()
        if max_stage_fight_times is not None and fight_recorder.get_total_count() >= max_stage_fight_times:
            print('已达最大通关次数 %d,结束运行' % max_stage_fight_times)
            exit()
예제 #7
0
 def __init__(self, test_device=False):
     self.adb_path = PathUtils.get_work_dir() + '/adb/adb.exe'
     if test_device:
         AutoAdbCheck.test_device(self)
예제 #8
0
class AutoAdb:
    threshold = 0.8
    wait_time = 1
    screen_pic_path = PathUtils.get_cache_dir() + '/screen.png'

    def __init__(self, test_device=False):
        self.adb_path = PathUtils.get_work_dir() + '/adb/adb.exe'
        if test_device:
            AutoAdbCheck.test_device(self)

    def run(self, raw_command):
        adb_host_port = ConfigUtils.get('adb_host_port')
        command = '%s -s %s %s' % (self.adb_path, adb_host_port, raw_command)
        res = os.popen(command)
        return res.buffer.read().decode('utf-8').strip()

    def screen_cap(self):
        self.run('exec-out screencap -p > ' + self.screen_pic_path)

    def get_location(self, *temp_rel_path_list, threshold=threshold):
        self.screen_cap()
        sp_gray = cv2.imread(self.screen_pic_path, cv2.COLOR_BGR2BGRA)

        for temp_rel_path in temp_rel_path_list:
            temp_abs_path = PathUtils.get_abs_path(temp_rel_path)
            temp_gray = cv2.imread(temp_abs_path, cv2.COLOR_BGR2BGRA)

            res = cv2.matchTemplate(sp_gray, temp_gray, cv2.TM_CCOEFF_NORMED)
            _, max_val, _, max_loc = cv2.minMaxLoc(res)
            if max_val < threshold:
                continue

            h, w, _ = cv2.imread(temp_abs_path).shape
            x = max_loc[0] + w / 2
            y = max_loc[1] + h / 2
            return Location(self, temp_rel_path, x, y)
        return None

    def check(self, *temp_rel_path_list):
        loc = self.get_location(*temp_rel_path_list)
        return loc is not None

    def click(self, temp_rel_path, threshold=threshold, wait_time=wait_time):
        loc = self.get_location(temp_rel_path, threshold=threshold)
        if loc is None:
            return False
        return loc.click(wait_time)

    def swipe(self, start_x, start_y, end_x, end_y, duration=1500):
        self.run('shell input swipe %d %d %d %d %d' %
                 (start_x, start_y, end_x, end_y, duration))

    def wait(self,
             temp_rel_path,
             threshold=threshold,
             cycle_interval=0,
             max_wait_time=None,
             episode=None):
        timer = Timer()
        while True:
            duration = timer.get_duration()
            print('\r > wait %s ... %ds ' % (temp_rel_path, duration), end='')

            if max_wait_time is not None and 0 < max_wait_time < duration:
                print(' ×', flush=True)
                return Location(self, None, None, None)

            if episode is not None:
                try:
                    episode()
                except Exception as e:
                    print('过程方法执行异常')
                    print(e)

            loc = self.get_location(temp_rel_path, threshold=threshold)
            if loc is not None:
                print(' √', flush=True)
                return loc

            if cycle_interval > 0:
                time.sleep(cycle_interval)
예제 #9
0
def get(key, section='default', fallback=None):
    cp = ConfigParser()
    cp.read(PathUtils.get_work_dir() + '/config.ini', encoding='utf-8')
    return cp.get(section, key, fallback=fallback)