Exemplo n.º 1
0
 def __init__(self, args, dev_id, id, websocket_handler, walker,
              mapping_manager, mitm_mapper: MitmMapper,
              db_wrapper: DbWrapper, area_id: int, routemanager_name: str):
     self._args = args
     self._communicator = Communicator(websocket_handler, id, self,
                                       args.websocket_command_timeout)
     self._stop_worker_event = Event()
     self._dev_id = dev_id
     self._origin = id
     self._routemanager_name = routemanager_name
     self._area_id = area_id
     self._walker = walker
     self.workerstart = None
     self._mapping_manager: MappingManager = mapping_manager
     self._mitm_mapper = mitm_mapper
     self._db_wrapper = db_wrapper
Exemplo n.º 2
0
 async def __add_worker_and_thread_to_entry(self, entry, origin) -> bool:
     communicator: AbstractCommunicator = Communicator(
         entry, origin, None, self.__args.websocket_command_timeout)
     worker: Optional[AbstractWorker] = await self.__worker_factory \
         .get_worker_using_settings(origin, self.__enable_configmode,
                                    communicator=communicator)
     if worker is None:
         return False
     # to break circular dependencies, we need to set the worker ref >.<
     communicator.worker_instance_ref = worker
     new_worker_thread = Thread(name=origin, target=worker.start_worker)
     new_worker_thread.daemon = True
     entry.worker_thread = new_worker_thread
     entry.worker_instance = worker
     return True
