Esempio n. 1
0
class NinSwitchSimpleGame(Game):
    async def on_init(self):
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()

        self.io.register_inputs(
            {
                "left_joystick": NSJoystick(
                    self.nsg.leftXAxis, self.nsg.leftYAxis
                ),
                "right_joystick": NSJoystick(
                    self.nsg.rightXAxis, self.nsg.rightYAxis
                ),
                "dpad_up": NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left": NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right": NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down": NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y": NSSwitch(self.nsg, NSButton.Y),
                "X": NSSwitch(self.nsg, NSButton.X),
                "A": NSSwitch(self.nsg, NSButton.A),
                "B": NSSwitch(self.nsg, NSButton.B),
                "left_throttle": NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger": NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle": NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger": NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus": NSSwitch(self.nsg, NSButton.MINUS),
                "plus": NSSwitch(self.nsg, NSButton.PLUS),
                "left_stick": NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick": NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
            },
        )

    """
    here you could do something with
    on_config, on_prepare, on_pre_game, on_countdown, on_start...
    """

    async def on_prepare(self):
        await reset_trinket()

    async def on_finish(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()

    async def on_exit(self, reason, exception):
        # end controls
        self.nsg.end()
Esempio n. 2
0
class NinSwitchWeplayGame(Game):
    async def on_init(self):
        # init controls
        # connect to pigpio daemon

        self.pi = pigpio.pi()
        if not self.pi.connected:
            raise RuntimeError("Could not connect to pigpio")

        # init joystick splitter, enable physical joystick by default
        self.pi.set_mode(20, pigpio.OUTPUT)
        self.pi.set_mode(21, pigpio.OUTPUT)
        self.pi.write(20, 1)
        self.pi.write(21, 1)
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick":
                NSJoystick(self.nsg.leftXAxis, self.nsg.leftYAxis),
                "right_joystick":
                NSJoystick(self.nsg.rightXAxis, self.nsg.rightYAxis),
                "dpad_up":
                NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left":
                NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right":
                NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down":
                NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y":
                NSSwitch(self.nsg, NSButton.Y),
                "X":
                WeplayXSwitch(self.nsg, NSButton.X),
                "A":
                WeplayASwitch(self.nsg, NSButton.A),
                "B":
                WeplayBSwitch(self.nsg, NSButton.B),
                "left_throttle":
                NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger":
                WeplayTriggerSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle":
                NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger":
                WeplayTriggerSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus":
                WeplayMinusSwitch(self.nsg, NSButton.MINUS),
                "plus":
                NSSwitch(self.nsg, NSButton.PLUS),
                "left_stick":
                NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick":
                NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "home":
                NSSwitch(self.nsg, NSButton.HOME),
                "capture":
                NSSwitch(self.nsg, NSButton.CAPTURE),
            }, )
        self.lock = asyncio.Lock()

        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")
        # get home current detector
        self.has_home_current_game_selected = get_pixel_detector(
            HOME_CURRENT_GAME_SELECTED_PIXELS, close=35)
        self.has_maybe_game_over = get_pixel_detector(MAYBE_GAME_OVER_PIXELS)

        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)
        self.inputs_can_be_enabled = False

        if SAVE_FRAMES:
            logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
            Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

        # single press B, this will exit MAP_MENU/ITEMS_MENU,
        # to PLAYING game_state (weplay_switches.py)
        logging.info("single pressing B to get away from menus")
        await single_press(NSButton.B, self.nsg)

    """
    here you could do something with
    on_config, on_prepare, on_pre_game, on_countdown, on_start...
    """

    async def on_config(self):
        async with self.lock:
            i = 0
            while not await self.is_home_current_selected():
                logging.info(
                    f"on_config: Not on Home, current game selected {i}.")
                if i >= 10:
                    logging.info("on_config: single pressing Home")
                    await single_press(NSButton.HOME, self.nsg)
                else:
                    await asyncio.sleep(1)
                i += 1
            logging.info("on_config: On Home, current game selected")

        # reset the board
        self.pi.write(20, 0)
        self.pi.write(21, 0)
        await asyncio.sleep(0.1)
        self.pi.write(20, 1)
        self.pi.write(21, 1)

    async def on_start(self):
        # this somehow enables the board after the reset?
        self.nsg.press(NSButton.A)
        self.nsg.release(NSButton.A)

        # exit home to the game
        logging.info("single pressing A")
        await single_press(NSButton.A, self.nsg, post_press_sleep=False)

        # make sure home is away
        # (three times because of failing frame reads...)
        while (await self.is_home_current_selected()
               or await self.is_home_current_selected()
               or await self.is_home_current_selected()):
            logging.info("Waiting for home to go away...")
            await asyncio.sleep(0.05)

        # give image rec some time to press retry from the game over screen
        await asyncio.sleep(0.4)

        # make sure game over is away
        # (three times because of failing frame reads...)
        while (await self.is_maybe_game_over()
               or await self.is_maybe_game_over()
               or await self.is_maybe_game_over()):
            logging.info("Waiting for Game Over to go away...")
            await asyncio.sleep(0.05)

        # enable playing
        async with self.lock:
            self.inputs_can_be_enabled = True
            self.io.enable_inputs()
            logging.info("Inputs enabled")

    async def on_finish(self):
        self.inputs_can_be_enabled = False
        self.io.disable_inputs()
        logging.info("on_finish: resetting inputs")
        self.nsg.releaseAll()

        async with self.lock:
            # why the first press does not work always?
            await single_press(NSButton.HOME, self.nsg)
            await asyncio.sleep(0.5)
            # the workaround...
            i = 0
            while not await self.is_home_current_selected():
                logging.info(
                    f"on_finish: Not on Home, current game selected {i}.")
                if i % 3 == 0:  # take failed frames into account
                    logging.info("on_finish: single pressing Home")
                    await single_press(NSButton.HOME, self.nsg)
                    await asyncio.sleep(1)
                else:
                    await asyncio.sleep(0.5)
                i += 1
            logging.info("on_finish: On Home, current game selected")

    async def on_exit(self, reason, exception):
        # end controls
        self.nsg.end()
        self.pi.stop()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

    async def is_home_current_selected(self):
        return self.has_home_current_game_selected(await self.cap.read())

    async def is_maybe_game_over(self):
        return self.has_maybe_game_over(await self.cap.read())

    async def image_rec_main(self):
        i = 0
        stop_frames = 0
        ongoing_auto_action = False
        async for frame in self.cap.frames():
            async with self.lock:
                detected = False
                for detector, actions in AUTO_ACTIONS.items():
                    if detector(frame):
                        detected = True
                        stop_frames = 0
                        if not ongoing_auto_action:
                            logging.info("Auto action started")
                            self.io.disable_inputs()
                            self.nsg.releaseAll()
                            ongoing_auto_action = True

                        for action in actions:
                            logging.info(f"pressing: {action}")
                            await single_press(action, self.nsg)

                if not detected and ongoing_auto_action:
                    stop_frames += 1
                    if stop_frames > ACTION_STOP_FRAMES_REQUIRED:
                        logging.info("Auto action stopped")
                        ongoing_auto_action = False
                        stop_frames = 0
                        if self.inputs_can_be_enabled:
                            logging.info("enabling inputs")
                            self.io.enable_inputs()
                    else:
                        logging.info(f"Action stop frame {stop_frames}.")

                if SAVE_FRAMES:
                    cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                    logging.info(f"SAVED {i}.jpg")
                i += 1

            await asyncio.sleep(0)  # might be redundant?

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error("".join(
                traceback.format_exception(None, e, e.__traceback__)))
            sys.exit(1)
