Пример #1
0
 def move_player(self):
     if self.point.current_status == 0:
         if self.mouse_mapping == "Hold Mouse Down":
             pydirectinput.mouseDown()
             # pydirectinput.keyDown('m')
         elif self.mouse_mapping == "Click":
             pydirectinput.click()
         elif self.mouse_mapping == "Double Click":
             pydirectinput.doubleClick()
         else:
             print(self.mouse_mapping, " is not recognized")
     else:
         pydirectinput.mouseUp()
Пример #2
0
    def doubleclickBox(self, horz, vert):
        #in windowmode 1920x1080:
        #608 | 683 "0/0"
        #640 | 715 erste box
        #930 | 875 letzte box
        #32 abstand

        time.sleep(self.delay)
        xcoord = self.display_vars['beginning_inventory_x'] + self.display_vars[
            'square_distance'] * horz
        ycoord = self.display_vars['beginning_inventory_y'] + self.display_vars[
            'square_distance'] * vert
        time.sleep(0.01)
        pyautogui.doubleClick(x=xcoord, y=ycoord)
Пример #3
0
def movePlayer():
    if currentStatus != -1:
        if isMouseClick(keyboardParameters[currentStatus]):
            print("helloooooo")
            pydirectinput.mouseDown()
        else:
            pydirectinput.keyDown(chr(int(keyboardParameters[currentStatus])))
    else:
        for elem in keyboardParameters:
            if isMouseClick(elem):
                pydirectinput.mouseUp()
            else:
                pydirectinput.keyUp(chr(int(elem)))

    if currentStatus2 == 0:
        pydirectinput.mouseDown()
    elif currentStatus2 == 1:
        pydirectinput.click()
    elif currentStatus2 == 2:
        pydirectinput.doubleClick()
    elif currentStatus2 == 3:
        print(currentStatus2)
    else:
        pydirectinput.mouseUp()
