Esempio n. 1
0
    def __internal_get_screen_text(self, screenpath: str,
                                   identifier) -> Optional[dict]:
        returning_dict: Optional[dict] = {}
        logger.debug("get_screen_text: Reading screen text - identifier {}",
                     identifier)

        try:
            with Image.open(screenpath) as frame:
                frame = frame.convert('LA')
                try:
                    returning_dict = pytesseract.image_to_data(
                        frame,
                        output_type=Output.DICT,
                        timeout=40,
                        config='--dpi 70')
                except Exception as e:
                    logger.error(
                        "Tesseract Error for device {}: {}. Exception: {}".
                        format(str(identifier), str(returning_dict), e))
                    returning_dict = None
        except (FileNotFoundError, ValueError) as e:
            logger.error("Failed opening image {} with exception {}",
                         screenpath, e)
            return None

        if isinstance(returning_dict, dict):
            return returning_dict
        else:
            logger.warning("Could not read text in image: {}", returning_dict)
            return None
Esempio n. 2
0
    def __check_close_present(self,
                              filename,
                              identifier,
                              communicator,
                              radiusratio=12,
                              Xcord=True):
        if not os.path.isfile(filename):
            logger.warning("__check_close_present: {} does not exist",
                           str(filename))
            return False

        try:
            image = cv2.imread(filename)
            height, width, _ = image.shape
        except Exception as e:
            logger.error("Screenshot corrupted: {}", e)
            return False

        cv2.imwrite(
            os.path.join(self.temp_dir_path,
                         str(identifier) + '_exitcircle.jpg'), image)

        if self.__read_circle_count(os.path.join(
                self.temp_dir_path,
                str(identifier) + '_exitcircle.jpg'),
                                    identifier,
                                    float(radiusratio),
                                    communicator,
                                    xcord=False,
                                    crop=True,
                                    click=True,
                                    canny=True) > 0:
            return True
Esempio n. 3
0
    def parse_ggl(self, xml, mail: str) -> bool:
        if xml is None:
            logger.warning(
                'Something wrong with processing - getting None Type from Websocket...'
            )
            return False
        try:
            parser = ET.XMLParser(encoding="utf-8")
            xmlroot = ET.fromstring(xml, parser=parser)
            for item in xmlroot.iter('node'):
                if mail.lower() in str(item.attrib['text']).lower():
                    logger.info("Found mail {}",
                                self.censor_account(str(item.attrib['text'])))
                    bounds = item.attrib['bounds']
                    logger.debug("Bounds {}", str(item.attrib['bounds']))
                    match = re.search(r'^\[(\d+),(\d+)\]\[(\d+),(\d+)\]$',
                                      bounds)
                    click_x = int(match.group(1)) + (
                        (int(match.group(3)) - int(match.group(1))) / 2)
                    click_y = int(match.group(2)) + (
                        (int(match.group(4)) - int(match.group(2))) / 2)
                    logger.debug('Click ' + str(click_x) + ' / ' +
                                 str(click_y))
                    self._communicator.click(click_x, click_y)
                    time.sleep(2)
                    return True
        except Exception as e:
            logger.error('Something wrong while parsing xml: {}'.format(
                str(e)))
            return False

        time.sleep(2)
        logger.warning('Dont find any mailaddress...')
        return False
Esempio n. 4
0
    async def __client_message_receiver(
            self, origin: str,
            client_entry: WebsocketConnectedClientEntry) -> None:
        if client_entry is None:
            return
        logger.info("Consumer handler of {} starting", origin)
        while client_entry.websocket_client_connection.open:
            message = None
            try:
                message = await asyncio.wait_for(
                    client_entry.websocket_client_connection.recv(),
                    timeout=4.0)
            except asyncio.TimeoutError:
                await asyncio.sleep(0.02)
            except websockets.exceptions.ConnectionClosed as cc:
                # TODO: cleanup needed here? better suited for the handler
                logger.warning(
                    "Connection to {} was closed, stopping receiver. Exception: ",
                    origin, cc)
                return

            if message is not None:
                await self.__on_message(client_entry, message)
        logger.warning("Connection of {} closed in __client_message_receiver",
                       str(origin))