class SAMPLE_ADVANCED_GAME(Game):
    async def on_init(self):
        self.prepare = True
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick":
                NSJoystick(self.nsg.leftXAxis, self.nsg.leftYAxis),
                "right_joystick":
                NSJoystick(self.nsg.rightXAxis, self.nsg.rightYAxis),
                "dpad_up":
                NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left":
                NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right":
                NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down":
                NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y":
                NSSwitch(self.nsg, NSButton.Y),
                "X":
                NSSwitch(self.nsg, NSButton.X),
                "A":
                NSSwitch(self.nsg, NSButton.A),
                "B":
                NSSwitch(self.nsg, NSButton.B),
                "left_throttle":
                NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger":
                NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle":
                NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger":
                NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "left_stick":
                NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick":
                NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "reset_trinkets":
                reset_trinkets(),
                "plus":
                NSSwitch(self.nsg, NSButton.PLUS),
            }, )
        self.io.register_inputs(
            {
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
                "debug_switch": debug_switch(),
                "capture_frame": CaptureScreen(),
                "minus": NSSwitch(self.nsg, NSButton.MINUS),
            },
            admin=True,
        )

        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)

        # init frame saving
        logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
        Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

        self.curUser = "******"
        self.userID = "eu-west-1:dummydummydummydummydummydummydummyd"

# ----------------------------------------------------

    async def on_start(self):
        self.curUser = self.players
        player = json.loads(json.dumps(self.players))[0]['username']

        req = requests.get(
            "https://g9b1fyald3.execute-api.eu-west-1.amazonaws.com/master/users?search="
            + str(player)).text
        uid = json.loads(req)['result'][0]['userId']
        self.userID = uid

# ----------------------------------------------------

    async def on_prepare(self):
        pi.write(nsg_reset, ON)
        await asyncio.sleep(0.5)
        pi.write(nsg_reset, OFF)
        await asyncio.sleep(2)

# ----------------------------------------------------

    async def on_finish(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()

        self.nsg.rightYAxis(128)
        self.nsg.rightXAxis(128)
        self.nsg.leftYAxis(128)
        self.nsg.leftXAxis(128)

        self.io.send_score(score=1, seat=0, final_score=True)

        self.prepare = True

# ----------------------------------------------------

    async def on_exit(self, reason, exception):
        # end controls
        self.io.disable_inputs()
        self.nsg.end()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

# ----------------------------------------------------

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        global LOCKED, allowReset, bypass, DEBUG
        LOCKED = False

        # get detector
        home = get_pixel_detector(HOME, 50)
        input_needed = get_pixel_detector(INPUT_NEEDED, 50)
        reconnected = get_pixel_detector(RECONNECTED, 50)
        settings = get_pixel_detector(SETTINGS, 50)
        title = get_pixel_detector(TITLE, 50)

        # loop through frames
        i = 0
        z = 0
        async for frame in self.cap.frames():
            # detect trigger
            if i % 30 == 0 and (input_needed(frame) or reconnected(frame)):
                pi.write(nsg_reset, ON)
                await asyncio.sleep(0.5)
                pi.write(nsg_reset, OFF)
                await asyncio.sleep(1)
            try:
                if (input_needed(frame) or reconnected(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)
            except:
                if (input_needed(frame) or reconnected(frame)) and not DEBUG:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)

            # lock trigger
            try:
                if (home(frame) or settings(frame)
                        or title(frame)) and not LOCKED and not DEBUG:
                    self.io.disable_input(0)
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "ANIMAL CROSSING\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                        content = json.loads('{"game":"crossing"}')
                        req = requests.post("[REDACTED]", content)
                    else:
                        msg = "ANIMAL CROSSING\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True
                        content = json.loads('{"game":"crossing"}')
                        req = requests.post("[REDACTED]", content)
            except:
                if (home(frame) or settings(frame)
                        or title(frame)) and not LOCKED and not DEBUG:
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "ANIMAL CROSSING\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                        content = json.loads('{"game":"crossing"}')
                        req = requests.post("[REDACTED]", content)
                    else:
                        msg = "ANIMAL CROSSING\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True
                        content = json.loads('{"game":"crossing"}')
                        req = requests.post("[REDACTED]", content)

            if LOCKED:
                self.io.send_playing_ended()
                self.prepare = True

            # generic
            if i % 100 == 0:
                allowReset = True
            if SAVE_ALL_FRAMES or save_individual_fame:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                logging.info(f"SAVED {i}.jpg")
            i += 1


# ----------------------------------------------------

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error("".join(
                traceback.format_exception(None, e, e.__traceback__)))
            sys.exit(1)
Esempio n. 4
0
class SAMPLE_ADVANCED_GAME(Game):
    async def on_init(self):
        self.prepare = True
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick":
                NSJoystick(self.nsg.leftXAxis, self.nsg.leftYAxis),
                "right_joystick":
                NSJoystick(self.nsg.rightXAxis, self.nsg.rightYAxis),
                "dpad_up":
                NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left":
                NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right":
                NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down":
                NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y":
                NSSwitch(self.nsg, NSButton.Y),
                "X":
                NSSwitch(self.nsg, NSButton.X),
                "A":
                NSSwitch(self.nsg, NSButton.A),
                "B":
                NSSwitch(self.nsg, NSButton.B),
                "left_throttle":
                NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger":
                NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle":
                NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger":
                NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus":
                NSSwitch(self.nsg, NSButton.MINUS),
                "left_stick":
                NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick":
                NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "capture_frame":
                CaptureScreen(),
                "reset_trinkets":
                reset_trinkets(),
            }, )
        self.io.register_inputs(
            {
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
                "debug_switch": debug_switch(),
                "plus": NSSwitch(self.nsg, NSButton.PLUS),
            },
            admin=True,
        )

        self.curUser = "******"
        self.userID = "eu-west-1:dummydummydummydummydummydummydummyd"
        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)

        # init frame saving
        logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
        Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

# ----------------------------------------------------

    async def on_start(self):
        self.curUser = self.players
        player = json.loads(json.dumps(self.players))[0]['username']

        req = requests.get(
            "https://g9b1fyald3.execute-api.eu-west-1.amazonaws.com/master/users?search="
            + str(player)).text
        uid = json.loads(req)['result'][0]['userId']
        self.userID = uid

# ----------------------------------------------------

    async def on_pre_game(self):
        self.io.send_pre_game_not_ready()
        self.nsg.press(NSButton.B)
        await asyncio.sleep(0.1)
        self.nsg.release(NSButton.B)
        await asyncio.sleep(1)
        self.io.send_pre_game_ready()

# ----------------------------------------------------

    async def on_prepare(self):
        pi.write(nsg_reset, ON)
        await asyncio.sleep(0.5)
        pi.write(nsg_reset, OFF)
        await asyncio.sleep(2)

        self.prepare = True

        while self.prepare:
            await asyncio.sleep(3)