def activate_curio(party, provision, inventory, item, raid_info, area_name,
                   tile_number, dungeon_path, reverse, debug):
    c = Controller(debug)

    sfr.decrypt_save_info('persist.map.json')
    f = open(Path(f'{sfr.save_editor_path()}/persist.map.json'))
    map_info = json.load(f)['base_root']
    f.close()
    areas = map_info['map']['static_dynamic']['areas']
    location = area_name
    static_areas = map_info['map']['static_dynamic']['static_save'][
        'base_root']['areas']
    area_tiles = areas[area_name]['tiles']
    area_length = len(area_tiles) - 1
    tile_name = f'tile{tile_number}'
    curio = Curios[area_tiles[tile_name]['curio_prop']]
    print(f"Interacting with curio! ({curio['name']})")

    if provision is None and curio['name'] != 'ConfessionBooth':
        reward = curio['reward'][0] if curio['reward'] is not None else None
    elif provision is None and curio['name'] == 'ConfessionBooth':
        reward = 'purge_negative_quirk'
    else:
        reward_index = next((index
                             for index, item in enumerate(curio['provision'])
                             if provision == item), None)
        reward = curio['reward'][
            reward_index] if reward_index is not None else None

    if reward is None:  # drop off quest item
        pass
    elif 'treasure' == reward:
        hero = next(
            (hero for hero in party if 'antiquarian' == hero.heroClass), None)
        if hero is not None:
            select_hero(hero.rank, debug)
    elif 'stress_heal' == reward:
        party.sort(key=lambda k: k.stress, reverse=True)
        select_hero(party[0].rank, debug)
    elif 'purge_negative_quirk' == reward:
        # future - if heroes have the same probability, choose the one that's higher level
        removal_scores = get_quirk_removal_scores(party)
        best_score = removal_scores[0]
        if curio['name'] == 'ConfessionBooth':
            best_score = next(
                score for score in removal_scores
                if next(hero for hero in party
                        if hero.rank == score['hero_rank']).stress < 60)
        select_hero(best_score['hero_rank'], debug)
    elif 'dmg_buff' == reward:  # prioritize tier 1 dmg dealers that can hit all ranks
        dmg_dealer_rank = next(
            (hero.rank for hero in party if hero.heroClass == 'shieldbreaker'
             or hero.heroClass == 'highwayman' or hero.heroClass == 'hellion'),
            None)
        if dmg_dealer_rank is None:
            dmg_dealer_rank = next(
                (hero.rank for hero in party
                 if hero.heroClass == 'grave_robber' or hero.heroClass ==
                 'crusader' or hero.heroClass == 'houndmaster'
                 or hero.heroClass == 'flagellant' or hero.heroClass ==
                 'man_at_arms' or hero.heroClass == 'bounty_hunter'), None)
        if dmg_dealer_rank is None:
            dmg_dealer_rank = party[0].rank
        select_hero(dmg_dealer_rank, debug)
    elif 'heal' == reward:
        party.sort(key=lambda k: k.percentHp)
        select_hero(party[0].rank, debug)
    elif 'def_buff' == reward:  # prioritize healer or non-tank heroes in ranks 1, 2, 3
        buff_target_rank = next(
            (hero.rank for hero in party
             if hero.heroClass == 'vestal' or hero.heroClass == 'highwayman' or
             hero.heroClass == 'hellion' or hero.heroClass == 'shieldbreaker'
             or hero.heroClass == 'houndmaster'), None)
        if buff_target_rank is None:
            buff_target_rank = party[0].rank
        select_hero(buff_target_rank, debug)

    dd_window = win32gui.FindWindowEx(0, 0, 0, "Darkest Dungeon")
    desktop = win32gui.GetDesktopWindow()
    search_region = rf'{sfr.save_editor_path()}\search_region.png'
    hand_img = rf'{sfr.game_install_location()}\scrolls\byhand.png'
    use_item_img = rf'{sfr.game_install_location()}\scrolls\use_inventory.png'
    curio_found = False

    # don't accidentally re-enter room or secret room
    party_tile = 0 if area_length == 0 else get_party_tile(
        raid_info, area_length, reverse)
    if area_name.startswith('co') and area_tiles[f'tile{party_tile}']['content'] == 13 \
            and area_tiles[f'tile{party_tile}']['crit_scout'] is True:
        c.press(c.right, 25)
    elif area_length > 0 and ((party_tile == 0 and not reverse) or
                              (party_tile == area_length and reverse)):
        c.press(c.right, 10)

    # Activate Curio
    c.write(c.up, 2)
    if not area_name.startswith('co'):
        time.sleep(1.5)  # wait for curio screen

    # if in hallway, may have to move and try again if didn't get curio
    while not raid_info['inbattle'] and area_name.startswith(
            'co') and area_name == location:
        print('Activating curio')
        # take screenshot
        # need to minimize and reactivate window, otherwise can't see loot/curio window with a screenshot
        if not debug:
            win32gui.SetForegroundWindow(desktop)
            pydirectinput.doubleClick(x=1050, y=500)
            pydirectinput.doubleClick(x=1050, y=500)
            win32gui.SetForegroundWindow(dd_window)
            pydirectinput.doubleClick(x=1050, y=500)
            pydirectinput.doubleClick(x=1050, y=500)

            if os.path.exists(search_region):
                os.remove(search_region)
            pyautogui.screenshot(search_region, region=(1060, 400, 585, 215))
        image = use_item_img if item is not None and item.type == 'quest' else hand_img
        found = list(pyautogui.locateAll(image, search_region, confidence=.45))
        curio_found = True if len(found) > 0 else False
        print(f'curio_found: {curio_found}')

        # move forward and try again if didn't get the curio
        sfr.decrypt_save_info('persist.raid.json')
        f = open(Path(f'{sfr.save_editor_path()}/persist.raid.json'))
        raid_info = json.load(f)['base_root']
        f.close()
        party_tile = 0 if area_length == 0 else get_party_tile(
            raid_info, area_length, reverse)
        location_number = raid_info['in_area']  # 1111584611
        location = next(index for index, area in areas.items()
                        if static_areas[index]['id'] == location_number)

        sfr.decrypt_save_info('persist.map.json')
        f = open(Path(f'{sfr.save_editor_path()}/persist.map.json'))
        map_info = json.load(f)['base_root']
        f.close()
        areas = map_info['map']['static_dynamic']['areas']
        hallway_tiles = areas[area_name]['tiles']

        if curio_found or (party_tile > tile_number and not reverse) or (party_tile < tile_number and reverse) \
                or hallway_tiles[tile_name]['content'] == 0:
            break
        c.press(c.right, 5)
        c.write(c.up, 2)

    if (curio_found
            or not area_name.startswith('co')) and area_name == location:
        if provision is None:
            if curio['name'] != 'Sack' and curio['name'] != 'DiscardedPack' and curio['name'] != 'Crate' \
                    and curio['name'] != 'Sconce':
                c.write(
                    c.d_pad_right, 2
                )  # necessary to make sure curio gets past use item screen
                c.write(c.a)
                time.sleep(
                    1.5
                )  # wait for potential loot screen or for save file to reflect curio has been activated
        else:
            item_used = False
            while not item_used:
                use_item_on_curio(int(item.item_slot), debug)
                # take screenshot
                # need to minimize and reactivate window, otherwise can't see loot/curio window with screenshot
                if not debug:
                    win32gui.SetForegroundWindow(desktop)
                    pydirectinput.doubleClick(x=1050, y=500)
                    pydirectinput.doubleClick(x=1050, y=500)
                    win32gui.SetForegroundWindow(dd_window)
                    pydirectinput.doubleClick(x=1050, y=500)
                    pydirectinput.doubleClick(x=1050, y=500)

                    if os.path.exists(search_region):
                        os.remove(search_region)
                    pyautogui.screenshot(search_region,
                                         region=(1300, 425, 100, 150))
                found = list(
                    pyautogui.locateAll(use_item_img,
                                        search_region,
                                        confidence=.8))
                item_used = False if len(found) > 0 else True
                print(f'item_used: {item_used}')

            item.quantity -= 1
            if item.quantity == 0:
                if item.item_slot != max(i.item_slot for i in inventory.items):
                    inventory.empty_slots.append(item.item_slot)
                inventory.items.remove(item)
        time.sleep(
            1.5
        )  # wait for potential loot screen or for save file to reflect curio has been activated

        if (reward == 'treasure'
                and item is not None) or (reward == 'quest'
                                          and provision is None):
            loot_treasure(raid_info, inventory, areas, area_name, party,
                          tile_number, dungeon_path, debug)
        # check in case curio does not always give loot
        elif 'treasure' in curio['reward'] and item is None:
            if not debug:
                win32gui.SetForegroundWindow(desktop)
                pydirectinput.doubleClick(x=1050, y=500)
                pydirectinput.doubleClick(x=1050, y=500)
                win32gui.SetForegroundWindow(dd_window)
                pydirectinput.doubleClick(x=1050, y=500)
                pydirectinput.doubleClick(x=1050, y=500)

                if os.path.exists(search_region):
                    os.remove(search_region)
                c.write(c.down, 2)
                # Tried inserting button presses and sleeps to make sure icons and text doesn't get in the way
                # of screenshot. Unfortunately nothing works. Probably just have to save off custom thumbnail to look
                # for instead. Don't need to be able to see specific loot items in image anyways, since we aren't
                # performing image based classification
                pyautogui.screenshot(search_region,
                                     region=(1060, 400, 585, 215))
            found = list(
                pyautogui.locateAll(hand_img, search_region, confidence=.45))
            loot_screen_found = True if len(found) > 0 else False
            print(f'loot_screen_found: {loot_screen_found}')
            if loot_screen_found:
                loot_treasure(raid_info, inventory, areas, area_name, party,
                              tile_number, dungeon_path, debug)
    print('Activate Curio Complete!')
    # check for mission complete
    if (raid_info['raid_instance']['type'] == 'inventory_activate'
            and provision in Items and Items[provision]['type'] == 'quest'
            and sum(item.type == 'quest' for item in inventory.items) == 1):
        time.sleep(1.5)
        c.write(c.b, 2)