Esempio n. 5
0
 def download_pogo(self, architecture):
     # Determine the version and fileid
     sql = "SELECT `version` FROM `mad_apks` WHERE `usage` = %s AND `arch` = %s"
     current_ver = self.dbc.autofetch_value(
         sql, args=(global_variables.MAD_APK_USAGE_POGO, architecture))
     latest_data = self.get_lastest(global_variables.MAD_APK_USAGE_POGO,
                                    architecture)
     if not latest_data or latest_data['url'] is None:
         self.find_latest_pogo(architecture)
         latest_data = self.get_lastest(global_variables.MAD_APK_USAGE_POGO,
                                        architecture)
     if not latest_data:
         logger.warning('Unable to find latest data for PoGo')
     else:
         if current_ver is None or is_newer_version(latest_data['version'],
                                                    current_ver):
             filename = 'pogo_%s_%s.apk' % (
                 architecture,
                 latest_data['version'],
             )
             download_url = latest_data['url']
             apk = APKDownloader(self.dbc,
                                 download_url,
                                 architecture,
                                 global_variables.MAD_APK_USAGE_POGO,
                                 filename=filename)
             apk.upload_file()
Esempio n. 6
0
 def __update_mad(self):
     if self._madver < self._installed_ver:
         logger.error('Mis-matched version number detected.  Not applying any updates')
     else:
         logger.warning('Performing updates from version {} to {} now',
                        self._installed_ver, self._madver)
         all_patches = list(MAD_UPDATES.keys())
         try:
             last_ver = all_patches.index(self._installed_ver)
             first_patch = last_ver + 1
         except ValueError:
             # The current version of the patch was most likely removed as it was no longer needed.  Determine
             # where to start by finding the last executed
             next_patch = None
             for patch_ver in all_patches:
                 if self._installed_ver > patch_ver:
                     continue
                 next_patch = patch_ver
                 break
             try:
                 first_patch = all_patches.index(next_patch)
             except ValueError:
                 logger.critical('Unable to find the next patch to apply')
         updates_to_apply = all_patches[first_patch:]
         logger.info('Patches to apply: {}', updates_to_apply)
         for patch_ver in updates_to_apply:
             self.__apply_update(patch_ver)
         logger.success('Updates to version {} finished', self._installed_ver)
Esempio n. 7
0
    async def __consumer_handler(
            self,
            websocket_client_connection: websockets.WebSocketClientProtocol):
        if websocket_client_connection is None:
            return
        worker_id = str(
            websocket_client_connection.request_headers.get_all("Origin")[0])
        logger.info("Consumer handler of {} starting", str(worker_id))
        while websocket_client_connection.open:
            message = None
            try:
                message = await asyncio.wait_for(
                    websocket_client_connection.recv(), timeout=4.0)
            except asyncio.TimeoutError as te:
                await asyncio.sleep(0.02)
            except websockets.exceptions.ConnectionClosed as cc:
                logger.warning("Connection to {} was closed, stopping worker",
                               str(worker_id))
                async with self.__users_mutex:
                    worker = self.__current_users.get(worker_id, None)
                if worker is not None:
                    # TODO: do it abruptly in the worker, maybe set a flag to be checked for in send_and_wait to
                    # TODO: throw an exception
                    worker[1].stop_worker()
                await self.__internal_clean_up_user(worker_id, None)
                return

            if message is not None:
                await self.__on_message(message)
        logger.warning("Connection of {} closed in consumer_handler",
                       str(worker_id))
Esempio n. 8
0
 def __internal_worker_join(self):
     while not self.__stop_server.is_set() \
             or (self.__stop_server.is_set() and not self.__worker_shutdown_queue.empty()):
         try:
             next_item: Optional[
                 Thread] = self.__worker_shutdown_queue.get_nowait()
         except queue.Empty:
             time.sleep(1)
             continue
         if next_item is not None:
             logger.info("Trying to join worker thread")
             try:
                 next_item.join(10)
             except RuntimeError as e:
                 logger.warning(
                     "Caught runtime error trying to join thread, the thread likely did not start "
                     "at all. Exact message: {}", e)
             if next_item.is_alive():
                 logger.debug(
                     "Error while joining worker thread - requeue it")
                 self.__worker_shutdown_queue.put(next_item)
             else:
                 logger.debug("Done with worker thread, moving on")
         self.__worker_shutdown_queue.task_done()
     logger.info("Worker join-thread done")