# ----------------------------------------------------

    async def on_finish(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()

        self.nsg.rightYAxis(128)
        self.nsg.rightXAxis(128)
        self.nsg.leftYAxis(128)
        self.nsg.leftXAxis(128)

        self.io.send_score(score=1, seat=0, final_score=True)

        self.prepare = True
        self.knownIndex = 0

# ----------------------------------------------------

    async def on_exit(self, reason, exception):
        # end controls
        self.io.disable_inputs()
        self.nsg.end()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

# ----------------------------------------------------

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        global LOCKED, allowReset, bypass, DEBUG
        LOCKED = False

        # get detector
        controller_dc_game_detec = get_pixel_detector(
            CONTROLLER_DC_GAME_DETECT, 50)
        controller_dc_input_needed = get_pixel_detector(
            CONTROLLER_DC_INPUT_NEEDED, 50)
        controller_dc_reconnect = get_pixel_detector(CONTROLLER_DC_RECONNECT,
                                                     50)

        game_pause_menu = get_pixel_detector(GAME_PAUSE_MENU, 75)
        game_settings_menu = get_pixel_detector(GAME_SETTINGS_MENU, 50)

        inventory_condenced = get_pixel_detector(INVENTORY_CONDENCED, 50)
        inventory_extended = get_pixel_detector(INVENTORY_EXTENDED, 50)

        game_main_menu = get_pixel_detector(GAME_MAIN_MENU, 50)
        game_main_menu_world = get_pixel_detector(GAME_MAIN_MENU_WORLD, 50)
        home_menu = get_pixel_detector(HOME_MENU, 50)
        settings_menu = get_pixel_detector(SETTINGS_MENU, 50)

        you_died_left = get_pixel_detector(YOU_DIED_LEFT, 50)
        you_died_right = get_pixel_detector(YOU_DIED_RIGHT, 50)
        sure_quit_confirm = get_pixel_detector(SURE_QUIT_CONFIRM, 50)
        sure_quit_cancel = get_pixel_detector(SURE_QUIT_CANCEL, 50)

        # loop through frames
        i = 0
        z = 0
        async for frame in self.cap.frames():
            # detect trigger
            if i % 30 == 0 and (controller_dc_game_detec(frame)
                                or controller_dc_input_needed(frame)
                                or controller_dc_reconnect(frame) or
                                you_died_left(frame) or you_died_right(frame)
                                or sure_quit_cancel(frame)
                                or sure_quit_confirm(frame)) and not DEBUG:
                pi.write(nsg_reset, ON)
                await asyncio.sleep(0.5)
                pi.write(nsg_reset, OFF)
                await asyncio.sleep(1)
            try:
                if (controller_dc_game_detec(frame)
                        or controller_dc_input_needed(frame)
                        or controller_dc_reconnect(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)
            except:
                if (controller_dc_game_detec(frame)
                        or controller_dc_input_needed(frame)
                        or controller_dc_reconnect(frame)) and not DEBUG:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)

            try:
                if (you_died_left(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)

                if (you_died_right(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.leftXAxis(0)
                    self.nsg.leftYAxis(128)
                    await asyncio.sleep(0.1)
                    self.nsg.leftXAxis(128)
                    self.nsg.leftYAxis(128)
                    await asyncio.sleep(0.1)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)

                if (sure_quit_confirm(frame)
                        or sure_quit_cancel(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)

            except:
                if (you_died_left(frame)) and not DEBUG:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)

                if (you_died_right(frame)) and not DEBUG:
                    self.nsg.leftXAxis(0)
                    self.nsg.leftYAxis(128)
                    await asyncio.sleep(0.1)
                    self.nsg.leftXAxis(128)
                    self.nsg.leftYAxis(128)
                    await asyncio.sleep(0.1)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)

                if (sure_quit_confirm(frame)
                        or sure_quit_cancel(frame)) and not DEBUG:
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(2)

            # Get to pause frames...Update as needed
            if (self.prepare and not (game_pause_menu(frame))
                    and not LOCKED) and not DEBUG:
                if z % 3 == 2:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(1)
                elif z % 3 == 1:
                    self.nsg.press(NSButton.PLUS)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.PLUS)
                    await asyncio.sleep(2)
                z += 1
            elif not LOCKED:
                z = 0
                self.prepare = False

            # lock trigger
            try:
                if (game_main_menu(frame) or game_main_menu_world(frame)
                        or home_menu(frame)
                        or settings_menu(frame)) and not LOCKED and not DEBUG:
                    self.io.disable_input(0)
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "MINECRAFT\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                    else:
                        msg = "MINECRAFT\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True
            except:
                if (game_main_menu(frame) or game_main_menu_world(frame)
                        or home_menu(frame)
                        or settings_menu(frame)) and not LOCKED and not DEBUG:
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "MINECRAFT\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                    else:
                        msg = "MINECRAFT\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True

            if LOCKED:
                self.io.send_playing_ended()
                self.prepare = True

            # generic
            if i % 100 == 0:
                allowReset = True
            if SAVE_ALL_FRAMES or save_individual_fame:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                logging.info(f"SAVED {i}.jpg")
            i += 1


# ----------------------------------------------------

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error("".join(
                traceback.format_exception(None, e, e.__traceback__)))
            sys.exit(1)
class NinSwitchImageRecGame(Game):
    async def on_init(self):
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick": NSJoystick(
                    self.nsg.leftXAxis, self.nsg.leftYAxis
                ),
                "right_joystick": NSJoystick(
                    self.nsg.rightXAxis, self.nsg.rightYAxis
                ),
                "dpad_up": NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left": NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right": NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down": NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y": NSSwitch(self.nsg, NSButton.Y),
                "X": NSSwitch(self.nsg, NSButton.X),
                "A": NSSwitch(self.nsg, NSButton.A),
                "B": NSSwitch(self.nsg, NSButton.B),
                "left_throttle": NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger": NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle": NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger": NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus": NSSwitch(self.nsg, NSButton.MINUS),
                "plus": NSSwitch(self.nsg, NSButton.PLUS),
                "left_stick": NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick": NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
            },
        )
        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)

        # init frame saving
        if SAVE_FRAMES:
            logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
            Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

    """
    here you could do something with
    on_config, on_prepare, on_pre_game, on_countdown, on_start...
    """

    async def on_finish(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()

    async def on_exit(self, reason, exception):
        # end controls
        self.nsg.end()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        # get detector
        has_flag = get_pixel_detector(FLAG_PIXELS)

        # loop through frames
        i = 0
        async for frame in self.cap.frames():
            # detect
            if has_flag(frame):
                logging.info("Has flag!")
            else:
                logging.info("Doesn't have flag")

            # generic
            if i % 100 == 0:
                logging.info("100 frames checked")
            if SAVE_FRAMES:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                logging.info(f"SAVED {i}.jpg")
            i += 1

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error(
                "".join(traceback.format_exception(None, e, e.__traceback__))
            )
            sys.exit(1)
Esempio n. 6
0
class SAMPLE_ADVANCED_GAME(Game):
    async def on_init(self):
        self.prepare = True
        self.started = False
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick":
                NSJoystick(self.nsg.leftXAxis, self.nsg.leftYAxis),
                "right_joystick":
                NSJoystick(self.nsg.rightXAxis, self.nsg.rightYAxis),
                "dpad_up":
                NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left":
                NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right":
                NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down":
                NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y":
                NSSwitch(self.nsg, NSButton.Y),
                "X":
                NSSwitch(self.nsg, NSButton.X),
                "A":
                NSSwitch(self.nsg, NSButton.A),
                "B":
                NSSwitch(self.nsg, NSButton.B),
                "left_throttle":
                NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger":
                NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle":
                NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger":
                NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus":
                NSSwitch(self.nsg, NSButton.MINUS),
                "left_stick":
                NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick":
                NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "capture_frame":
                CaptureScreen(),
                "reset_trinkets":
                reset_trinkets(),
                "plus":
                NSSwitch(self.nsg, NSButton.PLUS),
            }, )
        self.io.register_inputs(
            {
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
                "debug_switch": debug_switch(),
            },
            admin=True,
        )

        self.curUser = "******"
        self.userID = "eu-west-1:dummydummydummydummydummydummydummyd"
        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)

        # init frame saving
        logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
        Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

# ----------------------------------------------------

    async def on_start(self):
        self.curUser = self.players
        player = json.loads(json.dumps(self.players))[0]['username']

        req = requests.get(
            "https://g9b1fyald3.execute-api.eu-west-1.amazonaws.com/master/users?search="
            + str(player)).text
        uid = json.loads(req)['result'][0]['userId']
        self.userID = uid
        self.started = True
        self.prepare = False

