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
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
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
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))
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()
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)
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))
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")
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
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
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()
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
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
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 _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()
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
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
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)
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)
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
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)
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)
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
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
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
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)
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)
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')
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)
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