Esempio n. 9
0
    def parse_permission(self, xml) -> bool:
        if xml is None:
            logger.warning('Something wrong with processing - getting None Type from Websocket...')
            return False
        click_text = ('ZULASSEN', 'ALLOW', 'AUTORISER')
        try:
            parser = ET.XMLParser(encoding="utf-8")
            xmlroot = ET.fromstring(xml, parser=parser)
            bounds: str = ""
            for item in xmlroot.iter('node'):
                if str(item.attrib['text']).upper() in click_text:
                    logger.debug("Found text {}", str(item.attrib['text']))
                    bounds = item.attrib['bounds']
                    logger.debug("Bounds {}", str(item.attrib['bounds']))

                    match = re.search(r'^\[(\d+),(\d+)\]\[(\d+),(\d+)\]$', bounds)

                    click_x = int(match.group(1)) + ((int(match.group(3)) - int(match.group(1))) / 2)
                    click_y = int(match.group(2)) + ((int(match.group(4)) - int(match.group(2))) / 2)
                    logger.debug('Click ' + str(click_x) + ' / ' + str(click_y))
                    self._communicator.click(click_x, click_y)
                    time.sleep(2)
                    return True
        except Exception as e:
            logger.error('Something wrong while parsing xml: {}'.format(str(e)))
            return False

        time.sleep(2)
        logger.warning('Dont find any button...')
        return False
Esempio n. 10
0
    def get_next_raid_hatches(self, delay_after_hatch, geofence_helper=None):
        """
        In order to build a priority queue, we need to be able to check for the next hatches of raid eggs
        The result may not be sorted by priority, to be done at a higher level!
        :return: unsorted list of next hatches within delay_after_hatch
        """
        logger.debug("DbWrapper::get_next_raid_hatches called")
        db_time_to_check = datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%d %H:%M:%S")

        query = (
            "SELECT start, latitude, longitude "
            "FROM raid "
            "LEFT JOIN gym ON raid.gym_id = gym.gym_id WHERE raid.end > %s AND raid.pokemon_id IS NULL"
        )
        vals = (db_time_to_check, )

        res = self.execute(query, vals)
        data = []
        for (start, latitude, longitude) in res:
            if latitude is None or longitude is None:
                logger.warning("lat or lng is none")
                continue
            elif geofence_helper and not geofence_helper.is_coord_inside_include_geofence(
                [latitude, longitude]):
                logger.debug(
                    "Excluded hatch at {}, {} since the coordinate is not inside the given include fences",
                    str(latitude), str(longitude))
                continue
            timestamp = self.__db_timestring_to_unix_timestamp(str(start))
            data.append(
                (timestamp + delay_after_hatch, Location(latitude, longitude)))

        logger.debug("Latest Q: {}", str(data))
        return data
Esempio n. 11
0
    def _check_unprocessed_stops(self):
        self._manager_mutex.acquire()

        try:
            list_of_stops_to_return: List[Location] = []

            if len(self._stoplist) == 0:
                return list_of_stops_to_return
            else:
                # we only want to add stops that we haven't spun yet
                for stop in self._stoplist:
                    if stop not in self._stops_not_processed and stop not in self._get_unprocessed_coords_from_worker():
                        self._stops_not_processed[stop] = 1
                    else:
                        self._stops_not_processed[stop] += 1

            for stop, error_count in self._stops_not_processed.items():
                if stop not in self._stoplist:
                    logger.info(
                        "Location {} is no longer in our stoplist and will be ignored".format(str(stop)))
                    self._coords_to_be_ignored.add(stop)
                elif error_count < 4:
                    logger.warning("Found stop not processed yet: {}".format(str(stop)))
                    list_of_stops_to_return.append(stop)
                else:
                    logger.error("Stop {} has not been processed thrice in a row, "
                                 "please check your DB".format(str(stop)))
                    self._coords_to_be_ignored.add(stop)

            if len(list_of_stops_to_return) > 0:
                logger.info("Found stops not yet processed, retrying those in the next round")
            return list_of_stops_to_return
        finally:
            self._manager_mutex.release()
Esempio n. 12
0
    def run(self):
        # build a private DbWrapper instance...
        logger.info("Starting MITMDataProcessor")
        while True:
            try:
                item = self.__queue.get()

                try:
                    items_left = self.__queue.qsize()
                except NotImplementedError:
                    items_left = 0

                logger.debug(
                    "MITM data processing worker retrieved data. Queue length left afterwards: {}",
                    str(items_left))
                if items_left > 50:
                    logger.warning(
                        "MITM data processing workers are falling behind! Queue length: {}", str(items_left))

                if item is None:
                    logger.warning("Received none from queue of data")
                    break
                self.process_data(item[0], item[1], item[2])
                self.__queue.task_done()
            except KeyboardInterrupt as e:
                logger.info("MITMDataProcessor received keyboard interrupt, stopping")
                break
Esempio n. 13
0
 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():
         if self._args.config_mode:
             time.sleep(10)
         else:
             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()
     finally:
         logger.info("Internal cleanup of {} finished", str(self._origin))
     return