# ----------------------------------------------------

    async def on_pre_game(self):
        self.io.send_pre_game_not_ready()
        self.nsg.press(NSButton.B)
        await asyncio.sleep(0.1)
        self.nsg.release(NSButton.B)
        await asyncio.sleep(0.5)
        self.nsg.press(NSButton.Y)
        await asyncio.sleep(0.1)
        self.nsg.release(NSButton.Y)
        await asyncio.sleep(0.5)
        self.io.send_pre_game_ready()

# ----------------------------------------------------

    async def on_prepare(self):
        pi.write(nsg_reset, ON)
        await asyncio.sleep(0.5)
        pi.write(nsg_reset, OFF)
        await asyncio.sleep(2)

        self.prepare = True
        self.started = False

        while self.prepare:
            await asyncio.sleep(3)

# ----------------------------------------------------

    async def on_finish(self):
        self.prepare = True
        self.started = False
        self.io.disable_inputs()
        global LOCKED
        if not LOCKED:
            self.nsg.releaseAll()
            self.nsg.rightYAxis(128)
            self.nsg.rightXAxis(128)
            self.nsg.leftYAxis(128)
            self.nsg.leftXAxis(128)

        self.io.send_score(score=1, seat=0, final_score=True)

        self.knownIndex = 0

# ----------------------------------------------------

    async def on_exit(self, reason, exception):
        # end controls
        self.io.disable_inputs()
        global LOCKED
        if not LOCKED:
            self.nsg.end()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

