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()
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)
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)
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)
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!')