Esempio n. 14
0
 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))
Esempio n. 15
0
    def _post_move_location_routine(self, timestamp: float):
        if self._stop_worker_event.is_set():
            raise InternalStopWorkerException
        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")
            raise InternalStopWorkerException

        if self.get_devicesettings_value('rotate_on_lvl_30', False) and \
                self._mitm_mapper.get_playerlevel(self._origin) >= 30 and self._level_mode:
            # switch if player lvl >= 30
            self.switch_account()

        try:
            self._work_mutex.acquire()
            if not self._mapping_manager.routemanager_get_init(self._routemanager_name):
                logger.info("Processing Stop / Quest...")

                reachedMainMenu = self._check_pogo_main_screen(10, False)
                if not reachedMainMenu:
                    self._restart_pogo(mitm_mapper=self._mitm_mapper)

                logger.info('Open Stop')
                self._stop_process_time = math.floor(time.time())
                data_received = self._open_pokestop(self._stop_process_time)
                if data_received is not None and data_received == LatestReceivedType.STOP:
                    self._handle_stop(self._stop_process_time)

            else:
                logger.debug('Currently in INIT Mode - no Stop processing')
                time.sleep(5)
        finally:
            logger.debug("Releasing lock")
            self._work_mutex.release()
Esempio n. 16
0
    def __evaluate_topmost_app(
            self, topmost_app: str) -> Tuple[ScreenType, dict, int]:
        returntype: ScreenType = ScreenType.UNDEFINED
        global_dict: dict = {}
        diff = 1
        if "AccountPickerActivity" in topmost_app or 'SignInActivity' in topmost_app:
            return ScreenType.GGL, global_dict, diff
        elif "GrantPermissionsActivity" in topmost_app:
            return ScreenType.PERMISSION, global_dict, diff
        elif "GrantCredentialsWithAclNoTouchActivity" in topmost_app or "GrantCredentials" in topmost_app:
            return ScreenType.CREDENTIALS, global_dict, diff
        elif "ConsentActivity" in topmost_app:
            return ScreenType.CONSENT, global_dict, diff
        elif "com.nianticlabs.pokemongo" not in topmost_app:
            logger.warning("PoGo ist not opened! Current topmost app: {}",
                           topmost_app)
            return ScreenType.CLOSE, global_dict, diff
        elif self._nextscreen != ScreenType.UNDEFINED:
            # TODO: how can the nextscreen be known in the current? o.O
            return self._nextscreen, global_dict, diff
        elif not self.get_devicesettings_value('screendetection', False):
            logger.info('No more screen detection - disabled ...')
            return ScreenType.DISABLED, global_dict, diff
        else:
            if not self._takeScreenshot(
                    delayBefore=self.get_devicesettings_value(
                        "post_screenshot_delay", 1),
                    delayAfter=2):
                logger.error("_check_windows: Failed getting screenshot")
                return ScreenType.ERROR, global_dict, diff

            screenpath = self.get_screenshot_path()

            result = self._pogoWindowManager.screendetection_get_type_by_screen_analysis(
                screenpath, self._id)
            if result is None:
                logger.error("Failed analysing screen")
                return ScreenType.ERROR, global_dict, diff
            else:
                returntype, global_dict, self._width, self._height, diff = result
            if not global_dict:
                self._nextscreen = ScreenType.UNDEFINED
                logger.warning(
                    'Could not understand any text on screen - starting next round...'
                )
                return ScreenType.ERROR, global_dict, diff

            self._ratio = self._height / self._width

            logger.debug("Screenratio of origin {}: {}".format(
                str(self._id), str(self._ratio)))

            if 'text' not in global_dict:
                logger.error('Error while text detection')
                return ScreenType.ERROR, global_dict, diff
            elif returntype == ScreenType.UNDEFINED and "com.nianticlabs.pokemongo" in topmost_app:
                return ScreenType.POGO, global_dict, diff

        return returntype, global_dict, diff