Exemplo n.º 3
0
class WorkerConfigmode(object):
    def __init__(self, args, dev_id, id, websocket_handler, walker,
                 mapping_manager, mitm_mapper: MitmMapper,
                 db_wrapper: DbWrapper, area_id: int, routemanager_name: str):
        self._args = args
        self._communicator = Communicator(websocket_handler, id, self,
                                          args.websocket_command_timeout)
        self._stop_worker_event = Event()
        self._dev_id = dev_id
        self._origin = id
        self._routemanager_name = routemanager_name
        self._area_id = area_id
        self._walker = walker
        self.workerstart = None
        self._mapping_manager: MappingManager = mapping_manager
        self._mitm_mapper = mitm_mapper
        self._db_wrapper = db_wrapper

    def set_devicesettings_value(self, key: str, value):
        self._mapping_manager.set_devicesetting_value_of(
            self._origin, key, value)

    def get_devicesettings_value(self, key: str, default_value: object = None):
        devicemappings: Optional[
            dict] = self._mapping_manager.get_devicemappings_of(self._origin)
        if devicemappings is None:
            return default_value
        return devicemappings.get("settings", {}).get(key, default_value)

    def get_communicator(self):
        return self._communicator

    def start_worker(self):
        logger.info("Worker {} started in configmode", str(self._origin))
        self._mapping_manager.register_worker_to_routemanager(
            self._routemanager_name, self._origin)
        logger.debug("Setting device to idle for routemanager")
        self._db_wrapper.save_idle_status(self._dev_id, True)
        logger.debug("Device set to idle for routemanager {}",
                     str(self._origin))
        while self.check_walker() and not self._stop_worker_event.is_set():
            position_type = self._mapping_manager.routemanager_get_position_type(
                self._routemanager_name, self._origin)
            if position_type is None:
                logger.warning(
                    "Mappings/Routemanagers have changed, stopping worker to be created again"
                )
                self._stop_worker_event.set()
                time.sleep(1)
            else:
                time.sleep(10)
        self.set_devicesettings_value('finished', True)
        self._mapping_manager.unregister_worker_from_routemanager(
            self._routemanager_name, self._origin)
        try:
            self._communicator.cleanup_websocket()
        finally:
            logger.info("Internal cleanup of {} finished", str(self._origin))
        return

    def stop_worker(self):
        if self._stop_worker_event.set():
            logger.info('Worker {} already stopped - waiting for it',
                        str(self._origin))
        else:
            self._stop_worker_event.set()
            logger.warning("Worker {} stop called", str(self._origin))

    def set_geofix_sleeptime(self, sleeptime):
        return True

    def set_job_activated(self):
        return True

    def set_job_deactivated(self):
        return True

    def check_walker(self):
        mode = self._walker['walkertype']
        if mode == "countdown":
            logger.info("Checking walker mode 'countdown'")
            countdown = self._walker['walkervalue']
            if not countdown:
                logger.error(
                    "No Value for Mode - check your settings! Killing worker")
                return False
            if self.workerstart is None:
                self.workerstart = math.floor(time.time())
            else:
                if math.floor(
                        time.time()) >= int(self.workerstart) + int(countdown):
                    return False
            return True
        elif mode == "timer":
            logger.debug("Checking walker mode 'timer'")
            exittime = self._walker['walkervalue']
            if not exittime or ':' not in exittime:
                logger.error(
                    "No or wrong Value for Mode - check your settings! Killing worker"
                )
                return False
            return check_walker_value_type(exittime)
        elif mode == "round":
            logger.error("Rounds while sleep - HAHAHAH")
            return False
        elif mode == "period":
            logger.debug("Checking walker mode 'period'")
            period = self._walker['walkervalue']
            if len(period) == 0:
                logger.error(
                    "No Value for Mode - check your settings! Killing worker")
                return False
            return check_walker_value_type(period)
        elif mode == "coords":
            exittime = self._walker['walkervalue']
            if len(exittime) > 0:
                return check_walker_value_type(exittime)
            return True
        elif mode == "idle":
            logger.debug("Checking walker mode 'idle'")
            if len(self._walker['walkervalue']) == 0:
                logger.error(
                    "Wrong Value for mode - check your settings! Killing worker"
                )
                return False
            sleeptime = self._walker['walkervalue']
            logger.info('{} going to sleep', str(self._origin))
            killpogo = False
            if check_walker_value_type(sleeptime):
                self._stop_pogo()
                killpogo = True
                logger.debug("Setting device to idle for routemanager")
                self._db_wrapper.save_idle_status(self._dev_id, True)
                logger.debug("Device set to idle for routemanager {}",
                             str(self._origin))
            while check_walker_value_type(
                    sleeptime) and not self._stop_worker_event.isSet():
                time.sleep(1)
            logger.info('{} just woke up', str(self._origin))
            if killpogo:
                try:
                    self._start_pogo()
                except (WebsocketWorkerRemovedException,
                        WebsocketWorkerTimeoutException):
                    logger.error("Timeout during init of worker {}",
                                 str(self._origin))
            return False
        else:
            logger.error("Unknown walker mode! Killing worker")
            return False

    def _stop_pogo(self):
        attempts = 0
        stop_result = self._communicator.stopApp("com.nianticlabs.pokemongo")
        pogoTopmost = self._communicator.isPogoTopmost()
        while pogoTopmost:
            attempts += 1
            if attempts > 10:
                return False
            stop_result = self._communicator.stopApp(
                "com.nianticlabs.pokemongo")
            time.sleep(1)
            pogoTopmost = self._communicator.isPogoTopmost()
        return stop_result

    def _start_pogo(self):
        pogo_topmost = self._communicator.isPogoTopmost()
        if pogo_topmost:
            return True

        if not self._communicator.isScreenOn():
            self._communicator.startApp("de.grennith.rgc.remotegpscontroller")
            logger.warning("Turning screen on")
            self._communicator.turnScreenOn()
            time.sleep(
                self.get_devicesettings_value("post_turn_screen_on_delay", 7))

        start_result = False
        while not pogo_topmost:
            self._mitm_mapper.set_injection_status(self._origin, False)
            start_result = self._communicator.startApp(
                "com.nianticlabs.pokemongo")
            time.sleep(1)
            pogo_topmost = self._communicator.isPogoTopmost()

        reached_raidtab = False
        self._wait_pogo_start_delay()

        return reached_raidtab

    def _wait_for_injection(self):
        self._not_injected_count = 0
        while not self._mitm_mapper.get_injection_status(self._origin):
            if self._not_injected_count >= 20:
                logger.error("Worker {} not get injected in time - reboot",
                             str(self._origin))
                self._reboot()
                return False
            logger.info(
                "PogoDroid on worker {} didn't connect yet. Probably not injected? (Count: {})",
                str(self._origin), str(self._not_injected_count))
            if self._stop_worker_event.isSet():
                logger.error(
                    "Worker {} get killed while waiting for injection",
                    str(self._origin))
                return False
            self._not_injected_count += 1
            wait_time = 0
            while wait_time < 20:
                wait_time += 1
                if self._stop_worker_event.isSet():
                    logger.error(
                        "Worker {} get killed while waiting for injection",
                        str(self._origin))
                    return False
                time.sleep(1)
        return True

    def _reboot(self):
        if not self.get_devicesettings_value("reboot", True):
            logger.warning(
                "Reboot command to be issued to device but reboot is disabled. Skipping reboot"
            )
            return True
        try:
            start_result = self._communicator.reboot()
        except WebsocketWorkerRemovedException:
            logger.error(
                "Could not reboot due to client already having disconnected")
            start_result = False
        time.sleep(5)
        self._db_wrapper.save_last_reboot(self._dev_id)
        self.stop_worker()
        return start_result

    def _wait_pogo_start_delay(self):
        delay_count: int = 0
        pogo_start_delay: int = self.get_devicesettings_value(
            "post_pogo_start_delay", 60)
        logger.info('Waiting for pogo start: {} seconds',
                    str(pogo_start_delay))

        while delay_count <= pogo_start_delay:
            if self._stop_worker_event.is_set():
                logger.error(
                    "Worker {} get killed while waiting for pogo start",
                    str(self._origin))
                raise InternalStopWorkerException
            time.sleep(1)
            delay_count += 1