# ----------------------------------------------------

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        global LOCKED, allowReset, bypass, DEBUG
        LOCKED = False

        controller_dc_input_needed = get_pixel_detector(
            CONTROLLER_DC_INPUT_NEEDED, 150)
        controller_dc_reconnect = get_pixel_detector(CONTROLLER_DC_RECONNECT,
                                                     100)

        b_menu = get_pixel_detector(B_MENU, 150)
        creation_body = get_pixel_detector(CREATION_BODY, 150)
        creation_brow = get_pixel_detector(CREATION_BROW, 150)
        creation_eyes = get_pixel_detector(CREATION_EYES, 150)
        creation_face = get_pixel_detector(CREATION_FACE, 150)
        creation_hair = get_pixel_detector(CREATION_HAIR, 150)
        creation_mouth = get_pixel_detector(CREATION_MOUTH, 150)
        creation_race = get_pixel_detector(CREATION_RACE, 150)

        plus_opening = get_pixel_detector(PLUS_OPENING,
                                          200)  # Need to allow for reasons
        plus_system = get_pixel_detector(PLUS_SYSTEM_GEN,
                                         200)  # Avoid if possible
        plus_system_2 = get_pixel_detector(PLUS_SYSTEM_2, 200)

        plus_general_stats = get_pixel_detector(PLUS_GENERAL_STATS,
                                                200)  # Disable going to System
        plus_quests = get_pixel_detector(PLUS_QUESTS,
                                         200)  # Disable going to system

        game_main_menu = get_pixel_detector(GAME_MAIN_MENU, 150)
        game_main_menu_2 = get_pixel_detector(GAME_MAIN_MENU_2, 150)
        home_menu = get_pixel_detector(HOME_MENU, 150)
        settings_menu = get_pixel_detector(SETTINGS_MENU, 150)

        # loop through frames
        i = 0
        z = 0
        async for frame in self.cap.frames():
            # detect trigger
            if i % 30 == 0 and (controller_dc_input_needed(frame) or
                                controller_dc_reconnect(frame)) and not DEBUG:
                pi.write(nsg_reset, ON)
                await asyncio.sleep(0.5)
                pi.write(nsg_reset, OFF)
                await asyncio.sleep(1)
            try:
                if (controller_dc_input_needed(frame)
                        or controller_dc_reconnect(frame)) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.io.enable_input(0)
            except:
                if (controller_dc_input_needed(frame)
                        or controller_dc_reconnect(frame)) and not DEBUG:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(2)

            try:
                if (self.started and (plus_system(frame)
                                      or plus_system_2(frame))) and not DEBUG:
                    self.io.disable_input(0)
                    self.nsg.press(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(1)
                    self.io.enable_input(0)
            except:
                if (self.started and (plus_system(frame)
                                      or plus_system_2(frame))) and not DEBUG:
                    self.nsg.press(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(1)

            if (self.prepare and b_menu(frame) and not LOCKED and not DEBUG):
                self.nsg.press(NSButton.B)
                await asyncio.sleep(0.1)
                self.nsg.release(NSButton.B)

            # Get to pause frames...Update as needed
            if (self.prepare and not (
                (plus_system(frame) or plus_system_2(frame)
                 or creation_body(frame) or creation_brow(frame)
                 or creation_eyes(frame) or creation_face(frame)
                 or creation_hair(frame) or creation_mouth(frame)
                 or creation_race(frame) or plus_general_stats(frame)
                 or plus_quests(frame))) and not LOCKED) and not DEBUG:
                if z % 3 == 2:
                    self.nsg.press(NSButton.A)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.A)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.B)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.B)
                    await asyncio.sleep(1)
                elif z % 3 == 1:
                    self.nsg.rightXAxis(255)
                    self.nsg.rightYAxis(128)
                    await asyncio.sleep(0.5)
                    self.nsg.rightXAxis(128)
                    self.nsg.rightYAxis(128)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.PLUS)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.PLUS)
                    await asyncio.sleep(1)
                    self.nsg.press(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(0.1)
                    self.nsg.release(NSButton.LEFT_THROTTLE)
                    await asyncio.sleep(1)
                z += 1
            elif not LOCKED:
                z = 0
                self.prepare = False

            # lock trigger
            try:
                if (game_main_menu(frame) or game_main_menu_2(frame)
                        or home_menu(frame)
                        or settings_menu(frame)) and not LOCKED and not DEBUG:
                    self.io.disable_input(0)
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "SKYRIM\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                        content = json.loads('{"game":"skyrim"}')
                        req = requests.post("[REDACTED]", content)
                    else:
                        msg = "SKYRIM\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True
                        content = json.loads('{"game":"skyrim"}')
                        req = requests.post("[REDACTED]", content)
            except:
                if (game_main_menu(frame) or game_main_menu_2(frame)
                        or home_menu(frame)
                        or settings_menu(frame)) and not LOCKED and not DEBUG:
                    if not (i < 100 or bypass):
                        player = json.loads(json.dumps(
                            self.curUser))[0]['username']
                        msg = "SKYRIM\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> " + player + "\n> " + self.userID
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        LOCKED = True
                        self.nsg.end()
                        self.prepare = False
                        content = json.loads('{"game":"skyrim"}')
                        req = requests.post("[REDACTED]", content)
                    else:
                        msg = "SKYRIM\nBypass utilized...Take action to get to a proper menu before something messes up."
                        bot.send_message(chat_id, msg, parse_mode="markdown")
                        bypass = True
                        DEBUG = True
                        LOCKED = True
                        content = json.loads('{"game":"skyrim"}')
                        req = requests.post("[REDACTED]", content)

            if LOCKED:
                self.io.send_playing_ended()
                self.prepare = True

            # generic
            if i % 100 == 0:
                allowReset = True
            if SAVE_ALL_FRAMES or save_individual_fame:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                logging.info(f"SAVED {i}.jpg")
            i += 1


# ----------------------------------------------------

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error("".join(
                traceback.format_exception(None, e, e.__traceback__)))
            sys.exit(1)
class NinSwitchIRLKart(Game):
    async def on_init(self):
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs({
            "left_joystick":
            NSJoystick(self.nsg.leftXAxis, self.nsg.leftYAxis),
            "dpad_up":
            NSDPadSwitch(self.nsg, NSDPad.UP),
            "dpad_left":
            NSDPadSwitch(self.nsg, NSDPad.LEFT),
            "dpad_right":
            NSDPadSwitch(self.nsg, NSDPad.RIGHT),
            "dpad_down":
            NSDPadSwitch(self.nsg, NSDPad.DOWN),
            "X":
            NSSwitch(self.nsg, NSButton.X),
            "A":
            NSSwitch(self.nsg, NSButton.A),
            "B":
            NSSwitch(self.nsg, NSButton.B),
            "left_throttle":
            NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
            "right_throttle":
            NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
        })
        self.io.register_inputs(
            {
                "right_joystick":
                NSJoystick(self.nsg.rightXAxis, self.nsg.rightYAxis),
                "Y":
                NSSwitch(self.nsg, NSButton.Y),
                "left_trigger":
                NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_trigger":
                NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus":
                NSSwitch(self.nsg, NSButton.MINUS),
                "plus":
                NSSwitch(self.nsg, NSButton.PLUS),
                "left_stick":
                NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick":
                NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "home":
                NSSwitch(self.nsg, NSButton.HOME),
                "capture":
                NSSwitch(self.nsg, NSButton.CAPTURE),
            },
            admin=True,
        )

        # get detectors
        self.has_4_ready_to_start = get_pixel_detector(HAS_4_READY_PIXELS)
        self.has_flag = get_pixel_detector(FLAG_PIXELS)
        self.has_finish_text = get_pixel_detector(FINISH_TEXT_PIXELS)
        self.position_detectors = {
            1: get_pixel_detector(POS_1_PIXELS),
            2: get_pixel_detector(POS_2_PIXELS),
            3: get_pixel_detector(POS_3_PIXELS),
            4: get_pixel_detector(POS_4_PIXELS),
        }

        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)
        self.image_rec_task_cancelled = False

        # frame saving
        if SAVE_FRAMES:
            logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
            Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

        if SAVE_POS_FRAMES:
            logging.info(f"SAVING POS FRAMES TO {SAVE_POS_DIR_PATH}")
            Path(SAVE_POS_DIR_PATH).mkdir(parents=True, exist_ok=True)

        # game state
        self.has_started = False
        self.has_finished = False
        self.failed_score_reads = 0
        self.pre_game_ready_sent = False
        self.score_sent = False

    async def on_prepare(self):
        logging.info("self.driving...")
        for _ in range(4):
            self.nsg.press(NSButton.A)
            self.nsg.release(NSButton.A)
            await asyncio.sleep(4)
        self.nsg.press(NSButton.B)
        await asyncio.sleep(2.5)
        self.nsg.release(NSButton.B)
        self.nsg.releaseAll()
        logging.info("...self.driving finished")

    async def on_pre_game(self):
        self.io.enable_inputs()
        self.has_started = False
        self.pre_game_ready_sent = False
        return -1

    async def on_start(self):
        self.has_started = True
        self.has_finished = False
        self.failed_score_reads = 0
        self.score_sent = False

    async def on_finish(self):
        # this will trigger stop_controls even if image_rec_main fails
        self.stop_controls()

    async def on_exit(self, reason, exception):
        # end controls
        self.nsg.end()
        # end image rec task
        self.image_rec_task_cancelled = True
        await self.cap.release()
        self.image_rec_task.cancel()

    async def image_rec_main(self):
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        frame_index = 0
        async for frame in self.cap.frames():
            # on_pre_game
            if not self.has_started:
                # send pre_game ready/not_ready based on frame
                self._handle_pre_game(frame)

            # on_start
            if self.has_started:
                # check for the finish text if not found already
                # stop the controls if found
                if not self.has_finished:
                    self._check_for_finish_text(frame)

                # try to read and send score if not already sent
                if not self.score_sent:
                    self._try_reading_score(frame)

            # generic
            if frame_index % 1000 == 0:
                logging.info("1000 frames checked")
            if SAVE_FRAMES:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{frame_index}.jpg", frame)
                logging.info(f"SAVED {frame_index}.jpg")
            frame_index += 1

        if self.image_rec_task_cancelled:
            logging.info("Image rec task finished.")
        else:
            raise RuntimeError("Image rec task finished by itself")

    def _handle_pre_game(self, frame):
        if (self.has_4_ready_to_start(frame)
                or self.has_flag(frame)) and not self.pre_game_ready_sent:
            logging.info("PRE_GAME READY")
            self.pre_game_ready_sent = True
            for seat in self.io._message_router.get_all_seats():
                self.io.send_pre_game_ready(seat=seat)
        elif self.pre_game_ready_sent:
            logging.info("PRE_GAME NOT READY")
            self.pre_game_ready_sent = False
            for seat in self.io._message_router.get_all_seats():
                self.io.send_pre_game_not_ready(seat=seat)

    def _check_for_finish_text(self, frame):
        if self.has_finish_text(frame):
            self.has_finished = True
            self.stop_controls()
            logging.info("FINISHED")

    def _get_position(self, frame):
        detected = None
        for position in self.position_detectors.keys():
            if self.position_detectors[position](frame):
                detected = position
                break
        return detected

    def _try_reading_score(self, frame):
        pos = self._get_position(frame)
        if pos is not None:
            # if position found, try reading the time
            time_ms, time_string = get_time_ms(frame, pos)
            cleaned_time = time_string.replace(":", "-").replace(".", "-")

            # if time_ms reading failed
            if time_ms is None:
                if SAVE_POS_FRAMES:
                    self._save_pos_frame(frame, pos, cleaned_time, failed=True)
                if self.has_finished and not self.score_sent:
                    self.failed_score_reads += 1
                    logging.info(f"Score reading for pos {pos} failed "
                                 f"{self.failed_score_reads}. time: "
                                 f"{time_string}")
                    if self.failed_score_reads == MAX_FAILED_SCORE_READS:
                        logging.info(f"FAILED SCORE SENT")
                        self._send_score(FAILED_SCORE_READ_SCORE)
            else:  # if time reading succeeded
                if not self.has_finished:
                    self.stop_controls()
                    logging.info("STOPPED CONTROLS, FINISH WAS NOT READ")
                self.score_sent = True
                self._send_score(time_ms)
                logging.info(f"SCORE {time_string} SENT")
                if SAVE_POS_FRAMES:
                    self._save_pos_frame(frame, pos, cleaned_time)

    def _save_pos_frame(self, frame, pos, cleaned_time, failed=False):
        prefix = "FAILED_" if failed else ""
        timestamp = int(time() * 1000.0)
        filename = f"{prefix}{cleaned_time}_{pos}_{timestamp}.jpg"
        cv2.imwrite(
            f"{SAVE_POS_DIR_PATH}/{filename}",
            frame,
        )
        logging.info(f"SAVED {prefix}POS FRAME: {filename}")

    def _send_score(self, score):
        for seat in self.io._message_router.get_all_seats():
            self.io.send_score(
                score=score,
                seat=seat,
                seat_final_score=True,
            )

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error("".join(
                traceback.format_exception(None, e, e.__traceback__)))
            sys.exit(1)

    def stop_controls(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()
Esempio n. 8
0
class SurroBrosIR(Game):

    async def on_init(self):
        # init controls
        self.usb_0 = NSGamepadSerial()
        self.usb_1 = NSGamepadSerial()
        self.usb_2 = NSGamepadSerial()
        self.usb_3 = NSGamepadSerial()
        self.usb_4 = NSGamepadSerial()
        try:
            # RX -> TXD | GPIO14 (08 - Blue Wire) | TX -> RXD | GPIO15 (10 - Green Wire)
            # SERIAL_0 = serial.Serial('/dev/ttyAMA0', 2000000, timeout=0)
            # RX -> TXD | GPIO00 (27 - Blue Wire) | TX -> RXD | GPIO01 (28 - Green Wire)
            SERIAL_1 = serial.Serial('/dev/ttyAMA1', 2000000, timeout=0) 
            # RX -> TXD | GPIO04 (07 - Blue Wire) | TX -> RXD | GPIO05 (29 - Green Wire)
            SERIAL_2 = serial.Serial('/dev/ttyAMA2', 2000000, timeout=0)
            # RX -> TXD | GPIO08 (24 - Blue Wire) | TX -> RXD | GPIO09 (21 - Green Wire)
            SERIAL_3 = serial.Serial('/dev/ttyAMA3', 2000000, timeout=0)
            # RX -> TXD | GPIO12 (32 - Blue Wire) | TX -> RXD | GPIO13 (33 - Green Wire)
            SERIAL_4 = serial.Serial('/dev/ttyAMA4', 2000000, timeout=0)
            logging.info(f"Found ttyAMA0/ttyAMA1/ttyAMA2/ttyAMA3/ttyAMA4")
        except:
            logging.critical(f"NSGadget serial port not found")
            sys.exit(1)
        # usb_0.begin(SERIAL_0)
        self.usb_1.begin(SERIAL_1)
        self.usb_2.begin(SERIAL_2)
        self.usb_3.begin(SERIAL_3)
        self.usb_4.begin(SERIAL_4)

        self.io.register_inputs(
            {
                "left_joystick": NSJoystick( "Left",
                    self.usb_1.leftXAxis, self.usb_1.leftYAxis,
                    self.usb_2.leftXAxis, self.usb_2.leftYAxis,
                    self.usb_3.leftXAxis, self.usb_3.leftYAxis,
                    self.usb_4.leftXAxis, self.usb_4.leftYAxis
                ),
                "right_joystick": NSJoystick( "Right",
                    self.usb_1.rightXAxis, self.usb_1.rightYAxis,
                    self.usb_2.rightXAxis, self.usb_2.rightYAxis,
                    self.usb_3.rightXAxis, self.usb_3.rightYAxis,
                    self.usb_4.rightXAxis, self.usb_4.rightYAxis
                ),
                "dpad_up": NSDPadSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSDPad.UP, "UP"),
                "dpad_left": NSDPadSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSDPad.LEFT, "LEFT"),
                "dpad_right": NSDPadSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSDPad.RIGHT, "RIGHT"),
                "dpad_down": NSDPadSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSDPad.DOWN, "DOWN"),
                "Y": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.Y, "Y"),
                "X": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.X, "X"),
                "A": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.A, "A"),
                "B": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.B, "B"),
                "left_throttle": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.LEFT_THROTTLE, "LEFT_THROTTLE"),
                "left_trigger": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.LEFT_TRIGGER, "LEFT_TRIGGER"),
                "right_throttle": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.RIGHT_THROTTLE, "RIGHT_THROTTLE"),
                "right_trigger": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.RIGHT_TRIGGER, "RIGHT_TRIGGER"),
                "left_stick": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.LEFT_STICK, "LEFT_STICK"),
                "right_stick": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.RIGHT_STICK, "RIGHT_STICK"),
            },
        )
        self.io.register_inputs(
            {
                "minus": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.MINUS, "MINUS"),
                "plus": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.PLUS, "PLUS"),
                "home": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.HOME, "HOME"),
                "capture": NSSwitch(self.usb_1, self.usb_2, self.usb_3, self.usb_4, NSButton.CAPTURE, "CAPTURE"),
            },
            admin = True,
        )

        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)
        self.image_rec_task_cancelled = False

        self.has_started = False
        self.pre_game_ready_sent = False


        # init frame saving
        # if SAVE_FRAMES:
        #     logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
        #     Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)


    async def on_pre_game(self):
        self.io.send_pre_game_ready()

    async def on_finish(self):
        logging.info(f"Finish")
        self.io.disable_inputs()

        self.usb_1.rightYAxis(128)
        self.usb_1.rightXAxis(128)
        self.usb_1.leftYAxis(128)
        self.usb_1.leftXAxis(128)    

        self.usb_2.rightYAxis(128)
        self.usb_2.rightXAxis(128)
        self.usb_2.leftYAxis(128)
        self.usb_2.leftXAxis(128)   

        self.usb_3.rightYAxis(128)
        self.usb_3.rightXAxis(128)
        self.usb_3.leftYAxis(128)
        self.usb_3.leftXAxis(128)   

        self.usb_4.rightYAxis(128)
        self.usb_4.rightXAxis(128)
        self.usb_4.leftYAxis(128)
        self.usb_4.leftXAxis(128)  

        self.usb_1.releaseAll()
        self.usb_2.releaseAll()
        self.usb_3.releaseAll()
        self.usb_4.releaseAll()

    async def on_prepare(self):
        logging.info("preparing...")
        
        await asyncio.sleep(2)

        self.usb_1.press(NSButton.HOME)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.HOME)
        await asyncio.sleep(1)
        self.usb_1.press(NSButton.X)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.X)
        await asyncio.sleep(1)
        self.usb_1.press(NSButton.A)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.A)
        await asyncio.sleep(3)
        self.usb_1.press(NSButton.A)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.A)
        await asyncio.sleep(1)
        self.usb_1.press(NSButton.A)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.A)
        await asyncio.sleep(1)
        self.usb_1.press(NSButton.A)
        await asyncio.sleep(0.1)
        self.usb_1.release(NSButton.A)

        self.usb_1.releaseAll()
        self.usb_2.releaseAll()
        self.usb_3.releaseAll()
        self.usb_4.releaseAll()
        logging.info("...preparing.finish")


    async def on_exit(self, reason, exception):
        # end controls
        logging.info(f"Exit")
        self.io.disable_inputs() 

        self.usb_1.end()
        self.usb_2.end()
        self.usb_3.end()
        self.usb_4.end()

        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")

        # get detectors
        finish_flag = get_pixel_detector(PIXELS_FINISH)

        # loop through frames
        i = 0
        async for frame in self.cap.frames():
            # detect
            if finish_flag(frame):
                logging.info("Has flag!")
                for seat in self.io._message_router.get_all_seats():
                    logging.info(f"\t"+str(seat))
                    self.io.send_score(
                        score=1, seat=seat, seat_final_score=True,
                    )
                self.io.send_score(score=1, final_score=True)

            # generic
            # if i % 100 == 0:
            #     logging.info("100 frames checked")
            # if SAVE_FRAMES and i % 100 == 0:
            #     cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
            #     logging.info(f"SAVED {i}.jpg")
            # i += 1

        if self.image_rec_task_cancelled:
            logging.info("Image rec task finished.")
        else:
            raise RuntimeError("Image rec task finished by itself")

    async def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error(
                "".join(traceback.format_exception(None, e, e.__traceback__))
            )
            sys.exit(1)