Esempio n. 17
0
    def __call__(self, *args, **kwargs):
        logger.debug3("HTTP Request from {}".format(str(request.remote_addr)))
        origin = request.headers.get('Origin')
        abort = False
        if request.url_rule is not None and str(request.url_rule) == '/status/':
            auth = request.headers.get('Authorization', False)
            if self.application_args.mitm_status_password != "" and \
                    (not auth or auth != self.application_args.mitm_status_password):
                self.response = Response(status=500, headers={})
                abort = True
            else:
                abort = False
        elif request.url is not None and str(request.url_rule) == '/origin_generator':
            auth = request.headers.get('Authorization', None)
            if auth is None or not check_auth(auth, self.application_args,
                                              self.mapping_manager.get_auths()):
                logger.warning(
                    "Unauthorized attempt to POST from {}", str(request.remote_addr))
                self.response = Response(status=403, headers={})
                abort = True
        else:
            if not origin:
                logger.warning("Missing Origin header in request")
                self.response = Response(status=500, headers={})
                abort = True
            elif (self.mapping_manager.get_all_devicemappings().keys() is not None
                  and (origin is None or origin not in self.mapping_manager.get_all_devicemappings().keys())):
                logger.warning("MITMReceiver request without Origin or disallowed Origin: {}".format(origin))
                self.response = Response(status=403, headers={})
                abort = True
            elif self.mapping_manager.get_auths() is not None:
                auth = request.headers.get('Authorization', None)
                if auth is None or not check_auth(auth, self.application_args,
                                                  self.mapping_manager.get_auths()):
                    logger.warning(
                        "Unauthorized attempt to POST from {}", str(request.remote_addr))
                    self.response = Response(status=403, headers={})
                    abort = True

        if not abort:
            try:
                # TODO: use response data
                if len(request.data) > 0:
                    request_data = json.loads(request.data)
                else:
                    request_data = {}
                response_payload = self.action(origin, request_data, *args, **kwargs)
                if response_payload is None:
                    response_payload = ""
                if type(response_payload) is Response:
                    self.response = response_payload
                else:
                    self.response = Response(status=200, headers={"Content-Type": "application/json"})
                    self.response.data = response_payload
            except Exception as e:  # TODO: catch exact exception
                logger.warning(
                    "Could not get JSON data from request: {}", str(e))
                self.response = Response(status=500, headers={})
        return self.response
Esempio n. 18
0
    def _extract_args_single_stop(self, stop_data):
        if stop_data["type"] != 1:
            logger.warning("{} is not a pokestop", str(stop_data))
            return None

        now = datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%d %H:%M:%S")
        last_modified = datetime.utcfromtimestamp(
            stop_data["last_modified_timestamp_ms"] /
            1000).strftime("%Y-%m-%d %H:%M:%S")
        lure = "1970-01-01 00:00:00"
        active_fort_modifier = None
        incident_start = None
        incident_expiration = None
        incident_grunt_type = None

        if len(stop_data["active_fort_modifier"]) > 0:
            active_fort_modifier = stop_data["active_fort_modifier"][0]
            lure = datetime.utcfromtimestamp(self._lure_duration * 60 + (
                stop_data["last_modified_timestamp_ms"] /
                1000)).strftime("%Y-%m-%d %H:%M:%S")

        if "pokestop_displays" in stop_data \
                and len(stop_data["pokestop_displays"]) > 0 \
                and stop_data["pokestop_displays"][0]["character_display"] is not None \
                and stop_data["pokestop_displays"][0]["character_display"]["character"] > 1:
            start_ms = stop_data["pokestop_displays"][0]["incident_start_ms"]
            expiration_ms = stop_data["pokestop_displays"][0][
                "incident_expiration_ms"]
            incident_grunt_type = stop_data["pokestop_displays"][0][
                "character_display"]["character"]

            if start_ms > 0:
                incident_start = datetime.utcfromtimestamp(
                    start_ms / 1000).strftime("%Y-%m-%d %H:%M:%S")

            if expiration_ms > 0:
                incident_expiration = datetime.utcfromtimestamp(
                    expiration_ms / 1000).strftime("%Y-%m-%d %H:%M:%S")
        elif "pokestop_display" in stop_data:
            start_ms = stop_data["pokestop_display"]["incident_start_ms"]
            expiration_ms = stop_data["pokestop_display"][
                "incident_expiration_ms"]
            incident_grunt_type = stop_data["pokestop_display"][
                "character_display"]["character"]

            if start_ms > 0:
                incident_start = datetime.utcfromtimestamp(
                    start_ms / 1000).strftime("%Y-%m-%d %H:%M:%S")

            if expiration_ms > 0:
                incident_expiration = datetime.utcfromtimestamp(
                    expiration_ms / 1000).strftime("%Y-%m-%d %H:%M:%S")

        return (stop_data["id"], 1, stop_data["latitude"],
                stop_data["longitude"], last_modified, lure, now,
                active_fort_modifier, incident_start, incident_expiration,
                incident_grunt_type)
