def __prepare_weather_data(self, weather_data): ret = [] for weather in weather_data: weather_payload = { "s2_cell_id": weather["s2_cell_id"], "condition": weather["gameplay_weather"], "alert_severity": weather["severity"], "day": weather["world_time"], "time_changed": weather["last_updated"], } # required by PA but not provided by Monocle if weather.get("latitude", None) is None: weather_payload["latitude"] = S2Helper.middle_of_cell( weather["s2_cell_id"])[0] else: weather_payload["latitude"] = weather["latitude"] if weather.get("longitude", None) is None: weather_payload["longitude"] = S2Helper.middle_of_cell( weather["s2_cell_id"])[1] else: weather_payload["longitude"] = weather["longitude"] if weather.get("coords", None) is None: weather_payload["coords"] = S2Helper.coords_of_cell( weather["s2_cell_id"]) else: weather_payload["coords"] = weather["coords"] entire_payload = {"type": "weather", "message": weather_payload} ret.append(entire_payload) return ret
def _extract_args_single_weather(self, client_weather_data, time_of_day, received_timestamp): now = datetime.utcfromtimestamp( time.time()).strftime("%Y-%m-%d %H:%M:%S") cell_id = client_weather_data["cell_id"] real_lat, real_lng = S2Helper.middle_of_cell(cell_id) display_weather_data = client_weather_data.get("display_weather", None) if display_weather_data is None: return None else: gameplay_weather = client_weather_data["gameplay_weather"][ "gameplay_condition"] return ( cell_id, real_lat, real_lng, display_weather_data.get("cloud_level", 0), display_weather_data.get("rain_level", 0), display_weather_data.get("wind_level", 0), display_weather_data.get("snow_level", 0), display_weather_data.get("fog_level", 0), display_weather_data.get("wind_direction", 0), gameplay_weather, # TODO: alerts 0, 0, time_of_day, now)
def __extract_args_single_weather(self, client_weather_data, time_of_day, received_timestamp): now = datetime.utcfromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') cell_id = client_weather_data["cell_id"] real_lat, real_lng = S2Helper.middle_of_cell(cell_id) display_weather_data = client_weather_data.get("display_weather", None) if display_weather_data is None: return None elif time_of_day == 2 and client_weather_data["gameplay_weather"]["gameplay_condition"] == 3: gameplay_weather = 13 else: gameplay_weather = client_weather_data["gameplay_weather"]["gameplay_condition"] now_timezone = datetime.fromtimestamp(float(received_timestamp)) now_timezone = time.mktime(now_timezone.timetuple()) - (self.timezone * 60 * 60) self.webhook_helper.send_weather_webhook(cell_id, gameplay_weather, 0, 0, time_of_day, now_timezone) return ( cell_id, real_lat, real_lng, display_weather_data.get("cloud_level", 0), display_weather_data.get("rain_level", 0), display_weather_data.get("wind_level", 0), display_weather_data.get("snow_level", 0), display_weather_data.get("fog_level", 0), display_weather_data.get("wind_direction", 0), gameplay_weather, # TODO: alerts 0, 0, time_of_day, now )
def update_insert_weather(self, cell_id, gameplay_weather, capture_time, cloud_level=0, rain_level=0, wind_level=0, snow_level=0, fog_level=0, wind_direction=0, weather_daytime=0): log.debug("{RmWrapper::update_insert_weather} called") now_timezone = datetime.fromtimestamp(float(capture_time)) now_timezone = time.mktime(now_timezone.timetuple()) - (self.timezone * 60 * 60) now = now = datetime.utcfromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') real_lat, real_lng = S2Helper.middle_of_cell(cell_id) if weather_daytime == 2 and gameplay_weather == 3: gameplay_weather = 13 # TODO: put severity and warn_weather properly query = 'INSERT INTO weather (s2_cell_id, latitude, longitude, cloud_level, rain_level, wind_level, ' \ 'snow_level, fog_level, wind_direction, gameplay_weather, severity, warn_weather, world_time, ' \ 'last_updated) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, \'%s\') ' \ 'ON DUPLICATE KEY UPDATE fog_level=%s, cloud_level=%s, snow_level=%s, wind_direction=%s, ' \ 'world_time=%s, latitude=%s, longitude=%s, gameplay_weather=%s, last_updated=\'%s\'' data = (cell_id, real_lat, real_lng, cloud_level, rain_level, wind_level, snow_level, fog_level, wind_direction, gameplay_weather, None, None, weather_daytime, str(now), fog_level, cloud_level, snow_level, wind_direction, weather_daytime, real_lat, real_lng, gameplay_weather, str(now)) self.execute(query, data, commit=True) self.webhook_helper.send_weather_webhook( cell_id, gameplay_weather, 0, 0, weather_daytime, now_timezone )
def __fetch_coords(self, mode: str, geofence_helper: GeofenceHelper, coords_spawns_known: bool = False, init: bool = False, range_init: int = 630, including_stops: bool = False) -> List[Location]: coords: List[Location] = [] if not init: # grab data from DB depending on mode # TODO: move routemanagers to factory if mode == "raids_mitm": coords = self.__db_wrapper.gyms_from_db(geofence_helper) if including_stops: coords.extend(self.__db_wrapper.stops_from_db(geofence_helper)) elif mode == "mon_mitm": if coords_spawns_known: logger.debug("Reading known Spawnpoints from DB") coords = self.__db_wrapper.get_detected_spawns(geofence_helper) else: logger.debug("Reading unknown Spawnpoints from DB") coords = self.__db_wrapper.get_undetected_spawns(geofence_helper) elif mode == "pokestops": coords = self.__db_wrapper.stops_from_db(geofence_helper) else: logger.error("Mode not implemented yet: {}", str(mode)) exit(1) else: # calculate all level N cells (mapping back from mapping above linked to mode) coords = S2Helper._generate_locations(range_init, geofence_helper) return coords
def set_scanned_location(self, lat, lng, capture_time): log.debug("{RmWrapper::set_scanned_location} called") now = datetime.utcfromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S') cell_id = int(S2Helper.lat_lng_to_cell_id(float(lat), float(lng), 16)) query = ( "INSERT INTO scannedlocation (cellid, latitude, longitude, last_modified, done, band1, band2, " "band3, band4, band5, midpoint, width) " "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) " "ON DUPLICATE KEY UPDATE last_modified=VALUES(last_modified)" ) # TODO: think of a better "unique, real number" vals = (cell_id, lat, lng, now, -1, -1, -1, -1, -1, -1, -1, -1) self.execute(query, vals, commit=True) log.debug("{RmWrapper::set_scanned_location} Done setting location...") return True
def _get_count_and_coords_in_circle_within_timedelta(self, middle, relations, earliest_timestamp, latest_timestamp, max_radius): inside_circle = [] highest_timedelta = 0 if self.useS2: region = s2sphere.CellUnion(S2Helper.get_S2cells_from_circle(middle.lat, middle.lng, self.max_radius, self.S2level)) for event_relations in relations: # exclude previously clustered events... if len(event_relations) == 4 and event_relations[3]: inside_circle.append(event_relations) continue distance = get_distance_of_two_points_in_meters(middle.lat, middle.lng, event_relations[1].lat, event_relations[1].lng) event_in_range = 0 <= distance <= max_radius if self.useS2: event_in_range = region.contains(s2sphere.LatLng.from_degrees(event_relations[1].lat, event_relations[1].lng).to_point()) # timedelta of event being inspected to the earliest timestamp timedelta_end = latest_timestamp - event_relations[0] timedelta_start = event_relations[0] - earliest_timestamp if timedelta_end < 0 and event_in_range: # we found an event starting past the current latest timestamp, let's update the latest_timestamp latest_timestamp_temp = latest_timestamp + abs(timedelta_end) if latest_timestamp_temp - earliest_timestamp <= self.max_timedelta_seconds: latest_timestamp = latest_timestamp_temp highest_timedelta = highest_timedelta + abs(timedelta_end) inside_circle.append(event_relations) elif timedelta_start < 0 and event_in_range: # we found an event starting before earliest_timestamp, let's check that... earliest_timestamp_temp = earliest_timestamp - \ abs(timedelta_start) if latest_timestamp - earliest_timestamp_temp <= self.max_timedelta_seconds: earliest_timestamp = earliest_timestamp_temp highest_timedelta = highest_timedelta + \ abs(timedelta_start) inside_circle.append(event_relations) elif timedelta_end >= 0 and timedelta_start >= 0 and event_in_range: # we found an event within our current timedelta and proximity, just append it to the list inside_circle.append(event_relations) return len(inside_circle), inside_circle, highest_timedelta, latest_timestamp
def cells(self, origin: str, map_proto: dict): protocells = map_proto.get("cells", []) query = ( "INSERT INTO trs_s2cells (id, level, center_latitude, center_longitude, updated) " "VALUES (%s, %s, %s, %s, %s) " "ON DUPLICATE KEY UPDATE updated=VALUES(updated)") cells = [] for cell in protocells: cell_id = cell["id"] if cell_id < 0: cell_id = cell_id + 2**64 lat, lng, alt = S2Helper.get_position_from_cell(cell_id) cells.append( (cell_id, 15, lat, lng, cell["current_timestamp"] / 1000)) self._db_exec.executemany(query, cells, commit=True)
def get_cells(self): neLat, neLon, swLat, swLon, oNeLat, oNeLon, oSwLat, oSwLon = getBoundParameter( request) timestamp = request.args.get("timestamp", None) data = self._db.get_cells_in_rectangle(neLat=neLat, neLon=neLon, swLat=swLat, swLon=swLon, oNeLat=oNeLat, oNeLon=oNeLon, oSwLat=oSwLat, oSwLon=oSwLon, timestamp=timestamp) ret = [] for cell in data: ret.append({ "id": str(cell["id"]), "polygon": S2Helper.coords_of_cell(cell["id"]), "updated": cell["updated"] }) return jsonify(ret)
def submit_mon_iv(self, origin, timestamp, encounter_proto): log.debug("Updating IV sent by %s" % str(origin)) wild_pokemon = encounter_proto.get("wild_pokemon", None) if wild_pokemon is None: return query_insert = ( "INSERT sightings (pokemon_id, spawn_id, expire_timestamp, encounter_id, " "lat, lon, updated, gender, form, costume, weather_boosted_condition, weather_cell_id, " "atk_iv, def_iv, sta_iv, move_1, move_2, cp, level, weight) " "VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" "ON DUPLICATE KEY UPDATE updated=VALUES(updated), atk_iv=VALUES(atk_iv), def_iv=VALUES(def_iv), " "sta_iv=VALUES(sta_iv), move_1=VALUES(move_1), move_2=VALUES(move_2), cp=VALUES(cp), " "level=VALUES(level), weight=VALUES(weight), costume=VALUES(costume)" ) encounter_id = wild_pokemon['encounter_id'] if encounter_id < 0: encounter_id = encounter_id + 2**64 latitude = wild_pokemon.get("latitude") longitude = wild_pokemon.get("longitude") pokemon_data = wild_pokemon.get("pokemon_data") if pokemon_data.get("cp_multiplier") < 0.734: pokemon_level = (58.35178527 * pokemon_data.get("cp_multiplier") * pokemon_data.get("cp_multiplier") - 2.838007664 * pokemon_data.get("cp_multiplier") + 0.8539209906) else: pokemon_level = 171.0112688 * pokemon_data.get( "cp_multiplier") - 95.20425243 pokemon_level = round(pokemon_level) * 2 / 2 pokemon_display = pokemon_data.get("display") if pokemon_display is None: pokemon_display = {} despawn_time = datetime.now() + timedelta(seconds=300) despawn_time_unix = int(time.mktime(despawn_time.timetuple())) despawn_time = datetime.utcfromtimestamp( time.mktime( despawn_time.timetuple())).strftime('%Y-%m-%d %H:%M:%S') init = True getdetspawntime = self.get_detected_endtime( int(str(wild_pokemon["spawnpoint_id"]), 16)) if getdetspawntime: despawn_time_unix = self._gen_endtime(getdetspawntime) despawn_time = datetime.utcfromtimestamp( despawn_time_unix).strftime('%Y-%m-%d %H:%M:%S') init = False if init: log.info( "{0}: adding IV mon #{1} at {2}, {3}. Despawning at {4} (init)" .format(str(origin), pokemon_data["id"], latitude, longitude, despawn_time)) else: log.info( "{0}: adding IV mon #{1} at {2}, {3}. Despawning at {4} (non-init)" .format(str(origin), pokemon_data["id"], latitude, longitude, despawn_time)) s2_weather_cell_id = S2Helper.lat_lng_to_cell_id(latitude, longitude, level=10) vals = ( pokemon_data["id"], int(wild_pokemon.get("spawnpoint_id"), 16), despawn_time_unix, encounter_id, latitude, longitude, timestamp, pokemon_display.get("gender_value", None), pokemon_display.get("form_value", None), pokemon_display.get("costume_value", None), pokemon_display.get("weather_boosted_value", None), s2_weather_cell_id, pokemon_data.get("individual_attack"), pokemon_data.get("individual_defense"), pokemon_data.get("individual_stamina"), pokemon_data.get("move_1"), pokemon_data.get("move_2"), pokemon_data.get("cp"), pokemon_level, pokemon_data.get("weight"), ) self.execute(query_insert, vals, commit=True) self.webhook_helper.send_pokemon_webhook( encounter_id=encounter_id, pokemon_id=pokemon_data.get("id"), last_modified_time=timestamp, spawnpoint_id=int(wild_pokemon.get("spawnpoint_id"), 16), lat=latitude, lon=longitude, despawn_time_unix=despawn_time_unix, pokemon_level=pokemon_level, cp_multiplier=pokemon_data.get("cp_multiplier"), form=pokemon_display.get("form_value", None), cp=pokemon_data.get("cp"), individual_attack=pokemon_data.get("individual_attack"), individual_defense=pokemon_data.get("individual_defense"), individual_stamina=pokemon_data.get("individual_stamina"), move_1=pokemon_data.get("move_1"), move_2=pokemon_data.get("move_2"), height=pokemon_data.get("height"), weight=pokemon_data.get("weight"), gender=pokemon_display.get("gender_value", None), boosted_weather=pokemon_display.get("weather_boosted_value", None))
def get_routemanagers(self): from multiprocessing.pool import ThreadPool global mode_mapping # returns list of routemanagers with area IDs areas = {} area_arr = self.__raw_json["areas"] thread_pool = ThreadPool(processes=4) areas_procs = {} for area in area_arr: if area["geofence_included"] is None: raise RuntimeError("Cannot work without geofence_included") geofence_included = Path(area["geofence_included"]) if not geofence_included.is_file(): log.error("Geofence included file configured does not exist") sys.exit(1) geofence_excluded_raw_path = area.get("geofence_excluded", None) if geofence_excluded_raw_path is not None: geofence_excluded = Path(geofence_excluded_raw_path) if not geofence_excluded.is_file(): log.error("Geofence excluded specified but does not exist") sys.exit(1) area_dict = {"mode": area["mode"], "geofence_included": area["geofence_included"], "geofence_excluded": area.get("geofence_excluded", None), "routecalc": area["routecalc"]} # also build a routemanager for each area... # grab coords # first check if init is false or raids_ocr is set as mode, if so, grab the coords from DB # coords = np.loadtxt(area["coords"], delimiter=',') geofence_helper = GeofenceHelper( area["geofence_included"], area.get("geofence_excluded", None)) mode = area["mode"] # build routemanagers if mode == "raids_ocr" or mode == "raids_mitm": route_manager = RouteManagerRaids(self.db_wrapper, None, mode_mapping[area["mode"]]["range"], mode_mapping[area["mode"] ]["max_count"], area["geofence_included"], area.get( "geofence_excluded", None), area["routecalc"], mode=area["mode"], settings=area.get( "settings", None), init=area.get("init", False), name=area.get( "name", "unknown") ) elif mode == "mon_mitm": route_manager = RouteManagerMon(self.db_wrapper, None, mode_mapping[area["mode"]]["range"], mode_mapping[area["mode"] ]["max_count"], area["geofence_included"], area.get( "geofence_excluded", None), area["routecalc"], mode=area["mode"], coords_spawns_known=area.get( "coords_spawns_known", False), init=area.get("init", False), name=area.get( "name", "unknown"), settings=area.get( "settings", None) ) elif mode == "iv_mitm": route_manager = RouteManagerIV(self.db_wrapper, None, 0, 999999, area["geofence_included"], area.get( "geofence_excluded", None), area["routecalc"], name=area.get( "name", "unknown"), settings=area.get( "settings", None), mode=mode ) elif mode == "pokestops": route_manager = RouteManagerMon(self.db_wrapper, None, mode_mapping[area["mode"]]["range"], mode_mapping[area["mode"] ]["max_count"], area["geofence_included"], area.get( "geofence_excluded", None), area["routecalc"], mode=area["mode"], init=area.get("init", False), name=area.get( "name", "unknown"), settings=area.get( "settings", None) ) else: log.error("Invalid mode found in mapping parser.") sys.exit(1) if not mode == "iv_mitm": if mode == "raids_ocr" or area.get("init", False) is False: # grab data from DB depending on mode # TODO: move routemanagers to factory if mode == "raids_ocr" or mode == "raids_mitm": coords = self.db_wrapper.gyms_from_db(geofence_helper) elif mode == "mon_mitm": spawn_known = area.get("coords_spawns_known", False) if spawn_known: log.info("Reading known Spawnpoints from DB") coords = self.db_wrapper.get_detected_spawns( geofence_helper) else: log.info("Reading unknown Spawnpoints from DB") coords = self.db_wrapper.get_undetected_spawns( geofence_helper) elif mode == "pokestops": coords = self.db_wrapper.stops_from_db(geofence_helper) else: log.fatal("Mode not implemented yet: %s" % str(mode)) exit(1) else: # calculate all level N cells (mapping back from mapping above linked to mode) # coords = S2Helper.get_s2_cells_from_fence(geofence=geofence_helper, # cell_size=mode_mapping[mode]["s2_cell_level"]) coords = S2Helper._generate_locations(mode_mapping[area["mode"]]["range"], geofence_helper) route_manager.add_coords_list(coords) max_radius = mode_mapping[area["mode"]]["range"] max_count_in_radius = mode_mapping[area["mode"]]["max_count"] if not area.get("init", False): log.info("Calculating route for %s" % str(area.get("name", "unknown"))) proc = thread_pool.apply_async(route_manager.recalc_route, args=(max_radius, max_count_in_radius, 0, False)) areas_procs[area["name"]] = proc else: log.info("Init mode enabled and more than 400 coords in init. Going row-based for %s" % str(area.get("name", "unknown"))) # we are in init, let's write the init route to file to make it visible in madmin if area["routecalc"] is not None: routefile = area["routecalc"] if os.path.isfile(routefile + '.calc'): os.remove(routefile + '.calc') with open(routefile + '.calc', 'a') as f: for loc in coords: f.write(str(loc.lat) + ', ' + str(loc.lng) + '\n') # gotta feed the route to routemanager... TODO: without recalc... proc = thread_pool.apply_async(route_manager.recalc_route, args=(1, 99999999, 0, False)) areas_procs[area["name"]] = proc # log.error("Calculated route, appending another coord and recalculating") area_dict["routemanager"] = route_manager areas[area["name"]] = area_dict for area in areas_procs.keys(): to_be_checked = areas_procs[area] log.debug(to_be_checked) to_be_checked.get() thread_pool.close() thread_pool.join() return areas
def get_routemanagers(self, delay_after_hatch=None): from multiprocessing.pool import ThreadPool global mode_mapping # returns list of routemanagers with area IDs areas = {} area_arr = self.__raw_json["areas"] thread_pool = ThreadPool(processes=4) areas_procs = {} for area in area_arr: if area["geofence_included"] is None: raise RuntimeError("Cannot work without geofence_included") geofence_included = Path(area["geofence_included"]) if not geofence_included.is_file(): log.error("Geofence included file configured does not exist") sys.exit(1) geofence_excluded_raw_path = area.get("geofence_excluded", None) if geofence_excluded_raw_path is not None: geofence_excluded = Path(geofence_excluded_raw_path) if not geofence_excluded.is_file(): log.error("Geofence excluded specified but does not exist") sys.exit(1) area_dict = {"mode": area["mode"], "geofence_included": area["geofence_included"], "geofence_excluded": area.get("geofence_excluded", None), "routecalc": area["routecalc"]} # also build a routemanager for each area... # grab coords # first check if init is false or raids_ocr is set as mode, if so, grab the coords from DB # coords = np.loadtxt(area["coords"], delimiter=',') geofence_helper = GeofenceHelper(area["geofence_included"], area.get("geofence_excluded", None)) mode = area["mode"] if mode == "raids_ocr" or area.get("init", False) is False: # grab data from DB depending on mode if mode == "raids_ocr" or mode == "raids_mitm": coords = self.db_wrapper.gyms_from_db(geofence_helper) elif mode == "mon_mitm": spawn_known = area.get("coords_spawns_known", False) if spawn_known: log.info("Reading known Spawnpoints from DB") coords = self.db_wrapper.get_detected_spawns(geofence_helper) else: log.info("Reading unknown Spawnpoints from DB") coords = self.db_wrapper.get_undetected_spawns(geofence_helper) else: log.fatal("Mode not implemented yet: %s" % str(mode)) exit(1) else: # calculate all level N cells (mapping back from mapping above linked to mode) coords = S2Helper.get_s2_cells_from_fence(geofence=geofence_helper, cell_size=mode_mapping[mode]["s2_cell_level"]) # coords = S2Helper._generate_locations(mode_mapping[area["mode"]]["range"], # geofence_helper) # retrieve the range and max count per circle from central mapping... route_manager = RouteManager(self.db_wrapper, None, mode_mapping[area["mode"]]["range"], mode_mapping[area["mode"]]["max_count"], area["geofence_included"], area.get("geofence_excluded", None), area["routecalc"], coords_spawns_known=area.get("coords_spawns_known", False), delayAfterHatch=delay_after_hatch, init=area.get("init", False), mode=area["mode"], settings=area["settings"], name=area.get("name", "unknwon")) route_manager.add_coords_list(coords) max_radius = mode_mapping[area["mode"]]["range"] max_count_in_radius = mode_mapping[area["mode"]]["max_count"] proc = thread_pool.apply_async(route_manager.recalc_route, args=(max_radius, max_count_in_radius, 0, False)) areas_procs[area["name"]] = proc # log.error("Calculated route, appending another coord and recalculating") area_dict["routemanager"] = route_manager areas[area["name"]] = area_dict for area in areas_procs.keys(): to_be_checked = areas_procs[area] log.debug(to_be_checked) to_be_checked.get() thread_pool.close() thread_pool.join() return areas
def _main_work_thread(self): current_thread().name = self.id log.debug("Sub called") # first check if pogo is running etc etc self._workMutex.acquire() try: self._initRoutine() except WebsocketWorkerRemovedException: log.error("Timeout during init of worker %s" % str(self.id)) self._stop_worker_event.set() self._workMutex.release() return self._workMutex.release() # loop = asyncio.get_event_loop() # TODO:loop.create_task(self._speed_weather_check_thread()) speedWeatherCheckThread = Thread(name='speedWeatherCheckThread%s' % self.id, target=self._speed_weather_check_thread) speedWeatherCheckThread.daemon = False speedWeatherCheckThread.start() currentLocation = self._last_known_state.get("last_location", None) if currentLocation is None: currentLocation = Location(0.0, 0.0) lastLocation = None while not self._stop_worker_event.isSet(): while MadGlobals.sleep and self._route_manager_nighttime is None: time.sleep(1) __time = time.time() log.debug("Worker: acquiring lock for restart check") self._workMutex.acquire() log.debug("Worker: acquired lock") # Restart pogo every now and then... if self._devicesettings.get("restart_pogo", 80) > 0: # log.debug("main: Current time - lastPogoRestart: %s" % str(curTime - lastPogoRestart)) # if curTime - lastPogoRestart >= (args.restart_pogo * 60): self._locationCount += 1 if self._locationCount > self._devicesettings.get("restart_pogo", 80): log.error("scanned " + str(self._devicesettings.get("restart_pogo", 80)) + " locations, restarting pogo") self._restartPogo() self._locationCount = 0 self._workMutex.release() log.debug("Worker: lock released") # TODO: consider adding runWarningThreadEvent.set() lastLocation = currentLocation self._last_known_state["last_location"] = lastLocation if MadGlobals.sleep: currentLocation = self._route_manager_nighttime.getNextLocation() settings = self._route_manager_nighttime.settings else: currentLocation = self._route_manager_daytime.getNextLocation() settings = self._route_manager_daytime.settings # TODO: set position... needs to be adjust for multidevice posfile = open(self.id+'.position', "w") posfile.write(str(currentLocation.lat)+", "+str(currentLocation.lng)) posfile.close() log.debug("main: next stop: %s" % (str(currentLocation))) log.debug('main: LastLat: %s, LastLng: %s, CurLat: %s, CurLng: %s' % (lastLocation.lat, lastLocation.lng, currentLocation.lat, currentLocation.lng)) # get the distance from our current position (last) to the next gym (cur) distance = getDistanceOfTwoPointsInMeters(float(lastLocation.lat), float(lastLocation.lng), float(currentLocation.lat), float(currentLocation.lng)) log.info('main: Moving %s meters to the next position' % distance) delayUsed = 0 if MadGlobals.sleep: speed = self._route_manager_nighttime.settings.get("speed", 0) else: speed = self._route_manager_daytime.settings.get("speed", 0) if (speed == 0 or (settings["max_distance"] and 0 < settings["max_distance"] < distance) or (lastLocation.lat == 0.0 and lastLocation.lng == 0.0)): log.info("main: Teleporting...") self._communicator.setLocation(currentLocation.lat, currentLocation.lng, 0) delayUsed = self._devicesettings.get("post_teleport_delay",7) # Test for cooldown / teleported distance TODO: check this block... if self._devicesettings.get("cool_down_sleep",False): if distance > 2500: delayUsed = 30 elif distance > 5000: delayUsed = 45 elif distance > 10000: delayUsed = 60 log.info("Need more sleep after Teleport: %s seconds!" % str(delayUsed)) if 0 < self._devicesettings.get("walk_after_teleport_distance",0) < distance: toWalk = getDistanceOfTwoPointsInMeters(float(currentLocation.lat), float(currentLocation.lng), float(currentLocation.lat) + 0.0001, float(currentLocation.lng) + 0.0001) log.info("Walking a bit: %s" % str(toWalk)) time.sleep(0.3) self._communicator.walkFromTo(currentLocation.lat, currentLocation.lng, currentLocation.lat + 0.0001, currentLocation.lng + 0.0001, 11) log.debug("Walking back") time.sleep(0.3) self._communicator.walkFromTo(currentLocation.lat + 0.0001, currentLocation.lng + 0.0001, currentLocation.lat, currentLocation.lng, 11) log.debug("Done walking") else: log.info("main: Walking...") self._communicator.walkFromTo(lastLocation.lat, lastLocation.lng, currentLocation.lat, currentLocation.lng, speed) delayUsed = self._devicesettings.get("post_walk_delay",7) log.info("Sleeping %s" % str(delayUsed)) time.sleep(delayUsed) log.debug("main: Acquiring lock") while MadGlobals.sleep: # or not runWarningThreadEvent.isSet(): time.sleep(0.1) log.debug("Worker: acquiring lock") self._workMutex.acquire() log.debug("main: Lock acquired") if not self._takeScreenshot(): self._workMutex.release() log.debug("Worker: Lock released") continue log.debug("Worker: Got screenshot") curTime = time.time() if self._applicationArgs.last_scanned: log.info('main: Set new scannedlocation in Database') self._db_wrapper.set_scanned_location(str(currentLocation.lat), str(currentLocation.lng), str(curTime)) log.info("main: Checking raidcount and copying raidscreen if raids present") countOfRaids = self._pogoWindowManager.readRaidCircles(os.path.join( self._applicationArgs.temp_path, 'screenshot%s.png' % str(self.id)), self.id) if countOfRaids == -1: log.debug("Worker: Count present but no raid shown") log.warning("main: Count present but no raid shown, reopening raidTab") self._reopenRaidTab() # tabOutAndInPogo() log.debug("Done reopening raidtab") if not self._takeScreenshot(): self._workMutex.release() log.debug("Worker: Lock released") continue countOfRaids = self._pogoWindowManager.readRaidCircles(os.path.join( self._applicationArgs.temp_path, 'screenshot%s.png' % str(self.id)), self.id) # elif countOfRaids == 0: # emptycount += 1 # if emptycount > 30: # emptycount = 0 # log.error("Had 30 empty scans, restarting pogo") # restartPogo() # not an elif since we may have gotten a new screenshot.. # detectin weather if self._applicationArgs.weather: log.debug("Worker: Checking weather...") weather = checkWeather(os.path.join(self._applicationArgs.temp_path, 'screenshot%s.png' % str(self.id))) if weather[0]: log.debug('Submit Weather') cell_id = S2Helper.lat_lng_to_cell_id(currentLocation.lat, currentLocation.lng) self._db_wrapper.update_insert_weather(cell_id, weather[1], curTime) else: log.error('Weather could not detected') if countOfRaids > 0: log.debug("Worker: Count of raids >0") log.debug("main: New und old Screenshoot are different - starting OCR") log.debug("main: countOfRaids: %s" % str(countOfRaids)) curTime = time.time() copyFileName = self._applicationArgs.raidscreen_path + '/raidscreen_' + str(curTime) \ + "_" + str(currentLocation.lat) + "_" + str(currentLocation.lng) + "_" \ + str(countOfRaids) + '.png' log.debug('Copying file: ' + copyFileName) log.debug("Worker: Copying file to %s" % str(copyFileName)) copyfile(os.path.join(self._applicationArgs.temp_path, 'screenshot%s.png' % str(self.id)), copyFileName) os.remove(os.path.join(self._applicationArgs.temp_path, 'screenshot%s.png' % str(self.id))) log.debug("main: Releasing lock") self._workMutex.release() log.debug("Worker: Lock released")
def submit_spawnpoints_map_proto(self, origin, map_proto): log.debug("{DbWrapperBase::submit_spawnpoints_map_proto} called with data received by %s" % str(origin)) cells = map_proto.get("cells", None) if cells is None: return False spawnpoint_args, spawnpoint_args_unseen = [], [] spawnids = [] query_spawnpoints = ( "INSERT INTO trs_spawn (spawnpoint, latitude, longitude, earliest_unseen, " "last_scanned, spawndef, calc_endminsec) " "VALUES (%s, %s, %s, %s, %s, %s, %s) " "ON DUPLICATE KEY UPDATE last_scanned=VALUES(last_scanned), " "earliest_unseen=LEAST(earliest_unseen, VALUES(earliest_unseen)), " "spawndef=VALUES(spawndef), calc_endminsec=VALUES(calc_endminsec)" "" ) query_spawnpoints_unseen = ( "INSERT INTO trs_spawn (spawnpoint, latitude, longitude, earliest_unseen, last_non_scanned, spawndef) " "VALUES (%s, %s, %s, %s, %s, %s) " "ON DUPLICATE KEY UPDATE spawndef=VALUES(spawndef), last_non_scanned=VALUES(last_non_scanned)" "" ) now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") dt = datetime.now() for cell in cells: for wild_mon in cell["wild_pokemon"]: spawnids.append(int(str(wild_mon['spawnpoint_id']), 16)) spawndef = self.getspawndef(spawnids) for cell in cells: for wild_mon in cell["wild_pokemon"]: spawnid = int(str(wild_mon['spawnpoint_id']), 16) lat, lng, alt = S2Helper.get_position_from_cell(int(str(wild_mon['spawnpoint_id']) + '00000', 16)) despawntime = wild_mon['time_till_hidden'] minpos = self._get_min_pos_in_array() # TODO: retrieve the spawndefs by a single executemany and pass that... spawndef_ = spawndef.get(spawnid, False) if spawndef_: newspawndef = self._set_spawn_see_minutesgroup(spawndef_, minpos) else: newspawndef = self._set_spawn_see_minutesgroup(DbWrapperBase.def_spawn, minpos) last_scanned = None last_non_scanned = None if 0 <= int(despawntime) <= 90000: fulldate = dt + timedelta(milliseconds=despawntime) earliest_unseen = int(despawntime) last_scanned = now calcendtime = fulldate.strftime("%M:%S") spawnpoint_args.append( ( spawnid, lat, lng, earliest_unseen, last_scanned, newspawndef, calcendtime ) ) else: earliest_unseen = 99999999 last_non_scanned = now calcendtime = None spawnpoint_args_unseen.append( ( spawnid, lat, lng, earliest_unseen, last_non_scanned, newspawndef ) ) self.executemany(query_spawnpoints, spawnpoint_args, commit=True) self.executemany(query_spawnpoints_unseen, spawnpoint_args_unseen, commit=True)
def _post_move_location_routine(self, timestamp): # check if the speed_weather_check_thread signalled an abort by setting the stop_worker_event if self._stop_worker_event.is_set(): raise InternalStopWorkerException logger.debug("Main: acquiring lock") self._work_mutex.acquire() logger.debug("main: Lock acquired") # TODO: takeScreenshot can throw, should we care about releasing locks or just cleanup everything else? if not self._takeScreenshot(): self._work_mutex.release() logger.debug( "Worker: couldn't take screenshot before radscreen check, lock released" ) return logger.debug("Worker: Got screenshot") # curTime = time.time() logger.info( "main: Checking raidcount and copying raidscreen if raids present") count_of_raids = self._pogoWindowManager.readRaidCircles( self.get_screenshot_path(), self._id, self._communicator) if count_of_raids == -1: logger.debug("Worker: Count present but no raid shown") logger.warning( "main: Count present but no raid shown, reopening raidTab") self._reopenRaidTab() logger.debug("Done reopening raidtab") if not self._takeScreenshot(): self._work_mutex.release() logger.debug( "Worker: couldn't take screenshot after opening raidtab, lock released" ) return count_of_raids = self._pogoWindowManager.readRaidCircles( self.get_screenshot_path(), self._id, self._communicator) # elif countOfRaids == 0: # emptycount += 1 # if emptycount > 30: # emptycount = 0 # logger.error("Had 30 empty scans, restarting pogo") # restartPogo() # not an elif since we may have gotten a new screenshot.. # detectin weather if self._applicationArgs.weather: logger.debug("Worker: Checking weather...") weather = checkWeather(self.get_screenshot_path()) if weather[0]: logger.debug('Submit Weather') cell_id = S2Helper.lat_lng_to_cell_id( self.current_location.lat, self.current_location.lng) self._db_wrapper.update_insert_weather(cell_id, weather[1], timestamp) else: logger.error('Weather could not detected') if count_of_raids > 0: logger.debug("Worker: Count of raids >0") logger.debug( "main: New und old Screenshoot are different - starting OCR") logger.debug("main: countOfRaids: {}", str(count_of_raids)) timestamp = time.time() copyFileName = self._applicationArgs.raidscreen_path + '/raidscreen_' + str(timestamp) \ + "_" + str(self.current_location.lat) + "_" + str(self.current_location.lng) + "_" \ + str(count_of_raids) + '.png' logger.debug('Copying file: ' + copyFileName) logger.debug("Worker: Copying file to {}", str(copyFileName)) copyfile(self.get_screenshot_path(), copyFileName) os.remove(self.get_screenshot_path()) logger.debug("main: Releasing lock") self._work_mutex.release() logger.debug("Worker: Lock released")
def submit_gyms_map_proto(self, origin, map_proto): log.debug("Inserting/Updating gyms sent by %s" % str(origin)) cells = map_proto.get("cells", None) if cells is None: return False now = int(time.time()) vals_forts = [] vals_fort_sightings_insert = [] vals_fort_sightings_update = [] query_forts = ( "INSERT IGNORE INTO forts (external_id, lat, lon, name, url, " "sponsor, weather_cell_id, parkid, park) " "VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)") query_fort_sightings_insert = ( "INSERT INTO fort_sightings (fort_id, last_modified, team, guard_pokemon_id, " "slots_available, is_in_battle, updated) " "VALUES ((SELECT id FROM forts WHERE external_id = %s), %s, %s, %s, %s, %s, %s)" ) query_fort_sightings_update = ( "UPDATE fort_sightings SET team = %s, guard_pokemon_id = %s, " "slots_available = %s, updated = %s, last_modified = %s, " "is_in_battle=%s " "WHERE fort_id=(SELECT id FROM forts WHERE external_id=%s)") for cell in cells: for gym in cell['forts']: if gym['type'] == 0: gym_id = gym['id'] guardmon = gym['gym_details']['guard_pokemon'] lat = gym['latitude'] lon = gym['longitude'] image_uri = gym['image_url'] s2_cell_id = S2Helper.lat_lng_to_cell_id(lat, lon) team = gym['gym_details']['owned_by_team'] slots = gym['gym_details']['slots_available'] is_in_battle = gym['gym_details'].get( 'is_in_battle', False) last_modified = gym['last_modified_timestamp_ms'] / 1000 if is_in_battle: is_in_battle = 1 else: is_in_battle = 0 raidendSec = 0 if gym['gym_details']['has_raid']: raidendSec = int( gym['gym_details']['raid_info']['raid_end'] / 1000) self.webhook_helper.send_gym_webhook( gym_id, raidendSec, 'unknown', team, slots, guardmon, lat, lon, last_modified) vals_forts.append((gym_id, lat, lon, None, image_uri, None, s2_cell_id, None, None)) query_get_count = "SELECT count(*) from fort_sightings where fort_id=(SELECT id from forts where " \ "external_id = %s)" vals_get_count = (gym_id, ) res = self.execute(query_get_count, vals_get_count) fort_sightings_exists = res[0] fort_sightings_exists = ",".join( map(str, fort_sightings_exists)) if int(fort_sightings_exists) == 0: vals_fort_sightings_insert.append( (gym_id, last_modified, team, guardmon, slots, is_in_battle, now)) else: vals_fort_sightings_update.append( (team, guardmon, slots, now, last_modified, is_in_battle, gym_id)) self.executemany(query_forts, vals_forts, commit=True) self.executemany(query_fort_sightings_insert, vals_fort_sightings_insert, commit=True) self.executemany(query_fort_sightings_update, vals_fort_sightings_update, commit=True) return True
def submit_mons_map_proto(self, origin, map_proto, mon_ids_iv): cells = map_proto.get("cells", None) if cells is None: return False query_mons_insert = ( "INSERT IGNORE INTO sightings (pokemon_id, spawn_id, expire_timestamp, encounter_id, " "lat, lon, updated, gender, form, weather_boosted_condition, costume, weather_cell_id) " "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)") mon_vals_insert = [] for cell in cells: for wild_mon in cell['wild_pokemon']: spawnid = int(str(wild_mon['spawnpoint_id']), 16) lat = wild_mon['latitude'] lon = wild_mon['longitude'] now = int(time.time()) encounter_id = wild_mon['encounter_id'] if encounter_id < 0: encounter_id = encounter_id + 2**64 s2_weather_cell_id = S2Helper.lat_lng_to_cell_id(lat, lon, level=10) despawn_time = datetime.now() + timedelta(seconds=300) despawn_time_unix = int(time.mktime(despawn_time.timetuple())) init = True getdetspawntime = self.get_detected_endtime(str(spawnid)) if getdetspawntime: despawn_time = self._gen_endtime(getdetspawntime) despawn_time_unix = despawn_time init = False if init: log.info( "{0}: adding mon with id #{1} at {2}, {3}. Despawning at {4} (init)" .format(str(origin), wild_mon['pokemon_data']['id'], lat, lon, despawn_time)) else: log.info( "{0}: adding mon with id #{1} at {2}, {3}. Despawning at {4} (non-init)" .format(str(origin), wild_mon['pokemon_data']['id'], lat, lon, despawn_time)) mon_id = wild_mon['pokemon_data']['id'] if mon_ids_iv is not None and mon_id not in mon_ids_iv or mon_ids_iv is None: self.webhook_helper.send_pokemon_webhook( encounter_id, mon_id, time.time(), spawnid, lat, lon, despawn_time_unix, form=wild_mon['pokemon_data']['display']['form_value'], gender=wild_mon['pokemon_data']['display'] ['gender_value'], boosted_weather=wild_mon['pokemon_data']['display'] ['weather_boosted_value']) mon_vals_insert.append( (mon_id, spawnid, despawn_time_unix, encounter_id, lat, lon, now, wild_mon['pokemon_data']['display']['gender_value'], wild_mon['pokemon_data']['display']['form_value'], wild_mon['pokemon_data']['display'] ['weather_boosted_value'], wild_mon['pokemon_data']['display']['costume_value'], s2_weather_cell_id)) self.executemany(query_mons_insert, mon_vals_insert, commit=True) return True
def submit_gyms_map_proto(self, origin, map_proto): log.debug("Inserting/Updating gyms sent by %s" % str(origin)) cells = map_proto.get("cells", None) if cells is None: return False now = int(time.time()) vals_forts = [] vals_fort_sightings = [] query_forts = ( "INSERT IGNORE INTO forts (external_id, lat, lon, name, url, " "sponsor, weather_cell_id, parkid, park) " "VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)") query_fort_sightings = ( "INSERT INTO fort_sightings (fort_id, last_modified, team, guard_pokemon_id, " "slots_available, is_in_battle, updated) " "VALUES ((SELECT id FROM forts WHERE external_id = %s), %s, %s, %s, %s, %s, %s)" "ON DUPLICATE KEY UPDATE last_modified=VALUES(last_modified), team=VALUES(team)," "guard_pokemon_id=VALUES(guard_pokemon_id),slots_available=VALUES(slots_available)," "is_in_battle=VALUES(is_in_battle), updated=VALUES(updated)") for cell in cells: for gym in cell['forts']: if gym['type'] == 0: gym_id = gym['id'] guardmon = gym['gym_details']['guard_pokemon'] lat = gym['latitude'] lon = gym['longitude'] image_uri = gym['image_url'] s2_cell_id = S2Helper.lat_lng_to_cell_id(lat, lon) team = gym['gym_details']['owned_by_team'] slots = gym['gym_details']['slots_available'] is_in_battle = gym['gym_details'].get( 'is_in_battle', False) last_modified = gym['last_modified_timestamp_ms'] / 1000 if is_in_battle: is_in_battle = 1 else: is_in_battle = 0 raidendSec = 0 if gym['gym_details']['has_raid']: raidendSec = int( gym['gym_details']['raid_info']['raid_end'] / 1000) self.webhook_helper.send_gym_webhook( gym_id, raidendSec, 'unknown', team, slots, guardmon, lat, lon, last_modified) vals_forts.append((gym_id, lat, lon, None, image_uri, None, s2_cell_id, None, None)) vals_fort_sightings.append( (gym_id, last_modified, team, guardmon, slots, is_in_battle, now)) self.executemany(query_forts, vals_forts, commit=True) self.executemany(query_fort_sightings, vals_fort_sightings, commit=True) return True
def submit_mons_map_proto(self, map_proto): cells = map_proto.get("cells", None) if cells is None: return False query_mons = ( "INSERT IGNORE INTO sightings (pokemon_id, spawn_id, expire_timestamp, encounter_id, " "lat, lon, atk_iv, def_iv, sta_iv, move_1, move_2, gender, form, cp, level, updated, " "weather_boosted_condition, weather_cell_id, weight) " "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" ) mon_vals = [] for cell in cells: for wild_mon in cell['wild_pokemon']: spawnid = int(str(wild_mon['spawnpoint_id']), 16) lat = wild_mon['latitude'] lon = wild_mon['longitude'] s2_weather_cell_id = S2Helper.lat_lng_to_cell_id(lat, lon, level=10) despawn_time = datetime.now() + timedelta(seconds=300) despawn_time_unix = int(time.mktime(despawn_time.timetuple())) now = int(time.time()) init = True getdetspawntime = self.get_detected_endtime(str(spawnid)) if getdetspawntime: despawn_time = self._gen_endtime(getdetspawntime) despawn_time_unix = despawn_time init = False if init: log.info("Adding mon with id #{0} at {1}, {2}. Despawning at {3} (init)" .format(wild_mon['pokemon_data']['id'], lat, lon, despawn_time)) else: log.info("Adding mon with id #{0} at {1}, {2}. Despawning at {3} (non-init)" .format(wild_mon['pokemon_data']['id'], lat, lon, despawn_time)) mon_id = wild_mon['pokemon_data']['id'] self.webhook_helper.submit_pokemon_webhook( wild_mon['encounter_id'], mon_id, time.time(), spawnid, lat, lon, despawn_time_unix ) mon_vals.append( ( mon_id, spawnid, despawn_time_unix, abs(wild_mon['encounter_id']), lat, lon, None, None, None, None, None, # IVs and moves wild_mon['pokemon_data']['display']['gender_value'], wild_mon['pokemon_data']['display']['form_value'], None, None, # CP and level now, wild_mon['pokemon_data']['display']['weather_boosted_value'], s2_weather_cell_id, None # weight ) ) self.executemany(query_mons, mon_vals, commit=True) return True