Пример #5
0
def solver():
    #get window to make sure its Kastia
    window = win32gui.GetForegroundWindow()
    active_window_name = win32gui.GetWindowText(window)
    captcha_label.config(text="Window not active, not scanning for captcha")
    if (active_window_name == "Kastia"):
        window_name = 'Kastia'
        wd = win32ui.FindWindow(None, window_name)
        try:
            captcha_label.config(text="Waiting for Captcha")
            dc = wd.GetWindowDC()
            x = 200
            y = 100
            while y <= 715:
                while x <= 800:
                    px = dc.GetPixel(x, y)
                    if px == ALARM:
                        if sample(dc, x, y):
                            ldfound = hard_check(dc, x, y)
                            if ldfound:
                                oldx = x
                                oldy = y
                                x, y = find_text_box_ul(dc, x, y)
                                if final_verification(dc, x, y) and blue_check(
                                        dc, x, y):
                                    #stop all movement (only necessary for swimming I think since this is full blocking function when detected)
                                    #if swimming checked stop movement and attacking
                                    pydirectinput.press('f3')
                                    if (swimc1.get() == 1
                                            or swimc2.get() == 1):
                                        pydirectinput.press('left')
                                        time.sleep(0.05)
                                        pydirectinput.press('right')
                                        time.sleep(0.05)
                                        pydirectinput.press(swim_entry.get())

                                    captcha_label.config(
                                        text=
                                        "Lie detector found!!!! Now solving captcha.."
                                    )
                                    print("LD Found")
                                    #print('Lie detector found!!!! Now solving captcha..')
                                    image_file_path = 'captcha.jpg'
                                    w_l, w_t, _, _ = wd.GetWindowRect()
                                    pic_x = x + w_l
                                    pic_y = y + w_t
                                    ld_captcha = ImageGrab.grab(
                                        bbox=(pic_x - 2, pic_y - 52,
                                              pic_x + 200, pic_y))
                                    ld_captcha.save(image_file_path, 'JPEG')
                                    #click on the text box to get ready for input
                                    pydirectinput.moveTo(
                                        pic_x + 75, pic_y + 10)
                                    time.sleep(1)
                                    pydirectinput.doubleClick()
                                    #update label with processing then process
                                    captcha_label.config(
                                        text="Processing Captcha")
                                    solved_captcha = solve_captcha(
                                        image_file_path)
                                    #process logic
                                    #processed with no output
                                    if solved_captcha == 'kekw':
                                        solved_captcha = ''
                                    #processed equation
                                    if '=' in solved_captcha:
                                        cut_string = solved_captcha.split('=')
                                        cut_string = cut_string[0]
                                        if 'x' in cut_string:
                                            number_set = cut_string.split('x')
                                            if len(number_set) >= 2:
                                                solved_captcha = str(
                                                    int(number_set[0]) *
                                                    int(number_set[1]))
                                        else:
                                            try:
                                                solved_captcha = str(
                                                    eval(cut_string))
                                            except:
                                                print(
                                                    "Failed solving math equation."
                                                )
                                    #click again just to make sure the mouse hasn't moved or something
                                    pydirectinput.moveTo(
                                        pic_x + 75, pic_y + 10)
                                    time.sleep(1)
                                    pydirectinput.doubleClick()
                                    #put detection here for if there is an error
                                    if (len(solved_captcha) < 7
                                            and solved_captcha != ''):
                                        for i in solved_captcha:
                                            try:
                                                i = i.lower()
                                            except:
                                                pass
                                            pydirectinput.press(i)
                                            time.sleep(.5)
                                        pydirectinput.press('enter')
                                        time.sleep(2)
                                        pydirectinput.press('enter')
                                    #update label with solved captcha
                                    captcha_label.config(
                                        text=str(solvedcaptcha))
                                    print(solvedcaptcha)
                                    #sleep for 2 seconds just so everything is good
                                    pydirectinput.doubleClick()
                                    pydirectinput.press('f3')
                                    time.sleep(2)

                                x = oldx
                                y = oldy
                    x += 60

                x = 350
                y += 5

        except:
            #put somehting here to detect
            pass

    root.after(1000, solver)