Esempio n. 9
0
class NinSwitchFourPlayers(Game):
    async def on_init(self):
        # init controls
        self.nsg_1 = NSGamepadSerial()
        self.nsg_2 = NSGamepadSerial()
        self.nsg_3 = NSGamepadSerial()
        self.nsg_4 = NSGamepadSerial()

        try:
            # RX -> TXD | GPIO00 | TX -> RXD | GPIO01
            SERIAL_1 = serial.Serial('/dev/ttyAMA1', 2000000, timeout=0)
            # RX -> TXD | GPIO04 | TX -> RXD | GPIO05
            SERIAL_2 = serial.Serial('/dev/ttyAMA2', 2000000, timeout=0)
            # RX -> TXD | GPIO08 | TX -> RXD | GPIO09
            SERIAL_3 = serial.Serial('/dev/ttyAMA3', 2000000, timeout=0)
            # RX -> TXD | GPIO12 | TX -> RXD | GPIO13
            SERIAL_4 = serial.Serial('/dev/ttyAMA4', 2000000, timeout=0)
            logging.info(f"Found ttyAMA1/ttyAMA2/ttyAMA3/ttyAMA4")
        except:
            logging.critical(f"NSGadget serial port not found")
            sys.exit(1)

        self.nsg_1.begin(SERIAL_1)
        self.nsg_2.begin(SERIAL_2)
        self.nsg_3.begin(SERIAL_3)
        self.nsg_4.begin(SERIAL_4)

        self.io.register_inputs(
            {
                "left_joystick":
                NSJoystick("Left", self.nsg_1.leftXAxis, self.nsg_1.leftYAxis,
                           self.nsg_2.leftXAxis, self.nsg_2.leftYAxis,
                           self.nsg_3.leftXAxis, self.nsg_3.leftYAxis,
                           self.nsg_4.leftXAxis, self.nsg_4.leftYAxis),
                "right_joystick":
                NSJoystick("Right", self.nsg_1.rightXAxis,
                           self.nsg_1.rightYAxis, self.nsg_2.rightXAxis,
                           self.nsg_2.rightYAxis, self.nsg_3.rightXAxis,
                           self.nsg_3.rightYAxis, self.nsg_4.rightXAxis,
                           self.nsg_4.rightYAxis),
                "dpad_up":
                NSDPadSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                             NSDPad.UP, "UP"),
                "dpad_left":
                NSDPadSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                             NSDPad.LEFT, "LEFT"),
                "dpad_right":
                NSDPadSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                             NSDPad.RIGHT, "RIGHT"),
                "dpad_down":
                NSDPadSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                             NSDPad.DOWN, "DOWN"),
                "Y":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.Y, "Y"),
                "X":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.X, "X"),
                "A":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.A, "A"),
                "B":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.B, "B"),
                "minus":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.MINUS, "MINUS"),
                "plus":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.PLUS, "PLUS"),
                "left_throttle":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.LEFT_THROTTLE, "LEFT_THROTTLE"),
                "left_trigger":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.LEFT_TRIGGER, "LEFT_TRIGGER"),
                "right_throttle":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.RIGHT_THROTTLE, "RIGHT_THROTTLE"),
                "right_trigger":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.RIGHT_TRIGGER, "RIGHT_TRIGGER"),
                "left_stick":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.LEFT_STICK, "LEFT_STICK"),
                "right_stick":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.RIGHT_STICK, "RIGHT_STICK"),
            }, )
        self.io.register_inputs(
            {
                "home":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.HOME, "HOME"),
                "capture":
                NSSwitch(self.nsg_1, self.nsg_2, self.nsg_3, self.nsg_4,
                         NSButton.CAPTURE, "CAPTURE"),
            },
            admin=True,
        )

    async def on_finish(self):
        logging.info(f"Finish")
        self.io.disable_inputs()

        for seat in self.io._message_router.get_all_seats():
            self.io.send_score(
                score=1,
                seat=seat,
                seat_final_score=True,
            )
        self.io.send_score(score=1, final_score=True)

        self.nsg_1.releaseAll()
        self.nsg_2.releaseAll()
        self.nsg_3.releaseAll()
        self.nsg_4.releaseAll()

    async def on_prepare(self):
        await reset_trinket()
        await asyncio.sleep(2)

        self.nsg_1.releaseAll()
        self.nsg_2.releaseAll()
        self.nsg_3.releaseAll()
        self.nsg_4.releaseAll()

    async def on_exit(self, reason, exception):
        self.nsg_1.end()
        self.nsg_2.end()
        self.nsg_3.end()
        self.nsg_4.end()
