Beispiel #1
0
    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)
Beispiel #2
0
    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        self.client = conf.getint('DEFAULT', 'client')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')
        self.mitama_team_mark = conf.getint('mitama', 'mitama_team_mark')
        self.max_times = conf.getint('DEFAULT', 'max_times')
        self.end_operation = conf.getint('DEFAULT', 'end_operation')
        self.run_times = 0

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            if self.client == 0:
                hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
            elif self.client == 1:
                hwnd = win32gui.FindWindow(0, u'阴阳师 - MuMu模拟器')
                # TansuoPos.InitPosWithClient__()
                # YuhunPos.InitPosWithClient__()
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

        # 绑定场景

        # 自检
        debug_enable = conf.getboolean('others', 'debug_enable')
        if debug_enable:
            task = threading.Thread(target=self.yys.debug)
            task.start()
Beispiel #3
0
class Fighter:

    def __init__(self, name='', emyc=0):
        # 初始参数
        self.emyc = emyc
        self.name = name

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        self.yys = GameControl(u'阴阳师-网易游戏')
        self.log.writeinfo(self.name + 'Registration successful')

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + 'Activation successful')
        ut.mysleep(500)

    def check_battle(self):
        # 检测是否进入战斗
        self.yys.wait_game_img('img\\ZI-DONG.png')
        self.log.writeinfo(self.name + 'Already in battle')

    def check_end(self):
        # 检测是否打完
        self.yys.wait_game_img('img\\JIE-SU.png')
        self.log.writeinfo(self.name + "Battle finished")

    def click_monster(self):
        # 点击怪物
        pass
Beispiel #4
0
    def __init__(self, hwnd, quit_game_enable=1):
        '''
        初始化
            :param hwnd: 需要绑定的窗口句柄
            :param quit_game_enable: 程序死掉时是否退出游戏。True为是,False为否
        '''
        self.run = True
        self.hwnd = hwnd
        self.quit_game_enable = quit_game_enable
        #user32 = ctypes.windll.user32
        #user32.SetProcessDPIAware()

        # 启动日志
        self.log = WriteLog()
Beispiel #5
0
    def __init__(self, name='', emyc=0):
        # 初始参数
        self.emyc = emyc
        self.name = name

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        self.yys = GameControl(u'阴阳师-网易游戏')
        self.log.writeinfo(self.name + 'Registration successful')

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + 'Activation successful')
        ut.mysleep(500)
Beispiel #6
0
    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True
        self.run_time = time.time()

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')
        self.quit_time = conf.getint('watchdog', 'quit_time')

        self.team = conf.getboolean('others', 'team')
        self.team_id = conf.getint('others', 'team_id')
        self.monster = conf.getboolean('others', 'monster')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

        # 自检
        debug_enable = conf.getboolean('others', 'debug_enable')
        if debug_enable:
            task = threading.Thread(target=self.yys.debug)
            task.start()
Beispiel #7
0
    def __init__(self, name='', emyc=0):
        # 初始参数
        self.emyc = emyc
        self.name = name

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        self.yys = GameControl(u'阴阳师-网易游戏', quit_game_enable)
        self.log.writeinfo(self.name + 'Registration successful')

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + 'Activation successful')
        time.sleep(0.5)
Beispiel #8
0
    def __init__(self, name='', emyc=0, hwnd=0, activate=True):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
            : param activate=True: 是否激活窗口,支线任务不需要激活
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow('Win32Window0', u'阴阳师-网易游戏')
            # hwnd = win32gui.FindWindow('Qt5QWindowIcon', '夜神模拟器')
            # hwnd = win32gui.FindWindowEx(hwnd, 0, 'Qt5QWindowIcon', 'ScreenBoardClassWindow')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        if activate:
            # 激活窗口
            self.yys.activate_window()
            self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)
