Esempio n. 1
0
def solve(img, model, sc_func, click_func):
    index = 1
    attempted_words = {}
    prev_search_word = "" # This is just for logging.
    while True: # DSF-ish traversal of possible passwords.
        characters = password_features.get_password(img, model)
        match = word_matching_prefix(characters[:index])
        attemp_prefix = characters[:index-1]
        attempts = get_attempts(attemp_prefix, attempted_words)
        if attempts > 5:
            index -= 1
        while match is not None:
            if match != prev_search_word:
                log(f"Attempting to write '{match}'", LOG_DEBUG, "Password")
            prev_search_word = match
            if index == 5:
                return True # Match found.
            index += 1
            match = word_matching_prefix(characters[:index])
        if index == 0: # No passwords were found.
            break
        if attempts == 0:
            attempted_words[attemp_prefix] = 1
        else:
            attempted_words[attemp_prefix] += 1
        get_next_char(index-1, click_func)
        sc = sc_func()[0]
        img = features_util.convert_to_cv2(sc)
    return False
Esempio n. 2
0
 def monitor(self):
     _, SH = get_screen_size()
     lo = (30, 30, 30)
     hi = (255, 255, 255)
     self.change_event.set()
     while self.is_active:
         sc = screenshot(0, SH - 200, 200, 200)
         img = features_util.convert_to_cv2(sc)
         rgb = features_util.split_channels(img)
         if self.lights_on:
             if not features_util.color_in_range(self.pixel, rgb, lo, hi):
                 if self.bomb_exploded(rgb):  # We died :(
                     self.is_active = False
                     self.exit_after_explosion()
                 else:
                     log("Lights in the room are turned off. Pausing execution temporarily..."
                         )
                     self.lights_on = False
                     self.change_event.clear()
                     sleep(1)
         else:
             if features_util.color_in_range(self.pixel, rgb, lo, hi):
                 log("Lights in the room are turned back on. Resuming...")
                 self.change_event.set()
                 self.lights_on = True
                 sleep(1)
         sleep(0.25)
Esempio n. 3
0
def identify_side_features(sides, model):
    flattened = []
    for side in sides:
        for img in side:
            converted = dataset_util.reshape(convert_to_cv2(img), config.MODULE_INPUT_DIM[1:])
            flattened.append(converted)
    preds = module_classifier.predict(model, array(flattened))
    predictions = classifier_util.get_best_prediction(preds)
    return predictions
Esempio n. 4
0
def solve_whos_on_first(image, char_model, mod_pos):
    mod_x, mod_y = mod_pos
    for i in range(3):
        coords = whos_first_solver.solve(image, char_model)
        y, x = coords
        win_util.click(x + mod_x, y + mod_y)
        if i < 2:
            sleep(3.5)
        image = convert_to_cv2(screenshot_module()[0])
Esempio n. 5
0
def solve_memory(image, char_model, mod_pos):
    mod_x, mod_y = mod_pos
    history = []
    for i in range(5):
        coords, label, position = memory_solver.solve(image, char_model, history)
        history.append((label, position))
        y, x = coords
        win_util.click(x + mod_x, y + mod_y)
        if i < 4:
            sleep(3.5)
        image = convert_to_cv2(screenshot_module()[0])
Esempio n. 6
0
def solve_simon(image, mod_pos, side_features):
    mod_x, mod_y = mod_pos
    num = 1
    while not simon_solver.is_solved(image):
        btn_coords = simon_solver.solve(image, screenshot_module, side_features, num)
        for coords in btn_coords:
            button_y, button_x = coords
            win_util.click(mod_x + button_x, mod_y + button_y)
            sleep(0.5)
        num += 1
        SC, _, _ = screenshot_module()
        image = convert_to_cv2(SC)
Esempio n. 7
0
def solve_wire_sequence(image, mod_pos):
    mod_x, mod_y = mod_pos
    button_x, button_y = 128 + mod_x, 248 + mod_y
    color_hist = [0, 0, 0]
    for i in range(4):
        wires_to_cut, color_hist, coords = wire_seq_solver.solve(image, color_hist)
        for j, cut in enumerate(wires_to_cut):
            if cut:
                y, x = coords[j]
                win_util.click(mod_x + x, mod_y + y)
                sleep(0.5)
        win_util.click(button_x, button_y)
        if i < 3:
            sleep(1.8)
        image = convert_to_cv2(screenshot_module()[0])
