Esempio n. 1
0
 def run_process(*args, **kwargs):
     try:
         run_process_old(*args, **kwargs)
     except (KeyboardInterrupt, SystemExit):
         raise
     except BrokenPipeError:
         pass
     except Exception:
         logger.opt(
             exception=True).critical("An unhanded exception occurred!")
Esempio n. 2
0
    async def __register(self, websocket_client_connection):
        logger.info(
            "Client {} registering",
            str(
                websocket_client_connection.request_headers.get_all("Origin")
                [0]))

        try:
            origin = str(
                websocket_client_connection.request_headers.get_all("Origin")
                [0])
        except IndexError:
            logger.warning(
                "Client from {} tried to connect without Origin header",
                str(
                    websocket_client_connection.request_headers.get_all(
                        "Origin")[0]))
            return False

        if self.__mapping_manager is None or origin not in self.__mapping_manager.get_all_devicemappings(
        ).keys():
            logger.warning(
                "Register attempt of unknown origin: {}. "
                "Have you forgot to hit 'APPLY SETTINGS' in MADmin?".format(
                    origin))
            return False

        if origin in self.__users_connecting:
            logger.info("Client {} is already connecting".format(origin))
            return False

        auths = self.__mapping_manager.get_auths()
        if auths:
            try:
                authBase64 = str(
                    websocket_client_connection.request_headers.get_all(
                        "Authorization")[0])
            except IndexError:
                logger.warning(
                    "Client from {} tried to connect without auth header",
                    str(
                        websocket_client_connection.request_headers.get_all(
                            "Origin")[0]))
                return False

        async with self.__users_mutex:
            logger.debug("Checking if {} is already present", str(origin))
            if origin in self.__current_users:
                logger.warning(
                    "Worker with origin {} is already running, killing the running one and have client reconnect",
                    str(origin))
                self.__current_users.get(origin)[1].stop_worker()
                ## todo: do this better :D
                logger.debug(
                    "Old worker thread is still alive - waiting 20 seconds")
                await asyncio.sleep(20)
                logger.info("Reconnect ...")
                return

            self.__users_connecting.append(origin)

        # reset pref. error counter if exist
        await self.__reset_fail_counter(origin)
        try:
            if auths and authBase64 and not check_auth(authBase64, self.args,
                                                       auths):
                logger.warning(
                    "Invalid auth details received from {}",
                    str(
                        websocket_client_connection.request_headers.get_all(
                            "Origin")[0]))
                return False
            logger.info("Starting worker {}".format(origin))
            if self._configmode:
                worker = WorkerConfigmode(
                    self.args,
                    origin,
                    self,
                    walker=None,
                    mapping_manager=self.__mapping_manager,
                    mitm_mapper=self.__mitm_mapper,
                    db_wrapper=self.__db_wrapper,
                    routemanager_name=None)
                logger.debug("Starting worker for {}", str(origin))
                new_worker_thread = Thread(name='worker_%s' % origin,
                                           target=worker.start_worker)
                async with self.__users_mutex:
                    self.__current_users[origin] = [
                        new_worker_thread, worker, websocket_client_connection,
                        0
                    ]
                return True

            last_known_state = {}
            client_mapping = self.__mapping_manager.get_devicemappings_of(
                origin)
            devicesettings = self.__mapping_manager.get_devicesettings_of(
                origin)
            logger.info("Setting up routemanagers for {}", str(origin))

            if client_mapping.get("walker", None) is not None:
                if devicesettings is not None and "walker_area_index" not in devicesettings:
                    logger.debug("Initializing devicesettings")
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'walker_area_index', 0)
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'finished', False)
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'last_action_time', None)
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'last_cleanup_time', None)
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'job', False)
                    await asyncio.sleep(
                        1
                    )  # give the settings a moment... (dirty "workaround" against race condition)
                walker_index = devicesettings.get('walker_area_index', 0)

                if walker_index > 0:
                    # check status of last area
                    if not devicesettings.get('finished', False):
                        logger.info(
                            'Something wrong with last round - get back to old area'
                        )
                        walker_index -= 1
                        self.__mapping_manager.set_devicesetting_value_of(
                            origin, 'walker_area_index', walker_index)
                        # devicesettings['walker_area_index'] = walker_index

                walker_area_array = client_mapping["walker"]
                walker_settings = walker_area_array[walker_index]

                # preckeck walker setting
                while not pre_check_value(
                        walker_settings) and walker_index - 1 <= len(
                            walker_area_array):
                    walker_area_name = walker_area_array[walker_index][
                        'walkerarea']
                    logger.info(
                        '{} not using area {} - Walkervalue out of range',
                        str(origin),
                        str(
                            self.__mapping_manager.routemanager_get_name(
                                walker_area_name)))
                    if walker_index >= len(walker_area_array) - 1:
                        logger.error(
                            'Could not find any working area at this time - check your mappings for device: {}',
                            str(origin))
                        walker_index = 0
                        self.__mapping_manager.set_devicesetting_value_of(
                            origin, 'walker_area_index', walker_index)
                        walker_settings = walker_area_array[walker_index]
                        await websocket_client_connection.close()
                        return
                    walker_index += 1
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'walker_area_index', walker_index)
                    walker_settings = walker_area_array[walker_index]

                devicesettings = self.__mapping_manager.get_devicesettings_of(
                    origin)
                logger.debug("Checking walker_area_index length")
                if (devicesettings.get("walker_area_index", None) is None
                        or devicesettings['walker_area_index'] >=
                        len(walker_area_array)):
                    # check if array is smaller than expected - f.e. on the fly changes in mappings.json
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'walker_area_index', 0)
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'finished', False)
                    walker_index = 0

                walker_area_name = walker_area_array[walker_index][
                    'walkerarea']

                if walker_area_name not in self.__mapping_manager.get_all_routemanager_names(
                ):
                    await websocket_client_connection.close()
                    raise WrongAreaInWalker()

                logger.debug('Devicesettings {}: {}', str(origin),
                             devicesettings)
                logger.info(
                    '{} using walker area {} [{}/{}]', str(origin),
                    str(
                        self.__mapping_manager.routemanager_get_name(
                            walker_area_name)), str(walker_index + 1),
                    str(len(walker_area_array)))
                walker_routemanager_mode = self.__mapping_manager.routemanager_get_mode(
                    walker_area_name)
                self.__mapping_manager.set_devicesetting_value_of(
                    origin, 'walker_area_index', walker_index + 1)
                self.__mapping_manager.set_devicesetting_value_of(
                    origin, 'finished', False)
                if walker_index >= len(walker_area_array) - 1:
                    self.__mapping_manager.set_devicesetting_value_of(
                        origin, 'walker_area_index', 0)

                # set global mon_iv
                routemanager_settings = self.__mapping_manager.routemanager_get_settings(
                    walker_area_name)
                if routemanager_settings is not None:
                    client_mapping['mon_ids_iv'] =\
                        self.__mapping_manager.get_monlist(routemanager_settings.get("mon_ids_iv", None),
                                                           walker_area_name)
            else:
                walker_routemanager_mode = None

            if "last_location" not in devicesettings:
                devicesettings['last_location'] = Location(0.0, 0.0)

            logger.debug("Setting up worker for {}", str(origin))
            worker = None
            if walker_routemanager_mode is None:
                pass
            elif walker_routemanager_mode in [
                    "raids_mitm", "mon_mitm", "iv_mitm"
            ]:
                worker = WorkerMITM(
                    self.args,
                    origin,
                    last_known_state,
                    self,
                    routemanager_name=walker_area_name,
                    mitm_mapper=self.__mitm_mapper,
                    mapping_manager=self.__mapping_manager,
                    db_wrapper=self.__db_wrapper,
                    pogo_window_manager=self.__pogoWindowManager,
                    walker=walker_settings)
            elif walker_routemanager_mode in ["pokestops"]:
                worker = WorkerQuests(
                    self.args,
                    origin,
                    last_known_state,
                    self,
                    routemanager_name=walker_area_name,
                    mitm_mapper=self.__mitm_mapper,
                    mapping_manager=self.__mapping_manager,
                    db_wrapper=self.__db_wrapper,
                    pogo_window_manager=self.__pogoWindowManager,
                    walker=walker_settings)
            elif walker_routemanager_mode in ["idle"]:
                worker = WorkerConfigmode(
                    self.args,
                    origin,
                    self,
                    walker=walker_settings,
                    mapping_manager=self.__mapping_manager,
                    mitm_mapper=self.__mitm_mapper,
                    db_wrapper=self.__db_wrapper,
                    routemanager_name=walker_area_name)
            else:
                logger.error("Mode not implemented")
                sys.exit(1)

            if worker is None:
                logger.error(
                    "Invalid walker mode for {}. Closing connection".format(
                        str(origin)))
                await websocket_client_connection.close()
            else:
                logger.debug("Starting worker for {}", str(origin))
                new_worker_thread = Thread(name='worker_%s' % origin,
                                           target=worker.start_worker)

                new_worker_thread.daemon = True
                async with self.__users_mutex:
                    self.__current_users[origin] = [
                        new_worker_thread, worker, websocket_client_connection,
                        0
                    ]
                new_worker_thread.start()
        except WrongAreaInWalker:
            logger.error('Unknown Area in Walker settings - check config')
            await websocket_client_connection.close()
        except Exception:
            logger.opt(exception=True).error(
                "Other unhandled exception during registration of {}.", origin)
            await websocket_client_connection.close()
        finally:
            async with self.__users_mutex:
                self.__users_connecting.remove(origin)
            await asyncio.sleep(5)
        return True