Пример #6
0
def main(save_editor_path, game_install_location, profile_number, battle_speed='safe',
         debug=False, test_lootscreen=False):
    global provisions_bought
    c = Controller(debug)

    # Import Settings if Applicable
    filepath = Path(f'{os.getcwd()}/settings.json')
    if os.path.exists(filepath):
        f = open(filepath)
        settings = json.load(f)['settings']
        save_editor_path = settings['save_editor_path']
        game_install_location = settings['game_install_location']
        profile_number = settings['save_profile_number']
        battle_speed = settings['battle_speed']
        f.close()

    # Initialize Save File Reader
    sfr = SaveFileReader(save_editor_path, game_install_location, profile_number)

    if not debug:
        # Make Darkest Dungeon the active window
        dd_window = win32gui.FindWindowEx(0, 0, 0, "Darkest Dungeon")
        win32gui.SetForegroundWindow(dd_window)
        pydirectinput.doubleClick(x=1050, y=500)
        pydirectinput.doubleClick(x=1050, y=500)

    while True:
        print('Beginning main loop ...')
        sfr.decrypt_save_info('persist.game.json')
        f = open(Path(f'{sfr.SaveEditorPath}/persist.game.json'))
        info = json.load(f)['base_root']
        f.close()

        # In Dungeon
        if info['inraid']:
            # if ModsCheck is False:
            #     ModsCheck = True
            #     if 'applied_ugcs_1_0' in info:
            #         installed_mods = info['applied_ugcs_1_0']
            #         battle_speed = 'fast' \
            #             if any(mod['name'] == '885957080' for mod in installed_mods.values()) else 'safe'

            sfr.decrypt_save_info('persist.raid.json')
            f = open(Path(f'{sfr.SaveEditorPath}/persist.raid.json'))
            raid_info = json.load(f)['base_root']
            f.close()
            inventory = Inventory(raid_info)

            # Get party info
            sfr.decrypt_save_info('persist.roster.json')
            f = open(Path(f'{sfr.save_editor_path()}/persist.roster.json'))
            roster_info = json.load(f)['base_root']
            f.close()
            party_order = raid_info['party']['heroes']  # [front - back]
            party_info = Party(roster_info, party_order)

            # Separate utility for testing pattern recognition with saved lootscreen images
            # - problem with screen grab where it doesn't capture all windows including the loot window. Need to
            #   deselect and reselect darkest dungeon window in order to capture curio/loot window if not already
            #   open when starting the program (see activate_curio())
            # - second problem with pattern recognition accuracy not being good enough to classify items
            #  (not even close, see loot_treasure() for more details)
            if test_lootscreen:
                print('Testing loot screen capture!')
                search_region = rf'{sfr.save_editor_path()}\search_region.png'
                loot_img = rf'{sfr.game_install_location()}\scrolls\byhand.png'
                # use_item_img = rf'{sfr.game_install_location()}\scrolls\use_inventory.png'

                if not debug:
                    # Make Darkest Dungeon the active window
                    dd_window = win32gui.FindWindowEx(0, 0, 0, "Darkest Dungeon")
                    win32gui.SetForegroundWindow(dd_window)
                    pydirectinput.doubleClick(x=1050, y=500)
                    pydirectinput.doubleClick(x=1050, y=500)

                    if os.path.exists(search_region):
                        os.remove(search_region)
                    # pyautogui.screenshot(search_region, region=(1300, 425, 100, 150))
                    pyautogui.screenshot(search_region, region=(1060, 400, 585, 215))
                # found = list(pyautogui.locateAll(use_item_img, search_region, confidence=.8))
                found = list(pyautogui.locateAll(loot_img, search_region, confidence=.45))
                loot_screen_found = True if len(found) > 0 else False
                print(f'Found loot screen = {loot_screen_found}')

                if loot_screen_found:
                    dungeon_name = raid_info['raid_instance']['dungeon']
                    loot = identify_lootscreen_items(search_region, dungeon_name, party=party_info.heroes)
                    for item in loot:
                        print(f'item: {item.name}, quantity: {item.quantity}, slot: {item.item_slot}')
                return

            # Take action in Dungeon
            if raid_info['inbattle']:
                battle(inventory, battle_speed, debug)
            else:
                # Determine Dungeon location
                map_file = 'persist.map.json'
                sfr.decrypt_save_info(map_file)
                # map_file = 'map.json'  # can provide an alternate map file for debugging DungeonPath
                f = open(Path(f'{sfr.save_editor_path()}/{map_file}'))
                map_info = json.load(f)['base_root']
                f.close()
                areas = map_info['map']['static_dynamic']['areas']
                static_areas = map_info['map']['static_dynamic']['static_save']['base_root']['areas']
                location_number = raid_info['in_area']  # 1111584611
                location = next(index for index, area in areas.items() if static_areas[index]['id'] == location_number)

                # Used to debug droppable_items
                # dungeon_name = raid_info['raid_instance']['dungeon']
                # droppable_items = get_droppable_items(raid_info, areas, inventory, dungeon_name, party_info.heroes)
                # return

                # Check for loot screen
                queued_loot = raid_info['loot']['queue_items']['items']
                battle_reward = raid_info['loot']['result']['inventory_system']['items'] \
                    if 'result' in raid_info['loot'] else []
                if len(queued_loot) > 0 or len(battle_reward) > 0:
                    areas = map_info['map']['static_dynamic']['areas']
                    if location.startswith('co'):
                        static_tiles = static_areas[location]['tiles']
                        hallway_length = len(static_tiles) - 1
                        last_room_number = raid_info['last_room_id']  # 1111584611
                        reverse = last_room_number != static_tiles['tile0']['door_to']['area_to']
                        party_tile = get_party_tile(raid_info, hallway_length, reverse)
                    else:
                        party_tile = 0
                    dungeon_path, _ = get_dungeon_path(raid_info, static_areas, location)
                    loot_treasure(raid_info, inventory, areas, location, party_info.heroes,
                                  tile_number=party_tile, dungeon_path=dungeon_path, debug=debug)
                    sfr.decrypt_save_info('persist.raid.json')
                    f = open(Path(f'{sfr.SaveEditorPath}/persist.raid.json'))
                    raid_info = json.load(f)['base_root']
                    f.close()
                    inventory = Inventory(raid_info)  # important, need to check inventory again after looting

                time.sleep(.5)  # give enough time for loot/curio screen to close and mission complete to open
                c.write(c.b, 4)  # close out of menu (e.g. mission complete)
                time.sleep(.2)  # give enough time for mission complete screen to close

                navigate_dungeon(raid_info, areas, static_areas, inventory, party_info, location, debug)

        # In Town
        elif not info['inraid'] and not provisions_bought:
            # buy_provisions(dungeon_name, length, difficulty, debug)
            # provisions_bought = True

            # elif not info['inraid'] and provisions_bought:
            break
    print('DD bot finished!')