class SAMPLE_ADVANCED_GAME(Game):
    async def on_init(self):
        self.prepare = True
        # init controls
        self.nsg = NSGamepadSerial()
        self.nsg.begin()
        self.io.register_inputs(
            {
                "left_joystick": NSJoystick(
                    self.nsg.leftXAxis, self.nsg.leftYAxis
                ),
                "right_joystick": NSJoystick(
                    self.nsg.rightXAxis, self.nsg.rightYAxis
                ),
                "dpad_up": NSDPadSwitch(self.nsg, NSDPad.UP),
                "dpad_left": NSDPadSwitch(self.nsg, NSDPad.LEFT),
                "dpad_right": NSDPadSwitch(self.nsg, NSDPad.RIGHT),
                "dpad_down": NSDPadSwitch(self.nsg, NSDPad.DOWN),
                "Y": NSSwitch(self.nsg, NSButton.Y),
                "X": NSSwitch(self.nsg, NSButton.X),
                "A": NSSwitch(self.nsg, NSButton.A),
                "B": NSSwitch(self.nsg, NSButton.B),
                "left_throttle": NSSwitch(self.nsg, NSButton.LEFT_THROTTLE),
                "left_trigger": NSSwitch(self.nsg, NSButton.LEFT_TRIGGER),
                "right_throttle": NSSwitch(self.nsg, NSButton.RIGHT_THROTTLE),
                "right_trigger": NSSwitch(self.nsg, NSButton.RIGHT_TRIGGER),
                "minus": NSSwitch(self.nsg, NSButton.MINUS),
                "left_stick": NSSwitch(self.nsg, NSButton.LEFT_STICK),
                "right_stick": NSSwitch(self.nsg, NSButton.RIGHT_STICK),
                "capture_frame": CaptureScreen(),
                "reset_trinkets": reset_trinkets(),
                "plus": NSSwitch(self.nsg, NSButton.PLUS),
            },
        )
        self.io.register_inputs(
            {
                "home": NSSwitch(self.nsg, NSButton.HOME),
                "capture": NSSwitch(self.nsg, NSButton.CAPTURE),
                "debug_switch": debug_switch(),
            },
            admin=True,
        )

        # init image rec
        self.image_rec_task = asyncio.create_task(self.image_rec_main())
        self.image_rec_task.add_done_callback(self.image_rec_done_cb)

        # init frame saving
        logging.info(f"SAVING FRAMES TO {SAVE_DIR_PATH}")
        Path(SAVE_DIR_PATH).mkdir(parents=True, exist_ok=True)

        self.curUser = "******"
        self.userID = "eu-west-1:dummydummydummydummydummydummydummyd"
        # Dynamic point system
        # self.userIDs = []
        # self.userScores = []
        # self.knownIndex = 0
        # self.points = 0
        # with open("player_scores.dat", "r") as file:
        #     for line in file:
        #         currentPlace=line[:-1]
        #         breakPt = currentPlace.index("|")
        #         uid = currentPlace[0:int(breakPt)]
        #         score = int(currentPlace[int(breakPt)+1:])
        #         if not uid in self.userIDs:
        #             self.userIDs.append(uid)
        #             self.userScores.append(score)

# ----------------------------------------------------

    async def on_start(self):
        self.curUser = self.players
        player = json.loads(json.dumps(self.players))[0]['username']

        req = requests.get("https://g9b1fyald3.execute-api.eu-west-1.amazonaws.com/master/users?search="+str(player)).text
        uid = json.loads(req)['result'][0]['userId']
        self.userID = uid
        # Dynamic point system
        # if str(uid) in self.userIDs:
        #     self.knownIndex = self.userIDs.index(str(uid))
        #     self.points = self.userScores[self.knownIndex]
        # else: 
        #     self.userIDs.append(str(uid))
        #     self.points = 0
        #     self.userScores.append(self.points)
        #     self.knownIndex = len(self.userScores)-1

# ----------------------------------------------------

    async def on_prepare(self):
        pi.write(nsg_reset, ON)
        await asyncio.sleep(0.5)
        pi.write(nsg_reset, OFF)
        await asyncio.sleep(2)

        self.prepare = True

        # UNCOMMENT AFTER GETTING SUTIBLE PAUSE FRAMES
        # while self.prepare: 
        #     await asyncio.sleep(3)