Esempio n. 19
0
    def download_pogo(self, architecture: APK_Arch) -> NoReturn:
        """ Download the package com.nianticlabs.pokemongo

        Determine if theres a newer version of com.nianticlabs.pokemongo.  If a new version exists, validate it is
        supported by MAD.  If the release is supported download and save to the storage interface

        Args:
            architecture (APK_Arch): Architecture of the package to download
        """
        latest_version = self.find_latest_pogo(architecture)
        if latest_version is None:
            logger.warning(
                'Unable to find latest data for PoGo.  Try again later')
        elif supported_pogo_version(architecture, latest_version):
            current_version = self.storage.get_current_version(
                APK_Type.pogo, architecture)
            if type(current_version) is not str:
                current_version = None
            if current_version is None or is_newer_version(
                    latest_version, current_version):
                where = {
                    'usage': APK_Type.pogo.value,
                    'arch': architecture.value
                }
                try:
                    update_data = {'download_status': 1}
                    self.dbc.autoexec_update('mad_apk_autosearch',
                                             update_data,
                                             where_keyvals=where)
                    retries: int = 0
                    successful: bool = False
                    while retries < MAX_RETRIES and not successful:
                        self.gpconn = GPlayConnector(architecture)
                        downloaded_file = self.gpconn.download(
                            APK_Package.pogo.value)
                        if downloaded_file and downloaded_file.getbuffer(
                        ).nbytes > 0:
                            PackageImporter(APK_Type.pogo,
                                            architecture,
                                            self.storage,
                                            downloaded_file,
                                            'application/zip',
                                            version=latest_version)
                            successful = True
                        else:
                            logger.info("Issue downloading apk")
                            retries += 1
                            if retries < MAX_RETRIES:
                                logger.warning(
                                    'Unable to successfully download the APK')
                except:  # noqa: E722
                    raise
                finally:
                    update_data['download_status'] = 0
                    self.dbc.autoexec_update('mad_apk_autosearch',
                                             update_data,
                                             where_keyvals=where)
Esempio n. 20
0
 def connect_gmail(self, username: str, password: str) -> bool:
     logger.debug('Attempting GPlay Auth')
     try:
         self.api.login(email=username, password=password)
         logger.debug('GPlay Auth Successful')
         return True
     except LoginError as err:
         logger.warning('Unable to login to GPlay: {}', err)
         raise
Esempio n. 21
0
 def __handle_strike_screen(self, diff, global_dict) -> None:
     self._nextscreen = ScreenType.UNDEFINED
     logger.warning('Got a black strike warning!')
     click_text = 'GOT IT,ALLES KLAR'
     n_boxes = len(global_dict['level'])
     for i in range(n_boxes):
         if any(elem.lower() in (global_dict['text'][i].lower()) for elem in click_text.split(",")):
             self._click_center_button(diff, global_dict, i)
             time.sleep(2)
Esempio n. 22
0
 def worker_stats(self):
     logger.debug('===============================')
     logger.debug('Worker Stats')
     logger.debug('Origin: {} [{}]', str(self._origin), str(self._dev_id))
     logger.debug('Routemanager: {} [{}]', str(self._routemanager_name),
                  str(self._area_id))
     logger.debug('Restart Counter: {}', str(self._restart_count))
     logger.debug('Reboot Counter: {}', str(self._reboot_count))
     logger.debug('Reboot Option: {}',
                  str(self.get_devicesettings_value("reboot", False)))
     logger.debug('Current Pos: {} {}', str(self.current_location.lat),
                  str(self.current_location.lng))
     logger.debug('Last Pos: {} {}', str(self.last_location.lat),
                  str(self.last_location.lng))
     routemanager_status = self._mapping_manager.routemanager_get_route_stats(
         self._routemanager_name, self._origin)
     if routemanager_status is None:
         logger.warning("Routemanager not available")
         routemanager_status = [None, None]
     else:
         logger.debug('Route Pos: {} - Route Length: {}',
                      str(routemanager_status[0]),
                      str(routemanager_status[1]))
     routemanager_init: bool = self._mapping_manager.routemanager_get_init(
         self._routemanager_name)
     logger.debug('Init Mode: {}', str(routemanager_init))
     logger.debug('Last Date/Time of Data: {}', str(self._rec_data_time))
     logger.debug('===============================')
     save_data = {
         'device_id':
         self._dev_id,
         'currentPos':
         'POINT(%s,%s)' %
         (self.current_location.lat, self.current_location.lng),
         'lastPos':
         'POINT(%s,%s)' % (self.last_location.lat, self.last_location.lng),
         'routePos':
         routemanager_status[0],
         'routeMax':
         routemanager_status[1],
         'area_id':
         self._area_id,
         'rebootCounter':
         self._reboot_count,
         'init':
         routemanager_init,
         'rebootingOption':
         self.get_devicesettings_value("reboot", False),
         'restartCounter':
         self._restart_count,
         'currentSleepTime':
         self._current_sleep_time
     }
     if self._rec_data_time:
         save_data['lastProtoDateTime'] = 'NOW()'
         self._rec_data_time = None
     self._db_wrapper.save_status(save_data)