Beispiel #9
0
class Fighter:

    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

    def check_battle(self):
        # 检测是否进入战斗
        self.log.writeinfo(self.name + '检测是否进入战斗')
        self.yys.wait_game_img('img\\ZI-DONG.png', self.max_win_time)
        self.log.writeinfo(self.name + '已进入战斗')

    def check_end(self):
        # 检测是否打完
        self.log.writeinfo(self.name + '检测是战斗是否结束')
        self.yys.wait_game_img('img\\JIE-SU.png', self.max_win_time)
        self.log.writeinfo(self.name + "战斗结束")

    def click_monster(self):
        # 点击怪物
        pass

    def click_until(self, tag, img_path, pos, pos_end=None, step_time=None, appear=True, point=0.97):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现或消失
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :appear: 图片出现或消失:Ture-出现;False-消失
            :point: 判定图片的的识别概率
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        while time.time()-start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img(img_path, point=point)
            if not appear:
                result = not result
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            if step_time == None:
                time.sleep(random.randint(1, 3))
            else:
                time.sleep(step_time)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        # self.yys.quit_game()
        self.log.writewarning("强制退出脚本")
        sys.exit(0)

    def activate(self):
        self.log.writewarning(self.name + '启动脚本')
        self.run = True
        self.yys.run = True

    def deactivate(self):
        self.log.writewarning(self.name + '手动停止脚本')
        self.run = False
        self.yys.run = False

    def slide_x_scene(self, distance):
        '''
        水平滑动场景
            :return: 成功返回True; 失败返回False
        '''
        x0 = random.randint(distance + 10, 1126)
        x1 = x0 - distance
        y0 = random.randint(436, 486)
        y1 = random.randint(436, 486)
        self.yys.mouse_drag_bg((x0, y0), (x1, y1))
        logging.info(self.name + '水平滑动界面')

    def get_scene(self):
        '''
        识别当前场景
            :return: 返回场景名称:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
        '''
        # 拒绝悬赏
        self.yys.rejectbounty()

        # 分别识别庭院、探索、章节页、探索内
        maxVal, maxLoc = self.yys.find_multi_img(
            'img\\JIA-CHENG.png', 'img\\JUE-XING.png', 'img\\TAN-SUO.png', 'img\\YING-BING.png')

        scene_cof = max(maxVal)
        if scene_cof > 0.97:
            scene = maxVal.index(scene_cof)
            return scene + 1
        else:
            return 0

    def get_scene_baigui(self):
        '''
        识别百鬼结束的画面
            :return: 返回场景名称:1-百鬼首页,2-结算页面
        '''
        # 拒绝悬赏
        self.yys.rejectbounty()

        # 分别识别百鬼首页、结算页面
        maxVal, maxLoc = self.yys.find_multi_img(
            'img\\BAI-GUI-YE-XING.png', 'img\\BAI-GUI-QI-YUE-SHU.png')

        scene_cof = max(maxVal)
        if scene_cof > 0.97:
            scene = maxVal.index(scene_cof)
            return scene + 1
        else:
            return 0

    def get_scene_breakthrough(self):
        '''
        识别结界突破结果
            :return: 返回场景名称:1-成功,2-失败
        '''
        # 拒绝悬赏
        self.yys.rejectbounty()

        # 分别识别百鬼首页、结算页面
        maxVal, maxLoc = self.yys.find_multi_img(
            'img\\SHENG-LI.png', 'img\\SHI-BAI.png')

        scene_cof = max(maxVal)
        if scene_cof > 0.97:
            scene = maxVal.index(scene_cof)
            return scene + 1
        else:
            return 0

    def switch_to_scene(self, scene):
        '''
        切换场景
            :param scene: 需要切换到的场景:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
            :return: 切换成功返回True;切换失败直接退出
        '''
        scene_now = self.get_scene()
        logging.info(self.name + '目前场景:' + str(scene_now))
        if scene_now == scene:
            return True
        if scene_now == 1:
            # 庭院中
            if scene == 2 or scene == 3 or scene == 4:
                # 先将界面划到最右边
                self.slide_x_scene(800)
                time.sleep(2)
                self.slide_x_scene(800)

                # 点击探索灯笼进入探索界面
                self.click_until('探索灯笼', 'img\\JUE-XING.png', *
                                 TansuoPos.tansuo_denglong)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 2:
            # 探索界面
            if scene == 3 or scene == 4:
                # 点击最后章节
                self.click_until('最后章节', 'img\\TAN-SUO.png',
                                 *TansuoPos.last_chapter)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 3:
            # 章节界面
            if scene == 4:
                # 点击探索按钮
                self.click_until('探索按钮', 'img\\YING-BING.png',
                                 *TansuoPos.tansuo_btn)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 4:
            # 探索内
            if scene == 3:
                # 点击退出探索
                self.click_until('退出按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.quit_btn)

                # 点击确认
                self.click_until('确认按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.confirm_btn, 2, False)

                # 递归
                self.switch_to_scene(scene)
Beispiel #10
0
class Fighter:

    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')
        self.mitama_team_mark = conf.getint('mitama', 'mitama_team_mark')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

        # 自检
        debug_enable = conf.getboolean('others', 'debug_enable')
        if debug_enable:
            task = threading.Thread(target=self.yys.debug)
            task.start()

    def check_battle(self):
        # 检测是否进入战斗
        self.log.writeinfo(self.name + '检测是否进入战斗')
        self.yys.wait_game_img('img\\ZI-DONG.png', self.max_win_time)
        self.log.writeinfo(self.name + '已进入战斗')

    def check_end(self):
        # 检测是否打完
        self.log.writeinfo(self.name + '检测是战斗是否结束')
        self.yys.wait_game_img('img\\JIE-SU.png', self.max_win_time)
        self.log.writeinfo(self.name + "战斗结束")

    def mitama_team_click(self):
        '''
        御魂标记己方式神
        '''
        num = self.mitama_team_mark
        if num > 0:
            # 100 1040
            # 125 50
            # 御魂场景获取标记位置
            min = (num - 1) * 105 + (num - 1) * 100 + 95
            max = min + 50
            pos = (min, 355), (max, 425)
            
            start_time = time.time()
            while time.time() - start_time <= 3:
                x1 = pos[0][0] - 100
                y1 = pos[0][1] - 250
                x2 = pos[1][0] + 100
                y2 = pos[1][1]
                exp_pos = self.yys.find_color(
                    ((x1, y1), (x2, y2)), (134, 227, 96), 5)
                # print('颜色位置', exp_pos)
                if exp_pos != -1:
                    self.log.writeinfo(self.name + '标记式神成功')
                    return True
                else:
                    # 点击指定位置并等待下一轮
                    self.yys.mouse_click_bg(*pos)
                    self.log.writeinfo(self.name + '标记式神')
                    time.sleep(0.4)

            self.log.writewarning(self.name + '标记式神失败')
    
    def click_monster(self):
        # 点击怪物
        pass

    def click_until(self, tag, img_path, pos, pos_end=None, step_time=0.5, appear=True):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现或消失
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :appear: 图片出现或消失:Ture-出现;False-消失
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        while time.time()-start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img(img_path)
            if not appear:
                result = not result
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            time.sleep(step_time)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def activate(self):
        self.log.writewarning(self.name + '启动脚本')
        self.run = True
        self.yys.run = True

    def deactivate(self):
        self.log.writewarning(self.name + '手动停止脚本')
        self.run = False
        self.yys.run = False

    def slide_x_scene(self, distance):
        '''
        水平滑动场景
            :return: 成功返回True; 失败返回False
        '''
        x0 = random.randint(distance + 10, 1126)
        x1 = x0 - distance
        y0 = random.randint(436, 486)
        y1 = random.randint(436, 486)
        self.yys.mouse_drag_bg((x0, y0), (x1, y1))
        logging.info(self.name + '水平滑动界面')

    def get_scene(self):
        '''
        识别当前场景
            :return: 返回场景名称:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
        '''
        # 拒绝悬赏
        self.yys.rejectbounty()

        # 分别识别庭院、探索、章节页、探索内
        maxVal, maxLoc = self.yys.find_multi_img(
            'img/JIA-CHENG.png', 'img/JUE-XING.png', 'img/TAN-SUO.png', 'img/YING-BING.png')

        scene_cof = max(maxVal)
        if scene_cof > 0.97:
            scene = maxVal.index(scene_cof)
            return scene + 1
        else:
            return 0

    def switch_to_scene(self, scene):
        '''
        切换场景
            :param scene: 需要切换到的场景:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
            :return: 切换成功返回True;切换失败直接退出
        '''
        scene_now = self.get_scene()
        logging.info(self.name + '目前场景:' + str(scene_now))
        if scene_now == scene:
            return True
        if scene_now == 1:
            # 庭院中
            if scene == 2 or scene == 3 or scene == 4:
                # 先将界面划到最右边
                self.slide_x_scene(800)
                time.sleep(2)
                self.slide_x_scene(800)

                # 点击探索灯笼进入探索界面
                self.click_until('探索灯笼', 'img/JUE-XING.png', *
                                 TansuoPos.tansuo_denglong, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 2:
            # 探索界面
            if scene == 3 or scene == 4:
                # 点击最后章节
                self.click_until('最后章节', 'img/TAN-SUO.png',
                                 *TansuoPos.last_chapter, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 3:
            # 章节界面
            if scene == 4:
                # 点击探索按钮
                self.click_until('探索按钮', 'img/YING-BING.png',
                                 *TansuoPos.tansuo_btn, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 4:
            # 探索内
            if scene == 3:
                # 点击退出探索
                self.click_until('退出按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.quit_btn, 2)

                # 点击确认
                self.click_until('确认按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.confirm_btn, 2, False)

                # 递归
                self.switch_to_scene(scene)
Beispiel #11
0
class GameControl():
    def __init__(self, hwnd, quit_game_enable=1):
        '''
        初始化
            :param hwnd: 需要绑定的窗口句柄
            :param quit_game_enable: 程序死掉时是否退出游戏。True为是,False为否
        '''
        self.run = True
        self.hwnd = hwnd
        self.quit_game_enable = quit_game_enable
        #user32 = ctypes.windll.user32
        #user32.SetProcessDPIAware()

        # 启动日志
        self.log = WriteLog()

    def window_full_shot(self, file_name=None, gray=0):
        """
        窗口截图
            :param file_name=None: 截图文件的保存名称
            :param gray=0: 是否返回灰度图像,0:返回BGR彩色图像,其他:返回灰度黑白图像
            :return: file_name为空则返回RGB数据
        """
        try:
            l, t, r, b = win32gui.GetWindowRect(self.hwnd)
            # 39和16为Window与Client高和宽的差值
            h = b - t - 39
            w = r - l - 16
            hwindc = win32gui.GetWindowDC(self.hwnd)
            srcdc = win32ui.CreateDCFromHandle(hwindc)
            memdc = srcdc.CreateCompatibleDC()
            bmp = win32ui.CreateBitmap()
            bmp.CreateCompatibleBitmap(srcdc, w, h)
            memdc.SelectObject(bmp)
            memdc.BitBlt((0, 0), (w, h), srcdc, (8, 31), win32con.SRCCOPY)
            if file_name != None:
                bmp.SaveBitmapFile(memdc, file_name)
                srcdc.DeleteDC()
                memdc.DeleteDC()
                win32gui.ReleaseDC(self.hwnd, hwindc)
                win32gui.DeleteObject(bmp.GetHandle())
                return
            else:
                signedIntsArray = bmp.GetBitmapBits(True)
                img = np.fromstring(signedIntsArray, dtype='uint8')
                img.shape = (h, w, 4)
                srcdc.DeleteDC()
                memdc.DeleteDC()
                win32gui.ReleaseDC(self.hwnd, hwindc)
                win32gui.DeleteObject(bmp.GetHandle())
                #cv2.imshow("image", cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY))
                # cv2.waitKey(0)
                if gray == 0:
                    return cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
                else:
                    return cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
        except:
            pass

    def window_part_shot(self, pos1, pos2, file_name=None, gray=0):
        """
        窗口区域截图
            :param pos1: (x,y) 截图区域的左上角坐标
            :param pos2: (x,y) 截图区域的右下角坐标
            :param file_name=None: 截图文件的保存路径
            :param gray=0: 是否返回灰度图像,0:返回BGR彩色图像,其他:返回灰度黑白图像
            :return: file_name为空则返回RGB数据
        """
        w = pos2[0] - pos1[0]
        h = pos2[1] - pos1[1]
        hwindc = win32gui.GetWindowDC(self.hwnd)
        srcdc = win32ui.CreateDCFromHandle(hwindc)
        memdc = srcdc.CreateCompatibleDC()
        bmp = win32ui.CreateBitmap()
        bmp.CreateCompatibleBitmap(srcdc, w, h)
        memdc.SelectObject(bmp)
        memdc.BitBlt((0, 0), (w, h), srcdc, (pos1[0] + 8, pos1[1] + 31),
                     win32con.SRCCOPY)
        if file_name != None:
            bmp.SaveBitmapFile(memdc, file_name)
            srcdc.DeleteDC()
            memdc.DeleteDC()
            win32gui.ReleaseDC(self.hwnd, hwindc)
            win32gui.DeleteObject(bmp.GetHandle())
            return
        else:
            signedIntsArray = bmp.GetBitmapBits(True)
            img = np.fromstring(signedIntsArray, dtype='uint8')
            img.shape = (h, w, 4)
            srcdc.DeleteDC()
            memdc.DeleteDC()
            win32gui.ReleaseDC(self.hwnd, hwindc)
            win32gui.DeleteObject(bmp.GetHandle())
            #cv2.imshow("image", cv2.cvtColor(img, cv2.COLOR_BGRA2BGR))
            # cv2.waitKey(0)
            if gray == 0:
                return cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
            else:
                return cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)

    def find_color(self, region, color, tolerance=0):
        """
        寻找颜色
            :param region: ((x1,y1),(x2,y2)) 欲搜索区域的左上角坐标和右下角坐标
            :param color: (r,g,b) 欲搜索的颜色
            :param tolerance=0: 容差值
            :return: 成功返回客户区坐标,失败返回-1
        """
        img = Image.fromarray(self.window_part_shot(region[0], region[1]),
                              'RGB')
        width, height = img.size
        r1, g1, b1 = color[:3]
        for x in range(width):
            for y in range(height):
                try:
                    pixel = img.getpixel((x, y))
                    r2, g2, b2 = pixel[:3]
                    if abs(r1 - r2) <= tolerance and abs(
                            g1 - g2) <= tolerance and abs(b1 -
                                                          b2) <= tolerance:
                        return x + region[0][0], y + region[0][1]
                except:
                    return -1
        return -1

    def check_color(self, pos, color, tolerance=0):
        """
        对比窗口内某一点的颜色
            :param pos: (x,y) 欲对比的坐标
            :param color: (r,g,b) 欲对比的颜色 
            :param tolerance=0: 容差值
            :return: 成功返回True,失败返回False
        """
        img = Image.fromarray(self.window_full_shot(), 'RGB')
        r1, g1, b1 = color[:3]
        r2, g2, b2 = img.getpixel(pos)[:3]
        if abs(r1 - r2) <= tolerance and abs(g1 - g2) <= tolerance and abs(
                b1 - b2) <= tolerance:
            return True
        else:
            return False

    def find_img(self,
                 img_template_path,
                 part=0,
                 pos1=None,
                 pos2=None,
                 gray=0):
        """
        查找图片
            :param img_template_path: 欲查找的图片路径
            :param part=0: 是否全屏查找,1为否,其他为是
            :param pos1=None: 欲查找范围的左上角坐标
            :param pos2=None: 欲查找范围的右下角坐标
            :param gray=0: 是否彩色查找,0:查找彩色图片,1:查找黑白图片
            :return: (maxVal,maxLoc) maxVal为相关性,越接近1越好,maxLoc为得到的坐标
        """
        # 获取截图
        if part == 1:
            img_src = self.window_part_shot(pos1, pos2, None, gray)
        else:
            img_src = self.window_full_shot(None, gray)

        # show_img(img_src)

        # 读入文件
        if gray == 0:
            img_template = cv2.imread(img_template_path, cv2.IMREAD_COLOR)
        else:
            img_template = cv2.imread(img_template_path, cv2.IMREAD_GRAYSCALE)

        try:
            res = cv2.matchTemplate(img_src, img_template,
                                    cv2.TM_CCOEFF_NORMED)
            minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res)
            # print(maxLoc)
            return maxVal, maxLoc
        except:
            return 0, 0

    def find_multi_img(self,
                       *img_template_path,
                       part=0,
                       pos1=None,
                       pos2=None,
                       gray=0):
        """
        查找多张图片
            :param img_template_path: 欲查找的图片路径列表
            :param part=0: 是否全屏查找,1为否,其他为是
            :param pos1=None: 欲查找范围的左上角坐标
            :param pos2=None: 欲查找范围的右下角坐标
            :param gray=0: 是否彩色查找,0:查找彩色图片,1:查找黑白图片
            :return: (maxVal,maxLoc) maxVal为相关性列表,越接近1越好,maxLoc为得到的坐标列表
        """
        # 窗口截图
        if part == 1:
            img_src = self.window_part_shot(pos1, pos2, None, gray)
        else:
            img_src = self.window_full_shot(None, gray)

        # 返回值列表
        maxVal_list = []
        maxLoc_list = []
        for item in img_template_path:
            # 读入文件
            if gray == 0:
                img_template = cv2.imread(item, cv2.IMREAD_COLOR)
            else:
                img_template = cv2.imread(item, cv2.IMREAD_GRAYSCALE)

            # 开始识别
            try:
                res = cv2.matchTemplate(img_src, img_template,
                                        cv2.TM_CCOEFF_NORMED)
                minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res)
                maxVal_list.append(maxVal)
                maxLoc_list.append(maxLoc)
            except:
                maxVal_list.append(0)
                maxLoc_list.append(0)
        # 返回列表
        return maxVal_list, maxLoc_list

    def activate_window(self):
        user32 = ctypes.WinDLL('user32.dll')
        user32.SwitchToThisWindow(self.hwnd, True)

    def mouse_move(self, pos, pos_end=None):
        """
        模拟鼠标移动
            :param pos: (x,y) 鼠标移动的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标移动至以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
        """
        pos2 = win32gui.ClientToScreen(self.hwnd, pos)
        if pos_end == None:
            win32api.SetCursorPos(pos2)
        else:
            pos_end2 = win32gui.ClientToScreen(self.hwnd, pos_end)
            pos_rand = (random.randint(pos2[0], pos_end2[0]),
                        random.randint(pos2[1], pos_end2[1]))
            win32api.SetCursorPos(pos_rand)

    def mouse_click(self):
        """
        鼠标单击
        """
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
        time.sleep(random.randint(20, 80) / 1000)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)

    def mouse_drag(self, pos1, pos2):
        """
        鼠标拖拽
            :param pos1: (x,y) 起点坐标
            :param pos2: (x,y) 终点坐标
        """
        pos1_s = win32gui.ClientToScreen(self.hwnd, pos1)
        pos2_s = win32gui.ClientToScreen(self.hwnd, pos2)
        screen_x = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
        screen_y = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
        start_x = pos1_s[0] * 65535 // screen_x
        start_y = pos1_s[1] * 65535 // screen_y
        dst_x = pos2_s[0] * 65535 // screen_x
        dst_y = pos2_s[1] * 65535 // screen_y
        move_x = np.linspace(start_x, dst_x, num=20, endpoint=True)[0:]
        move_y = np.linspace(start_y, dst_y, num=20, endpoint=True)[0:]
        self.mouse_move(pos1)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
        for i in range(20):
            x = int(round(move_x[i]))
            y = int(round(move_y[i]))
            win32api.mouse_event(
                win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, x,
                y, 0, 0)
            time.sleep(0.01)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)

    def mouse_click_bg(self, pos, pos_end=None):
        """
        后台鼠标单击
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
        """
        if pos_end == None:
            win32gui.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, 0,
                                 win32api.MAKELONG(pos[0], pos[1]))
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, 0,
                                 win32api.MAKELONG(pos[0], pos[1]))
            time.sleep(random.randint(20, 80) / 1000)
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0,
                                 win32api.MAKELONG(pos[0], pos[1]))
        else:
            pos_rand = (random.randint(pos[0], pos_end[0]),
                        random.randint(pos[1], pos_end[1]))
            win32gui.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))
            time.sleep(random.randint(20, 80) / 1000)
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))

    def mouse_double_click_bg(self, pos, pos_end):
        """
        后台鼠标双击
            :param pos: (x,y) 鼠标双击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标双击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
        """
        # 获取随机位置
        pos_rand = (random.randint(pos[0], pos_end[0]),
                    random.randint(pos[1], pos_end[1]))
        for i in range(2):
            win32gui.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))
            time.sleep(random.randint(20, 80) / 1000)
            win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0,
                                 win32api.MAKELONG(pos_rand[0], pos_rand[1]))

            time.sleep(random.randint(100, 200) / 1000)

    def mouse_drag_bg(self, pos1, pos2):
        """
        后台鼠标拖拽
            :param pos1: (x,y) 起点坐标
            :param pos2: (x,y) 终点坐标
        """
        move_x = np.linspace(pos1[0], pos2[0], num=20, endpoint=True)[0:]
        move_y = np.linspace(pos1[1], pos2[1], num=20, endpoint=True)[0:]
        win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, 0,
                             win32api.MAKELONG(pos1[0], pos1[1]))
        for i in range(20):
            x = int(round(move_x[i]))
            y = int(round(move_y[i]))
            win32gui.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, 0,
                                 win32api.MAKELONG(x, y))
            time.sleep(0.01)
        win32gui.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0,
                             win32api.MAKELONG(pos2[0], pos2[1]))

    def wait_game_img(self, img_path, max_time=100, quit=True):
        """
        等待游戏图像
            :param img_path: 图片路径
            :param max_time=60: 超时时间
            :param quit=True: 超时后是否退出
            :return: 成功返回坐标,失败返回False
        """
        self.rejectbounty()
        start_time = time.time()
        while time.time() - start_time <= max_time and self.run:
            maxVal, maxLoc = self.find_img(img_path)
            if maxVal > 0.97:
                return maxLoc
            if max_time > 5:
                time.sleep(1)
            else:
                time.sleep(0.1)
        if quit:
            # 超时则退出游戏
            # self.quit_game()
            self.log.writewarning("强制退出脚本")
            sys.exit(0)
        else:
            return False

    def wait_game_img_disappear(self, img_path, max_time=100, quit=True):
        """
        等待游戏图像消失
            :param img_path: 图片路径
            :param max_time=60: 超时时间
            :param quit=True: 超时后是否退出
            :return: 成功返回坐标,失败返回False
        """
        self.rejectbounty()
        start_time = time.time()
        while time.time() - start_time <= max_time and self.run:
            maxVal, maxLoc = self.find_img(img_path)
            if maxVal < 0.97:
                return maxLoc
            if max_time > 5:
                time.sleep(1)
            else:
                time.sleep(0.1)
        if quit:
            # 超时则退出游戏
            # self.quit_game()
            self.log.writewarning("强制退出脚本")
            sys.exit(0)
        else:
            return False

    def wait_multi_game_img(self, *img_path, max_time=100, quit=True):
        """
        等待游戏图像
            :param img_path: 图片路径
            :param max_time=60: 超时时间
            :param quit=True: 超时后是否退出
            :return: 成功返回坐标,失败返回False
        """
        self.rejectbounty()
        start_time = time.time()
        while time.time() - start_time <= max_time and self.run:
            for item in img_path:
                maxVal, maxLoc = self.find_img(item)
                if maxVal > 0.97:
                    return maxLoc
            if max_time > 5:
                time.sleep(1)
            else:
                time.sleep(0.1)
        if quit:
            # 超时则退出游戏
            # self.quit_game()
            self.log.writewarning("强制退出脚本")
            sys.exit(0)
        else:
            return False

    def wait_game_color(self,
                        region,
                        color,
                        tolerance=0,
                        max_time=60,
                        quit=True):
        """
        等待游戏颜色
            :param region: ((x1,y1),(x2,y2)) 欲搜索的区域
            :param color: (r,g,b) 欲等待的颜色
            :param tolerance=0: 容差值
            :param max_time=30: 超时时间
            :param quit=True: 超时后是否退出
            :return: 成功返回True,失败返回False
        """
        self.rejectbounty()
        start_time = time.time()
        while time.time() - start_time <= max_time and self.run:
            pos = self.find_color(region, color)
            if pos != -1:
                return True
            time.sleep(1)
        if quit:
            # 超时则退出游戏
            # self.quit_game()
            self.log.writewarning("强制退出脚本")
            sys.exit(0)
        else:
            return False

    def quit_game(self):
        """
        退出游戏
        """
        self.takescreenshot()  # 保存一下现场
        if not self.run:
            return False
        if self.quit_game_enable:
            win32gui.SendMessage(self.hwnd, win32con.WM_DESTROY, 0, 0)  # 退出游戏
        sys.exit(0)

    def takescreenshot(self):
        '''
        截图
        '''
        img_src_path = 'img\\full.png'
        self.window_full_shot(img_src_path)

    def rejectbounty(self):
        '''
        拒绝悬赏
            :return: 拒绝成功返回True,其他情况返回False
        '''
        maxVal, maxLoc = self.find_img('img\\XUAN-SHANG.png')
        if maxVal > 0.97:
            self.mouse_click_bg((757, 460))
            return True
        return False

    def find_game_img(self,
                      img_path,
                      part=0,
                      pos1=None,
                      pos2=None,
                      gray=0,
                      point=0.97):
        '''
        查找图片
            :param img_path: 查找路径
            :param part=0: 是否全屏查找,1为否,其他为是
            :param pos1=None: 欲查找范围的左上角坐标
            :param pos2=None: 欲查找范围的右下角坐标
            :param gray=0: 是否查找黑白图片,0:查找彩色图片,1:查找黑白图片
            :param point: 判定图片的的识别概率
            :return: 查找成功返回位置坐标,否则返回False
        '''
        self.rejectbounty()
        maxVal, maxLoc = self.find_img(img_path, part, pos1, pos2, gray)
        # print(maxVal)
        if maxVal > point:
            return maxLoc
        else:
            return False