# ----------------------------------------------------

    async def on_finish(self):
        self.io.disable_inputs()
        self.nsg.releaseAll()

        self.nsg.rightYAxis(128)
        self.nsg.rightXAxis(128)
        self.nsg.leftYAxis(128)
        self.nsg.leftXAxis(128)   

        self.io.send_score(score=1, seat=0, final_score=True) # Comment out if using below

        # Dynamic point system
        # self.userScores[0] = 0
        # self.io.send_score(score=self.points, seat=0, final_score=True)
        # self.userScores[self.knownIndex] = self.points

        # with open("player_scores.dat", "w") as file:
        #     for i in range(len(self.userIDs)):
        #         item = self.userIDs[i]+"|"+str(self.userScores[i])
        #         file.write('%s\n' % item)

        self.prepare = True
        self.knownIndex = 0

# ----------------------------------------------------

    async def on_exit(self, reason, exception):
        # end controls
        self.io.disable_inputs() 
        self.nsg.end()
        # end image rec task
        await self.cap.release()
        self.image_rec_task.cancel()

# ----------------------------------------------------

    async def image_rec_main(self):
        # create capture
        self.cap = await AsyncVideoCapture.create("/dev/video21")
        
        global LOCKED, allowReset
        LOCKED = False

        # get detector
        # odyssey_nav_menu = get_pixel_detector(ODYSSEY_NAV_MENU, 50)
        # talking = get_pixel_detector(TALKING, 50)
        # minus_menu_ingame = get_pixel_detector(MINUS_MENU_INGAME, 50)

        # controller_dc_input_needed = get_pixel_detector(CONTROLLER_DC_INPUT_NEEDED, 50)
        # controller_dc_reconnected = get_pixel_detector(CONTROLLER_DC_RECONNECTED, 50)

        # lock detector
        # shop_load = get_pixel_detector(SHOP_LOAD, 50)
        # shop = get_pixel_detector(SHOP, 50)
        # screenshots = get_pixel_detector(SCREENSHOTS, 50)
        # settings = get_pixel_detector(SETTINGS, 50)
        # home_menu = get_pixel_detector(HOME_MENU, 50)
        # plus_menu_ingame = get_pixel_detector(PLUS_MENU_INGAME, 50)
        # game_main_menu = get_pixel_detector(GAME_MAIN_MENU, 50)

        # Point detector
        # detector = []
        # gotten = []
        # timeoutThreshold = []
        # pointsToAdd = []
        # curTimeout = []

        # detector.append(get_pixel_detector(GOT_MOON_BIG, 15))
        # gotten.append(True)
        # timeoutThreshold.append(100)
        # pointsToAdd.append(50) # Can be set to any value
        # curTimeout.append(0)
        # detector.append(get_pixel_detector(GOT_MOON_RETRO, 15))
        # gotten.append(True)
        # timeoutThreshold.append(100)
        # pointsToAdd.append(30) # Can be set to any value
        # curTimeout.append(0)
        # detector.append(get_pixel_detector(GOT_MOON_NORMAL, 15))
        # gotten.append(True)
        # timeoutThreshold.append(100)
        # pointsToAdd.append(50) 
        # curTimeout.append(0)
        # detector.append(get_pixel_detector(GOT_MULTI_MOON, 15))
        # gotten.append(True)
        # timeoutThreshold.append(100)
        # pointsToAdd.append(50) # Can be set to any value
        # curTimeout.append(0)


        # loop through frames
        i = 0
        z = 0
        async for frame in self.cap.frames():
            # detect trigger
            # if i%30==0 and (controller_dc_reconnected(frame) or controller_dc_input_needed(frame) or controller_dc_reconnected(frame) or controller_dc_input_needed(frame)):
            #     pi.write(nsg_reset, ON)
            #     await asyncio.sleep(0.5)
            #     pi.write(nsg_reset, OFF)
            #     await asyncio.sleep(1)
            # try:
            #     if (controller_dc_reconnected(frame) or controller_dc_input_needed(frame)) and not DEBUG:
            #         self.io.disable_input(0)
            #         self.nsg.press(NSButton.A)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.A)
            #         await asyncio.sleep(2)
            #         self.nsg.press(NSButton.A)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.A)
            #         await asyncio.sleep(2)
            #         self.io.enable_input(0)
            # except:
            #     if (controller_dc_reconnected(frame) or controller_dc_input_needed(frame)) and not DEBUG:
            #         self.nsg.press(NSButton.A)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.A)
            #         await asyncio.sleep(2)
            #         self.nsg.press(NSButton.A)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.A)
            #         await asyncio.sleep(2)

            # Get to pause frames...Update as needed
            # if (self.prepare and not ((odyssey_nav_menu(frame) or talking(frame) or minus_menu_ingame(frame))) and not LOCKED) and not DEBUG:
            #     if z % 3 == 2:
            #         self.nsg.press(NSButton.A)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.A)
            #         await asyncio.sleep(1)
            #         self.nsg.press(NSButton.B)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.B)
            #         await asyncio.sleep(1)
            #     else:
            #         self.nsg.press(NSButton.MINUS)
            #         await asyncio.sleep(0.1)
            #         self.nsg.release(NSButton.MINUS)
            #         await asyncio.sleep(1)
            #     z += 1
            # elif not LOCKED:
            #     z = 0
            #     self.prepare = False

            # lock trigger
            # try:
            #     if (shop_load(frame) or shop(frame) or screenshots(frame) or settings(frame) or home_menu(frame) or plus_menu_ingame(frame) or game_main_menu(frame)) and not LOCKED and not DEBUG:
            #         self.io.disable_input(0)
            #         player = json.loads(json.dumps(self.curUser))[0]['username']
            #         msg = "SAMPLE GAME\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> "+player+"\n> "+self.userID
            #         # Can use a service like Telegram to send a message to the game owner
            #         LOCKED = True
            # except:
            #     if (shop_load(frame) or shop(frame) or screenshots(frame) or settings(frame) or home_menu(frame) or plus_menu_ingame(frame) or game_main_menu(frame)) and not LOCKED and not DEBUG:
            #         player = json.loads(json.dumps(self.curUser))[0]['username']
            #         msg = "SAMPLE GAME\nGame locked due to either being at home screen or capture card bars. \nUser's information are as follows:\n> "+player+"\n> "+self.userID
            #         # Can use a service like Telegram to send a message to the game owner
            #         LOCKED = True

            if LOCKED: 
                self.io.send_playing_ended()
                self.prepare = True

            # Point trigger
            # for pointTrigger in range(len(detector)):
            #     if detector[pointTrigger](frame):
            #         if not gotten[pointTrigger]:
            #             self.points += pointsToAdd[pointTrigger]
            #             self.io.send_score(score = self.points, seat = 0, final_score = False)
            #             self.usb_2.press(NSButton.A)
            #             await asyncio.sleep(0.1)
            #             self.usb_2.release(NSButton.A)
            #         curTimeout[pointTrigger] = 0
            #         gotten[pointTrigger] = True
            #     elif curTimeout[pointTrigger] < timeoutThreshold[pointTrigger]:
            #         curTimeout[pointTrigger] += 1
            #     else:
            #         gotten[pointTrigger] = False

            # generic
            if i%100==0:
                allowReset = True
            if SAVE_ALL_FRAMES or save_individual_fame:
                cv2.imwrite(f"{SAVE_DIR_PATH}/{i}.jpg", frame)
                logging.info(f"SAVED {i}.jpg")
            i += 1

# ----------------------------------------------------

    def image_rec_done_cb(self, fut):
        # make program end if image_rec_task raises error
        if not fut.cancelled() and fut.exception() is not None:
            import traceback, sys  # noqa: E401

            e = fut.exception()
            logging.error(
                "".join(traceback.format_exception(None, e, e.__traceback__))
            )
            sys.exit(1)