Esempio n. 23
0
    def _clear_quests(self, delayadd, openmenu=True):
        logger.debug('{_clear_quests} called')
        if openmenu:
            x, y = self._resocalc.get_coords_quest_menu(self)[0], \
                   self._resocalc.get_coords_quest_menu(self)[1]
            self._communicator.click(int(x), int(y))
            logger.debug("_clear_quests Open menu: {}, {}", str(int(x)), str(int(y)))
            time.sleep(6 + int(delayadd))

        x, y = self._resocalc.get_quest_listview(self)[0], \
               self._resocalc.get_quest_listview(self)[1]
        self._communicator.click(int(x), int(y))
        logger.debug("_clear_quests Open field: {}, {}", str(int(x)), str(int(y)))
        time.sleep(4 + int(delayadd))

        trashcancheck = self._get_trash_positions(full_screen=True)
        logger.debug("_clear_quests Found trash: {}", str(trashcancheck))
        if trashcancheck is None:
            logger.error('Could not find any trashcan - abort')
            return
        if len(trashcancheck) == 0:
            self._clear_quests_failcount += 1
            if self._clear_quests_failcount < 3:
                logger.warning("Could not find any trashcan on a valid screen"
                    "shot {} time(s) in a row!", self._clear_quests_failcount)
            else:
                self._clear_quests_failcount = 0
                logger.error("Unable to clear quests 3 times in a row. Restart "
                        "pogo ...")
                if not self._restart_pogo(mitm_mapper=self._mitm_mapper):
                    # TODO: put in loop, count up for a reboot ;)
                    raise InternalStopWorkerException
                return
        else:
            logger.info("Found {} trashcan(s) on screen", len(trashcancheck))
        # get confirm box coords
        x, y = self._resocalc.get_confirm_delete_quest_coords(self)[0], \
               self._resocalc.get_confirm_delete_quest_coords(self)[1]

        for trash in range(len(trashcancheck)):
            self._clear_quests_failcount = 0
            self.set_devicesettings_value('last_questclear_time', time.time())
            logger.info("Delete old quest {}", int(trash) + 1)
            self._communicator.click(int(trashcancheck[0].x), int(trashcancheck[0].y))
            time.sleep(1 + int(delayadd))
            self._communicator.click(int(x), int(y))
            time.sleep(1 + int(delayadd))

        x, y = self._resocalc.get_close_main_button_coords(self)[0], \
               self._resocalc.get_close_main_button_coords(self)[1]
        self._communicator.click(int(x), int(y))

        time.sleep(1.5)

        logger.debug('{_clear_quests} finished')
        return
Esempio n. 24
0
    async def __authenticate_connection(self, websocket_client_connection: websockets.WebSocketClientProtocol) \
            -> Optional[str]:
        """
        :param websocket_client_connection:
        :return: origin (string) if the auth and everything else checks out, else None to signal abort
        """
        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 None

        if not self.__data_manager.is_device_active(origin):
            logger.warning(
                'Origin %s is currently paused.  Unpause through MADmin to begin working',
                origin)
            return None
        logger.info("Client {} registering", str(origin))
        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 None

        valid_auths = self.__mapping_manager.get_auths()
        auth_base64 = None
        if valid_auths:
            try:
                auth_base64 = 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 None
        if valid_auths and auth_base64 and not check_auth(
                auth_base64, self.__args, valid_auths):
            logger.warning(
                "Invalid auth details received from {}",
                str(
                    websocket_client_connection.request_headers.get_all(
                        "Origin")[0]))
            return None
        return origin