Esempio n. 8
0
def solve_needy_modules(modules, needy_indices, curr_module, duration):
    SW, SH = win_util.get_screen_size()
    prev_index = curr_module
    timestamp = None
    for index in needy_indices:
        if (index > 5) ^ (prev_index > 5):  # Flip the bomb, if needed.
            inspect_bomb.flip_bomb(SW, SH)
            sleep(0.75)
            win_util.mouse_up(SW // 2, SH // 2, btn="right")
            sleep(0.5)
        mod_index = index if index < 6 else index - 6
        label = modules[index]
        select_module(mod_index)
        add_overlay_properties("module_info", (label))
        SC, x, y = screenshot_module()
        mod_pos = (x, y)
        cv2_img = convert_to_cv2(SC)
        mod_name = module_classifier.LABELS[label]
        log(f"Solving {mod_name}...")
        try:
            if label == 20:  # Needy Vent Gas.
                solve_needy_vent(cv2_img, mod_pos)
            elif label == 21:  # Needy Discharge Capacitor.
                solve_needy_discharge(cv2_img, mod_pos)
            elif label == 22:  # Solve Knob.
                solve_needy_knob(cv2_img, mod_pos)
        except KeyboardInterrupt:
            handle_module_exception(mod_name, cv2_img)
            raise KeyboardInterrupt
        except Exception:
            handle_module_exception(mod_name, cv2_img)
        if timestamp is None:
            cooldown_time = 5
            timestamp = time() + cooldown_time
        sleep(0.5)
        deselect_module()
        prev_index = index
    # Flip the bomb back to it's original state, if needed.
    if (curr_module > 5) ^ (prev_index > 5):
        inspect_bomb.flip_bomb(SW, SH)
        sleep(0.75)
        win_util.mouse_up(SW // 2, SH // 2, btn="right")
        sleep(0.5)
    return timestamp
Esempio n. 9
0
def solve_button(image, mod_pos, side_features, character_model, duration):
    mod_x, mod_y = mod_pos
    hold = button_solver.solve(image, side_features, character_model)
    button_x, button_y = mod_x + 125, mod_y + 175
    if not hold:
        log(f"Tapping button.", config.LOG_DEBUG, "Button")
        win_util.click(button_x, button_y)
        sleep(0.5)
    else:
        log(f"Holding button...", config.LOG_DEBUG, "Button")
        win_util.mouse_move(button_x, button_y)
        win_util.mouse_down(button_x, button_y)
        sleep(0.9)  # 48 frames until strip lights up.
        SC, _, _ = screenshot_module()
        image = convert_to_cv2(SC)
        pixel = (184, 255)
        release_time = button_solver.get_release_time(image, pixel)
        log(f"Release button at {release_time}", config.LOG_DEBUG, "Button")
        release_mouse_at(release_time, duration, button_x, button_y)
Esempio n. 10
0
def process_module_data(images, predictions=None):
    IMAGES_CAPTURED = 0
    for i, img in enumerate(images):
        cv2_img = convert_to_cv2(img)
        path = None
        if predictions is not None:
            label = predictions[i]
            if label in INCLUDED_LABELS:
                label_name = clean_file_path(classifier.LABELS[label])
                path = f"../resources/training_images/{label_name}/"
                if not os.path.exists(path):
                    os.mkdir(path)
        else:
            path = f"../resources/training_images/"
        if path is not None:
            num_images = len(glob(path + "*.png"))
            imwrite(f"{path}{num_images:03d}.png", cv2_img)
            IMAGES_CAPTURED += 1

    log(f"Captured {IMAGES_CAPTURED} module images.")
Esempio n. 11
0
def extract_side_features(sides, labels, character_model):
    index = 0
    features = {"indicators": [], "parallel_port": False, "batteries": 0}
    for side in sides:
        for img in side:
            cv2_img = convert_to_cv2(img)
            mod_name = module_classifier.LABELS[labels[index]]
            try:
                if labels[index] == 1:  # Single battery (large or small).
                    features["batteries"] += 1
                elif labels[index] == 2:  # Double batteries.
                    features["batteries"] += 2
                elif labels[index] == 3:  # Serial number.
                    serial_num = get_serial_number(cv2_img, character_model)
                    if serial_num is None:
                        log(f"Serial number could not be determined.",
                            config.LOG_WARNING)
                        index += 1
                        continue
                    log(f"Serial number: {serial_num}",
                        verbose=config.LOG_DEBUG)
                    features["serial_number"] = serial_num
                    serial_features = extract_serial_number_features(
                        serial_num)
                    features.update(serial_features)
                elif labels[index] == 5:  # Parallel port.
                    features["parallel_port"] = True
                elif labels[index] == 6:  # Indicator of some kind.
                    lit, text = get_indicator_features(cv2_img,
                                                       character_model)
                    desc = "lit_" + text if lit else "unlit_" + text
                    features["indicators"].append(desc)
            except KeyboardInterrupt:
                handle_module_exception(mod_name, cv2_img)
                raise KeyboardInterrupt
            except Exception:
                handle_module_exception(mod_name, cv2_img)
            index += 1
    return features
Esempio n. 12
0
def process_bomb_data(images):
    IMAGES_CAPTURED = 0
    predictions = []
    for img in images:
        cv2_img = convert_to_cv2(img)
        path = f"../resources/training_images/"
        if AUTO_LABEL:
            resized = dataset_util.reshape(cv2_img, config.MODULE_INPUT_DIM[1:])
            pred = classifier.predict(MODEL, resized)
            label = classifier_util.get_best_prediction(pred)[0]
            predictions.append(label)
            if label in INCLUDED_LABELS:
                if label < 7:
                    label_name = clean_file_path(classifier.LABELS[label])
                    path = f"{path}{label_name}/"
        if DATA_TYPE != "modules":
            num_images = len(glob(path + "*.png"))
            imwrite(f"{path}{num_images:03d}.png", cv2_img)
            IMAGES_CAPTURED += 1

    log(f"Captured {IMAGES_CAPTURED} bomb images.")
    return predictions
Esempio n. 13
0
def solve_modules(modules, side_features, character_model, symbol_model,
                  duration):
    # Get list of indexes of needy modules (all modules an index over 19).
    needy_indices = list(
        filter(lambda i: modules[i] > 19, [x for x in range(len(modules))]))
    needy_timestamp = duration[0]
    module_durations = [2, 5, 2, 12, 10, 2, 14, 8, 8, 8, 20]
    log(f"Needy modules: {len(needy_indices)}", config.LOG_DEBUG)

    solved_modules = 0
    num_modules = len(list(filter(lambda x: 8 < x < 20, modules)))
    module = 0
    while module < len(modules):
        label = modules[module]
        LIGHT_MONITOR.wait_for_light()  # If the room is dark, wait for light.
        mod_index = module if module < 6 else module - 6
        bomb_solved = solved_modules == num_modules
        mod_duration = 2 if label > 19 else module_durations[label - 9]
        critical = needy_modules_critical(len(needy_indices), needy_timestamp,
                                          mod_duration)
        if not bomb_solved and critical:
            # Needy modules need attention! Solve them, and continue where we left off.
            needy_timestamp = solve_needy_modules(modules, needy_indices,
                                                  module, needy_timestamp)

        if 8 < label < 20:
            select_module(mod_index)
            SC, x, y = screenshot_module()
            #add_overlay_properties("module_selected", (x, y, mod_index))
            mod_pos = (x, y)
            cv2_img = convert_to_cv2(SC)
            mod_name = module_classifier.LABELS[label]
            log(f"Solving {mod_name}...")
            try:
                if label == 9:  # Wires.
                    solve_wires(cv2_img, mod_pos, side_features)
                elif label == 10:  # Button.
                    solve_button(cv2_img, mod_pos, side_features,
                                 character_model, duration)
                elif label == 11:  # Symbols.
                    solve_symbols(cv2_img, mod_pos, symbol_model)
                elif label == 12:  # Simon Says.
                    solve_simon(cv2_img, mod_pos, side_features)
                elif label == 13:  # Wire Sequence.
                    solve_wire_sequence(cv2_img, mod_pos)
                elif label == 14:  # Complicated Wires.
                    solve_complicated_wires(cv2_img, mod_pos, side_features)
                elif label == 15:  # Memory Game.
                    solve_memory(cv2_img, character_model, mod_pos)
                elif label == 16:  # Who's on First?
                    solve_whos_on_first(cv2_img, character_model, mod_pos)
                elif label == 17:  # Maze.
                    solve_maze(cv2_img, mod_pos)
                elif label == 18:  # Password.
                    solve_password(cv2_img, character_model, mod_pos)
                elif label == 19:  # Morse.
                    solve_morse(cv2_img, mod_pos)
                solved_modules += 1
            except KeyboardInterrupt:  # Bomb 'sploded.
                handle_module_exception(mod_name, cv2_img)
                raise KeyboardInterrupt
            except Exception:
                # If an exception happened while lights were off, we try again.
                if not LIGHT_MONITOR.lights_on:
                    log("Exception while light was off. We try again in a bit!"
                        )
                    deselect_module()
                    continue
                handle_module_exception(mod_name, cv2_img)

            sleep(0.1)
            deselect_module()

        if module == 5 and solved_modules != num_modules:
            # We have gone through all modules on one side of the bomb, flip it over and continue.
            SW, SH = win_util.get_screen_size()
            inspect_bomb.flip_bomb(SW, SH)
            sleep(0.75)
            win_util.mouse_up(SW // 2, SH // 2, btn="right")
            sleep(0.5)

        module += 1
    if solved_modules == num_modules:
        log("We did it! We live to defuse another bomb!")
    else:
        log("Some modules could not be disarmed, it seems we are doomed...")
        raise KeyboardInterrupt  # We failed.