Beispiel #12
0
class Fighter:
    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True
        self.run_time = time.time()

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')
        self.quit_time = conf.getint('watchdog', 'quit_time')

        self.team = conf.getboolean('others', 'team')
        self.team_id = conf.getint('others', 'team_id')
        self.monster = conf.getboolean('others', 'monster')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

        # 自检
        debug_enable = conf.getboolean('others', 'debug_enable')
        if debug_enable:
            task = threading.Thread(target=self.yys.debug)
            task.start()

    def check_battle(self):
        # 检测是否进入战斗
        self.log.writeinfo(self.name + '检测是否进入战斗')
        self.yys.wait_game_img('img\\ZI-DONG.png', self.max_win_time)
        self.log.writeinfo(self.name + '已进入战斗')

    def check_end(self):
        # 检测是否打完
        self.log.writeinfo(self.name + '检测是战斗是否结束')
        self.yys.wait_game_img('img\\JIE-SU.png', self.max_win_time, 0.8)
        self.log.writeinfo(self.name + "战斗结束")

    def click_monster(self):
        # 点击怪物
        pass

    def click_team(self, mode=1, number=0):
        """
        标记式神
            :param mode 标记场景类型 1:御魂 2: 突破
        """
        # 标记式神

        num = 0
        if number > 0:
            num = number

        if self.team and self.team_id > 0:
            num = self.team_id

        if num > 0:
            # 100 1040
            # 125 50
            if mode == 1:
                # 御魂场景获取标记位置
                min = (num - 1) * 105 + (num - 1) * 100 + 95
                max = min + 50
                pos = (min, 355), (max, 425)
            elif mode == 2:
                # 突破场景获取标记位置
                pos = {
                    1: ((79, 385), (142, 418)),
                    2: ((315, 335), (360, 358)),
                    3: ((523, 270), (570, 325)),
                    4: ((715, 340), (750, 380)),
                    5: ((955, 400), (1055, 430)),
                }.get(num)
            start_time = time.time()
            while time.time() - start_time <= 3 and self.run:
                x1 = pos[0][0] - 100
                y1 = pos[0][1] - 250
                x2 = pos[1][0] + 100
                y2 = pos[1][1]
                exp_pos = self.yys.find_color(((x1, y1), (x2, y2)),
                                              (134, 227, 96), 5)
                # print('颜色位置', exp_pos)
                if exp_pos != -1:
                    self.log.writeinfo(self.name + ' 标记式神成功')
                    return True
                else:
                    # 点击指定位置并等待下一轮
                    self.yys.mouse_click_bg(*pos)
                    self.log.writeinfo(self.name + '标记式神')
                    time.sleep(0.4)

            self.log.writewarning(self.name + '标记式神失败')

    def click_until_multi(self,
                          tag,
                          *img_path,
                          pos,
                          pos_end=None,
                          sleep_time=0.5):
        '''
        在某一时间段内,后台点击鼠标,直到出现某些图片出现
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :return: 成功返回True, 失败退出游戏
        '''
        start_time = time.time()
        while time.time() - start_time <= self.max_op_time and self.run:
            result = self.yys.find_multi_game_img(*img_path)
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            time.sleep(sleep_time)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def click_until(self,
                    tag,
                    img_path,
                    pos,
                    pos_end=None,
                    step_time=0.5,
                    appear=True):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现或消失
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :appear: 图片出现或消失:Ture-出现;False-消失
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        self.log.writeinfo(self.name + '点击 ' + tag)
        while time.time() - start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img(img_path)
            if not appear:
                result = not result
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                # print("点击")
                self.yys.mouse_click_bg(pos, pos_end)
                # self.log.writeinfo(self.name + '点击 ' + tag)
            time.sleep(step_time)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        return False
        # 提醒玩家点击失败,并在5s后退出
        # self.yys.activate_window()
        # time.sleep(5)
        # self.yys.quit_game()

    def activate(self):
        self.log.writewarning(self.name + '启动脚本')
        self.run = True
        self.yys.run = True

    def deactivate(self):
        self.log.writewarning(self.name + '手动停止脚本')
        self.run = False
        self.yys.run = False

    def slide_x_scene(self, distance):
        '''
        水平滑动场景
            :return: 成功返回True; 失败返回False
        '''
        x0 = random.randint(distance + 10, 1126)
        x1 = x0 - distance
        y0 = random.randint(436, 486)
        y1 = random.randint(436, 486)
        self.yys.mouse_drag_bg((x0, y0), (x1, y1))
        logging.info(self.name + '水平滑动界面')

    def get_scene(self):
        '''
        识别当前场景
            :return: 返回场景名称:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
        '''
        # 拒绝悬赏
        self.yys.rejectbounty()

        # 分别识别庭院、探索、章节页、探索内
        maxVal, maxLoc = self.yys.find_multi_img('img/JIA-CHENG.png',
                                                 'img/JUE-XING.png',
                                                 'img/TAN-SUO.png',
                                                 'img/YING-BING.png')

        scene_cof = max(maxVal)
        if scene_cof > 0.97:
            scene = maxVal.index(scene_cof)
            return scene + 1
        else:
            return 0

    def switch_to_scene(self, scene):
        '''
        切换场景
            :param scene: 需要切换到的场景:1-庭院; 2-探索界面; 3-章节界面; 4-探索内
            :return: 切换成功返回True;切换失败直接退出
        '''
        scene_now = self.get_scene()
        logging.info(self.name + '目前场景:' + str(scene_now))
        if scene_now == scene:
            return True
        if scene_now == 1:
            # 庭院中
            if scene == 2 or scene == 3 or scene == 4:
                # 先将界面划到最右边
                self.slide_x_scene(800)
                time.sleep(2)
                self.slide_x_scene(800)

                # 点击探索灯笼进入探索界面
                self.click_until('探索灯笼', 'img/JUE-XING.png',
                                 *TansuoPos.tansuo_denglong, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 2:
            # 探索界面
            if scene == 3 or scene == 4:
                # 点击最后章节
                self.click_until('最后章节', 'img/TAN-SUO.png',
                                 *TansuoPos.last_chapter, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 3:
            # 章节界面
            if scene == 4:
                # 点击探索按钮
                self.click_until('探索按钮', 'img/YING-BING.png',
                                 *TansuoPos.tansuo_btn, 2)

                # 递归
                self.switch_to_scene(scene)

        if scene_now == 4:
            # 探索内
            if scene == 3:
                # 点击退出探索
                self.click_until('退出按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.quit_btn, 2)

                # 点击确认
                self.click_until('确认按钮', 'img\\QUE-REN.png',
                                 *TansuoPos.confirm_btn, 2, False)

                # 递归
                self.switch_to_scene(scene)

    def check_quit_game(self):

        if self.quit_time > 0:
            if time.time() - self.run_time > self.quit_time:
                # 切换到庭院
                is_home = False
                while not is_home:
                    maxVal, maxLoc = self.yys.find_img('img/JIA-CHENG.png')
                    print("加成", maxVal)
                    if maxVal > 0.9:
                        is_home = True
                        continue

                    # 检查关闭
                    if self.yys.mouse_click_img('img/close.png'):
                        time.sleep(0.3)

                    # 检查返回
                    if self.yys.mouse_click_img('img/back.png'):
                        time.sleep(0.5)

                    # 检查确认
                    if self.yys.mouse_click_img('img/que-ding.png'):
                        time.sleep(0.3)

                # 关闭加成
                is_jiacheng = True
                self.click_until('加成', 'img/yu-hun-jia-cheng.png',
                                 *CommonPos.jia_cheng_btn, 0.3)

                while is_jiacheng:
                    pos = self.yys.find_many_game_img('img/on-jia-cheng.png')
                    print(pos)
                    if len(pos) <= 0:
                        is_jiacheng = False
                    else:
                        for item in pos:
                            pos1 = (item[0] + 8, item[1] + 3)
                            pos2 = (item[0] + 60, item[1] + 15)
                            print(pos1, pos2)
                            self.yys.mouse_click_bg(pos1, pos2)
                            mood1 = ut.Mood(1)
                            mood1.moodsleep()

                self.yys.quit_true_game()
Beispiel #13
0
import random
import time

from tools.logsystem import WriteLog

log = WriteLog()


class Mood:
    '''
    用于模拟随机的点击频率,每5分钟更换一次点击规律\n
    energetic: 状态极佳,点击延迟在1-1.5s\n
    joyful: 状态不错,点击延迟在1.3-2.1s\n
    normal: 状态一般,点击延迟在1.8-3s\n
    tired: 状态疲劳,点击延迟在2.5-4\n
    exhausted: CHSM,点击延迟在3-5s\n
    '''
    def __init__(self, state=5):
        self.lastime = time.time()
        self.state = state
        Mood.mymood = {
            1: (1000, 500),
            2: (1300, 800),
            3: (1800, 1200),
            4: (2500, 1500),
            5: (3000, 2000)
        }
        a = random.randint(1, self.state)
        log.writeinfo("Now you mood is level %d", a)
        self.lastmood = Mood.mymood[a]
Beispiel #14
0
class Fighter(GameScene):

    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')
        self.mitama_team_mark = conf.getint('mitama', 'mitama_team_mark')
        self.max_times = conf.getint('DEFAULT', 'max_times')
        self.end_operation = conf.getint('DEFAULT', 'end_operation')
        self.run_times = 0

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

        # 绑定场景

        # 自检
        debug_enable = conf.getboolean('others', 'debug_enable')
        if debug_enable:
            task = threading.Thread(target=self.yys.debug)
            task.start()

    def check_battle(self):
        # 检测是否进入战斗
        self.log.writeinfo(self.name + '检测是否进入战斗')
        self.yys.wait_game_img('img\\ZI-DONG.png', self.max_win_time)
        self.log.writeinfo(self.name + '已进入战斗')

    def check_end(self):
        '''
        检测是否打完
            :return: 胜利页面返回0;奖励页面返回1
        '''
        self.log.writeinfo(self.name + '检测是战斗是否结束')
        if self.yys.wait_game_img_knn('img/SHENG-LI.png', self.max_win_time, False, 8):
            logging.info('战斗成功')
            return 0
        elif self.yys.wait_game_img_knn('img/TIAO-DAN.png', 2, thread=20):
            logging.info('本轮战斗结束')
            return 1

    def check_times(self):
        '''
        监测游戏次数是否达到最大次数
        '''
        self.run_times = self.run_times + 1
        logging.info('游戏已运行'+str(self.run_times)+'次')
        if(self.run_times == self.max_times):
            if(self.end_operation == 0):
                logging.warning('关闭脚本(次数已满)...')
                self.run = False
                os._exit(0)
            elif(self.end_operation == 1):
                logging.warning('关闭游戏(次数已满)...')
                self.yys.quit_game()
                logging.warning('关闭脚本(次数已满)...')
                self.run = False
                os._exit(0)

    def get_reward(self, mood, state):
        '''
        结算处理
            :param mood: 状态函数
            :param state: 上一步的状态。0-战斗成功页面; 1-领取奖励页面
        '''
        if state == 0:
            self.click_until_knn('奖励', 'img/TIAO-DAN.png', ut.firstposition(), None, mood.get1mood()/1000, thread=20)
        start_time = time.time()
        while time.time()-start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img_knn('img/TIAO-DAN.png', thread=2)
            if not result:
                logging.info(self.name + '结算成功')
                return
            else:
                self.yys.mouse_click_bg(ut.secondposition())
                self.log.writeinfo(self.name + '点击结算')
            mood.moodsleep()
        self.log.writewarning(self.name + '点击结算失败!')
        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def mitama_team_click(self):
        '''
        御魂标记己方式神
        '''
        num = self.mitama_team_mark
        if num > 0:
            # 100 1040
            # 125 50
            # 御魂场景获取标记位置
            min = (num - 1) * 105 + (num - 1) * 100 + 95
            max = min + 50
            pos = (min, 355), (max, 425)

            start_time = time.time()
            while time.time() - start_time <= 3:
                x1 = pos[0][0] - 100
                y1 = pos[0][1] - 250
                x2 = pos[1][0] + 100
                y2 = pos[1][1]
                exp_pos = self.yys.find_color(
                    ((x1, y1), (x2, y2)), (134, 227, 96), 5)
                # print('颜色位置', exp_pos)
                if exp_pos != -1:
                    self.log.writeinfo(self.name + '标记式神成功')
                    return True
                else:
                    # 点击指定位置并等待下一轮
                    self.yys.mouse_click_bg(*pos)
                    self.log.writeinfo(self.name + '标记式神')
                    time.sleep(0.4)

            self.log.writewarning(self.name + '标记式神失败')

    def click_monster(self):
        # 点击怪物
        pass

    def click_until(self, tag, img_path, pos, pos_end=None, step_time=0.5, appear=True):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现或消失
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :appear: 图片出现或消失:Ture-出现;False-消失
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        while time.time()-start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img(img_path)
            if not appear:
                result = not result
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            ut.mysleep(step_time*1000)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def click_until_knn(self, tag, img_path, pos, pos_end=None, step_time=0.5, appear=True, thread=0):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现或消失
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :appear: 图片出现或消失:Ture-出现;False-消失
            :thread: 检测阈值
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        while time.time()-start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img_knn(img_path, thread=thread)
            if not appear:
                result = not result
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            ut.mysleep(step_time*1000)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def activate(self):
        self.log.writewarning(self.name + '启动脚本')
        self.run = True
        self.yys.run = True

    def deactivate(self):
        self.log.writewarning(self.name + '手动停止脚本')
        self.run = False
        self.yys.run = False

    def slide_x_scene(self, distance):
        '''
        水平滑动场景
            :return: 成功返回True; 失败返回False
        '''
        x0 = random.randint(distance + 10, 1126)
        x1 = x0 - distance
        y0 = random.randint(436, 486)
        y1 = random.randint(436, 486)
        self.yys.mouse_drag_bg((x0, y0), (x1, y1))
        logging.info(self.name + '水平滑动界面')
Beispiel #15
0
class Fighter:
    def __init__(self, name='', emyc=0, hwnd=0):
        '''
        初始化
            :param name='': 打手名称
            : param emyc=0: 点怪设置:0-不点怪
            : param hwnd=0: 指定窗口句柄:0-否;其他-窗口句柄
        '''
        # 初始参数
        self.emyc = emyc
        self.name = name
        self.run = True

        # 读取配置文件
        conf = configparser.ConfigParser()
        conf.read('conf.ini')
        quit_game_enable = conf.getboolean('watchdog', 'watchdog_enable')
        self.max_op_time = conf.getint('watchdog', 'max_op_time')
        self.max_win_time = conf.getint('watchdog', 'max_win_time')

        # 启动日志
        self.log = WriteLog()

        # 绑定窗口
        if hwnd == 0:
            hwnd = win32gui.FindWindow(0, u'阴阳师-网易游戏')
        self.yys = GameControl(hwnd, quit_game_enable)
        self.log.writeinfo(self.name + '绑定窗口成功')
        self.log.writeinfo(self.name + str(hwnd))

        # 激活窗口
        self.yys.activate_window()
        self.log.writeinfo(self.name + '激活窗口成功')
        time.sleep(0.5)

    def check_battle(self):
        # 检测是否进入战斗
        self.log.writeinfo(self.name + '检测是否进入战斗')
        self.yys.wait_game_img('img\\ZI-DONG.png', self.max_win_time)
        self.log.writeinfo(self.name + '已进入战斗')

    def check_end(self):
        # 检测是否打完
        self.log.writeinfo(self.name + '检测是战斗是否结束')
        self.yys.wait_game_img('img\\JIE-SU.png', self.max_win_time)
        self.log.writeinfo(self.name + "战斗结束")

    def click_monster(self):
        # 点击怪物
        pass

    def click_until(self, tag, img_path, pos, pos_end=None, step_time=0.5):
        '''
        在某一时间段内,后台点击鼠标,直到出现某一图片出现
            :param tag: 按键名
            :param img_path: 图片路径
            :param pos: (x,y) 鼠标单击的坐标
            :param pos_end=None: (x,y) 若pos_end不为空,则鼠标单击以pos为左上角坐标pos_end为右下角坐标的区域内的随机位置
            :step_time=0.5: 查询间隔
            :return: 成功返回True, 失败退出游戏
        '''
        # 在指定时间内反复监测画面并点击
        start_time = time.time()
        while time.time() - start_time <= self.max_op_time and self.run:
            result = self.yys.find_game_img(img_path)
            if result:
                self.log.writeinfo(self.name + '点击 ' + tag + ' 成功')
                return True
            else:
                # 点击指定位置并等待下一轮
                self.yys.mouse_click_bg(pos, pos_end)
                self.log.writeinfo(self.name + '点击 ' + tag)
            time.sleep(step_time)
        self.log.writewarning(self.name + '点击 ' + tag + ' 失败!')

        # 提醒玩家点击失败,并在5s后退出
        self.yys.activate_window()
        time.sleep(5)
        self.yys.quit_game()

    def activate(self):
        self.log.writewarning(self.name + '启动脚本')
        self.run = True
        self.yys.run = True

    def deactivate(self):
        self.log.writewarning(self.name + '手动停止脚本')
        self.run = False
        self.yys.run = False
Beispiel #16
0
import os
import ctypes

from explore.explore import ExploreFight
from mitama.fighter_driver import DriverFighter
from mitama.fighter_passenger import FighterPassenger
from mitama.single_fight import SingleFight
from tools.logsystem import WriteLog

# 设置
global mode
global emyc
global done

#初始化对象
log = WriteLog()

def init():
    global section
    global mode
    global emyc
    global done
    
    try:
        # 选择打什么
        section = int(input('\n选择刷什么(Ctrl-C跳过并单刷御魂:\n0-御魂\n1-探索\n'))
        log.writeinfo('Section = %d', section)
        if section == 0:
            # 御魂模式选择
            mode=int(input('\n选择游戏模式(Ctrl-C跳过并单刷):\n0-单刷\n2-组队司机\n3-组队打手\n'))
            if(mode==1):