Esempio n. 25
0
    def _open_pokestop(self, timestamp: float):
        to = 0
        data_received = LatestReceivedType.UNDEFINED

        # let's first check the GMO for the stop we intend to visit and abort if it's disabled, a gym, whatsoever
        spinnable_stop, skip_recheck = self._current_position_has_spinnable_stop(timestamp)
        if not spinnable_stop:
            if not skip_recheck:
                # wait for GMO in case we moved too far away
                data_received = self._wait_for_data(
                    timestamp=timestamp, proto_to_wait_for=106, timeout=35)
                if data_received != LatestReceivedType.UNDEFINED:
                    spinnable_stop, _ = self._current_position_has_spinnable_stop(timestamp)
                    if not spinnable_stop:
                        logger.info("Stop {}, {} "
                                    "considered to be ignored in the next round due to failed spinnable check",
                                    str(self.current_location.lat), str(self.current_location.lng))
                        self._mapping_manager.routemanager_add_coords_to_be_removed(self._routemanager_name,
                                                                                    self.current_location.lat,
                                                                                    self.current_location.lng)
                        return None
            else:
                return None
        while data_received != LatestReceivedType.STOP and int(to) < 3:
            self._stop_process_time = math.floor(time.time())
            self._waittime_without_delays = self._stop_process_time
            self._open_gym(self._delay_add)
            self.set_devicesettings_value('last_action_time', time.time())
            data_received = self._wait_for_data(
                timestamp=self._stop_process_time, proto_to_wait_for=104, timeout=15)
            if data_received == LatestReceivedType.GYM:
                logger.info('Clicking GYM')
                time.sleep(10)
                x, y = self._resocalc.get_close_main_button_coords(
                    self)[0], self._resocalc.get_close_main_button_coords(self)[1]
                self._communicator.click(int(x), int(y))
                time.sleep(3)
                self._turn_map(self._delay_add)
                time.sleep(1)
            elif data_received == LatestReceivedType.MON:
                time.sleep(1)
                logger.info('Clicking MON')
                time.sleep(.5)
                self._turn_map(self._delay_add)
                time.sleep(1)
            elif data_received == LatestReceivedType.UNDEFINED:
                logger.info('Getting timeout - or other unknown error. Try again')
                if not self._checkPogoButton():
                    self._checkPogoClose(takescreen=True)

            to += 1
            if to > 2:
                logger.warning("Giving up on this stop after 3 failures in open_pokestop loop")
        return data_received
Esempio n. 26
0
 def get_devicesettings_value(self, key: str, default_value: object = None):
     logger.debug2("Fetching devicemappings of {}".format(self._id))
     try:
         devicemappings: Optional[dict] = self._mapping_manager.get_devicemappings_of(self._id)
     except (EOFError, FileNotFoundError) as e:
         logger.warning("Failed fetching devicemappings in worker {} with description: {}. Stopping worker"
                        .format(str(self._id), str(e)))
         return None
     if devicemappings is None:
         return default_value
     return devicemappings.get("settings", {}).get(key, default_value)
Esempio n. 27
0
 async def __close_and_signal_stop(self, origin: str) -> None:
     logger.info("Signalling {} to stop", origin)
     async with self.__current_users_mutex:
         entry: Optional[WebsocketConnectedClientEntry] = self.__current_users.get(origin, None)
         if entry is not None:
             entry.worker_instance.stop_worker()
             await self.__close_websocket_client_connection(entry.origin,
                                                            entry.websocket_client_connection)
             logger.info("Done signalling {} to stop", origin)
         else:
             logger.warning("Unable to signal {} to stop, not present", origin)
Esempio n. 28
0
 def get_apk_info(self, downloaded_file: io.BytesIO) -> NoReturn:
     try:
         apk = apkutils.APK(downloaded_file)
     except:  # noqa: E722
         logger.warning('Unable to parse APK file')
     else:
         manifest = apk.get_manifest()
         try:
             self.package_version, self.package_name = (
                 manifest['@android:versionName'], manifest['@package'])
         except KeyError:
             raise InvalidFile('Unable to parse the APK file')
Esempio n. 29
0
    def detect_screentype(self) -> ScreenType:
        topmostapp = self._communicator.topmost_app()
        if not topmostapp:
            logger.warning("Failed getting the topmost app!")
            return ScreenType.ERROR

        screentype, global_dict, diff = self.__evaluate_topmost_app(
            topmost_app=topmostapp)
        logger.info("Processing Screen: {}", str(ScreenType(screentype)))
        return self.__handle_screentype(screentype=screentype,
                                        global_dict=global_dict,
                                        diff=diff)
Esempio n. 30
0
def pre_check_value(walker_settings, eventid):
    walkertype = walker_settings['walkertype']
    walkereventid = walker_settings.get('eventid', None)
    if walkereventid is not None and walkereventid != eventid:
        logger.warning("Area is used for another event - leaving now")
        return False
    if walkertype in ('timer', 'period', 'coords', 'idle'):
        walkervalue = walker_settings['walkervalue']
        if len(walkervalue) == 0:
            return True
        return check_walker_value_type(walkervalue)
    return True