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"], } 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 get_routepool_coords(coord_list, mode): route_serialized = [] s2cells = {} prepared_coords = coord_list if isinstance(coord_list, RoutePoolEntry): prepared_coords = coord_list.subroute for location in prepared_coords: route_serialized.append( [getCoordFloat(location.lat), getCoordFloat(location.lng)]) if mode == "raids_mitm": cells = S2Helper.get_S2cells_from_circle(location.lat, location.lng, 490) for cell in cells: s2cells[str(cell.id())] = S2Helper.coords_of_cell(cell.id()) return (route_serialized, s2cells)
def _directly_surrounding_gmo_cells_containing_stops_around_current_position(self, gmo_cells) -> List: """ Returns a list of cells containing forts Args: gmo_cells: Returns: List of cells that actually contain forts around the current position """ cells_with_forts = [] if not gmo_cells: self.logger.debug("No GMO cells passed for surrounding cell check") return cells_with_forts # 35m radius around current location (thus cells that may be touched by that radius hopefully get included) s2cells_valid_around_location: List[CellId] = \ S2Helper.get_s2cells_from_circle(self.current_location.lat, self.current_location.lng, RADIUS_FOR_CELLS_CONSIDERED_FOR_STOP_SCAN, S2_GMO_CELL_LEVEL) s2cell_ids_valid: List[str] = [s2cell.id() for s2cell in s2cells_valid_around_location] for cell in gmo_cells: # each cell contains an array of forts, check each cell for a fort with our current location (maybe +- # very very little jitter) and check its properties if cell["id"] not in s2cell_ids_valid: continue forts: list = cell.get("forts", None) if forts: cells_with_forts.append(cell) if not cells_with_forts: self.logger.debug2("GMO cells around current position ({}) do not contain stops ", self.current_location) return cells_with_forts
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, # noqa: E800 TODO: alerts 0, 0, time_of_day, now)
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, include_event_id=None) -> 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: try: stops = self.__db_wrapper.stops_from_db(geofence_helper) if stops: coords.extend(stops) except Exception: pass elif mode == "mon_mitm": if coords_spawns_known: logger.debug("Reading known Spawnpoints from DB") coords = self.__db_wrapper.get_detected_spawns(geofence_helper, include_event_id) else: logger.debug("Reading unknown Spawnpoints from DB") coords = self.__db_wrapper.get_undetected_spawns(geofence_helper, include_event_id) elif mode == "pokestops": coords = self.__db_wrapper.stops_from_db(geofence_helper) else: logger.error("Mode not implemented yet: {}", 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 _check_data_distance(self, data): max_radius = self._mapping_manager.routemanager_get_max_radius( self._routemanager_name) if not max_radius: return True max_radius: int = self._applicationArgs.maximum_valid_distance \ if max_radius < self._applicationArgs.maximum_valid_distance else max_radius mode = self._mapping_manager.routemanager_get_mode( self._routemanager_name) if mode in ["mon_mitm", "iv_mitm"]: data_to_check = "wild_pokemon" else: data_to_check = "forts" lat_sum, lng_sum, counter = 0, 0, 0 if data_to_check == "forts": for cell in data: if cell[data_to_check]: cell_id = cell["id"] if cell_id < 0: cell_id = cell_id + 2**64 lat, lng, alt = S2Helper.get_position_from_cell(cell_id) counter += 1 lat_sum += lat lng_sum += lng else: for cell in data: for element in cell[data_to_check]: counter += 1 lat_sum += element["latitude"] lng_sum += element["longitude"] if counter == 0: return None avg_lat = lat_sum / counter avg_lng = lng_sum / counter distance = get_distance_of_two_points_in_meters( float(avg_lat), float(avg_lng), float(self.current_location.lat), float(self.current_location.lng)) if distance > max_radius: logger.debug2( "Data is too far away!! avg location {}, {} from " "data with self.current_location location {}, {} - that's a " "{}m distance with max_radius {} for mode {}", avg_lat, avg_lng, self.current_location.lat, self.current_location.lng, distance, max_radius, mode) return False else: logger.debug( "Data distance is ok! found avg location {}, {} " "from data with self.current_location location {}, {} - that's " "a {}m distance with max_radius {} for mode {}", avg_lat, avg_lng, self.current_location.lat, self.current_location.lng, distance, max_radius, mode) 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 set_scanned_location(self, lat, lng, capture_time): """ Update scannedlocation (in RM) of a given lat/lng """ logger.debug("DbWrapper::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) return True
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, _ = 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 get_cells(self): ne_lat, ne_lon, sw_lat, sw_lon, o_ne_lat, o_ne_lon, o_sw_lat, o_sw_lon = get_bound_params( request) timestamp = request.args.get("timestamp", None) data = self._db.get_cells_in_rectangle(ne_lat=ne_lat, ne_lon=ne_lon, sw_lat=sw_lat, sw_lon=sw_lon, o_ne_lat=o_ne_lat, o_ne_lon=o_ne_lon, o_sw_lat=o_sw_lat, o_sw_lon=o_sw_lon, timestamp=timestamp) ret = [] for cell in data: ret.append({ "id": str(cell["cell_id"]), "polygon": S2Helper.coords_of_cell(cell["cell_id"]), "updated": cell["updated"] }) return jsonify(ret)
def __prepare_mon_data(self, mon_data): ret = [] for mon in mon_data: if self.__is_in_excluded_area([mon["latitude"], mon["longitude"]]): continue mon_payload = { "encounter_id": str(mon["encounter_id"]), "pokemon_id": mon["pokemon_id"], "display_pokemon_id": mon['display_pokemon'], "spawnpoint_id": mon["spawnpoint_id"], "latitude": mon["latitude"], "longitude": mon["longitude"], "disappear_time": mon["disappear_time"], "verified": mon["spawn_verified"], "seen_type": str(mon["seen_type"]) } # get rarity pokemon_rarity = self.__rarity.rarity_by_id( pokemonid=mon["pokemon_id"]) if mon.get("cp_multiplier", None) is not None: mon_payload["cp_multiplier"] = mon["cp_multiplier"] mon_payload["pokemon_level"] = calculate_mon_level( mon["cp_multiplier"]) if mon["form"] is not None and mon["form"] > 0: mon_payload["form"] = mon["form"] if mon["display_form"] is not None and mon["display_form"] > 0: mon_payload["display_form"] = mon["display_form"] if mon["costume"] is not None: mon_payload["costume"] = mon["costume"] if mon["display_costume"] is not None and mon[ "display_costume"] > 0: mon_payload["display_costume"] = mon["display_costume"] if mon["cp"] is not None: mon_payload["cp"] = mon["cp"] if mon["individual_attack"] is not None: mon_payload["individual_attack"] = mon["individual_attack"] if mon["individual_defense"] is not None: mon_payload["individual_defense"] = mon["individual_defense"] if mon["individual_stamina"] is not None: mon_payload["individual_stamina"] = mon["individual_stamina"] if mon["move_1"] is not None: mon_payload["move_1"] = mon["move_1"] if mon["move_2"] is not None: mon_payload["move_2"] = mon["move_2"] if mon.get("height", None) is not None: mon_payload["height"] = mon["height"] if mon["weight"] is not None: mon_payload["weight"] = mon["weight"] if mon["gender"] is not None: mon_payload["gender"] = mon["gender"] if mon["display_gender"] is not None: mon_payload["display_gender"] = mon["display_gender"] if pokemon_rarity is not None: mon_payload["rarity"] = pokemon_rarity if mon["base_catch"] is not None: mon_payload["base_catch"] = mon["base_catch"] mon_payload["great_catch"] = mon["great_catch"] mon_payload["ultra_catch"] = mon["ultra_catch"] if mon["weather_boosted_condition"] is not None \ and mon["weather_boosted_condition"] > 0: if self.__args.quest_webhook_flavor == "default": mon_payload["boosted_weather"] = mon[ "weather_boosted_condition"] if self.__args.quest_webhook_flavor == "poracle": mon_payload["weather"] = mon["weather_boosted_condition"] if mon["seen_type"] in ("nearby_stop", "lure_wild", "lure_encounter"): mon_payload["pokestop_id"] = mon["fort_id"] mon_payload["pokestop_name"] = mon.get("stop_name") mon_payload["pokestop_url"] = mon.get("stop_url") if mon["seen_type"] == "nearby_stop": mon_payload["verified"] = False else: mon_payload["verified"] = True if mon["seen_type"] == "nearby_cell": mon_payload["cell_coords"] = S2Helper.coords_of_cell( mon["cell_id"]) mon_payload["cell_id"] = mon["cell_id"] mon_payload["verified"] = False entire_payload = {"type": "pokemon", "message": mon_payload} ret.append(entire_payload) return ret
def spawnpoints(self, origin: str, map_proto: dict, proto_dt: datetime): origin_logger = get_origin_logger(logger, origin=origin) origin_logger.debug3( "DbPogoProtoSubmit::spawnpoints called with data received") cells = map_proto.get("cells", None) if cells is None: return False spawnpoint_args, spawnpoint_args_unseen = [], [] spawn_ids = [] query_spawnpoints = ( "INSERT INTO trs_spawn (spawnpoint, latitude, longitude, earliest_unseen, " "last_scanned, spawndef, calc_endminsec, eventid) " "VALUES (%s, %s, %s, %s, %s, %s, %s, " "(select id from trs_event where now() between event_start and " "event_end order by event_start desc limit 1)) " "ON DUPLICATE KEY UPDATE " "last_scanned=VALUES(last_scanned), " "earliest_unseen=LEAST(earliest_unseen, VALUES(earliest_unseen)), " "spawndef=if(((select id from trs_event where now() between event_start and event_end order " "by event_start desc limit 1)=1 and eventid=1) or (select id from trs_event where now() between " "event_start and event_end order by event_start desc limit 1)<>1 and eventid<>1, VALUES(spawndef), " "spawndef), " "calc_endminsec=VALUES(calc_endminsec)") query_spawnpoints_unseen = ( "INSERT INTO trs_spawn (spawnpoint, latitude, longitude, earliest_unseen, last_non_scanned, spawndef, " "eventid) VALUES (%s, %s, %s, %s, %s, %s, " "(select id from trs_event where now() between event_start and " "event_end order by event_start desc limit 1)) " "ON DUPLICATE KEY UPDATE " "spawndef=if(((select id from trs_event where now() between event_start and event_end order " "by event_start desc limit 1)=1 and eventid=1) or (select id from trs_event where now() between " "event_start and event_end order by event_start desc limit 1)<>1 and eventid<>1, VALUES(spawndef), " "spawndef), " "last_non_scanned=VALUES(last_non_scanned)") now = proto_dt.strftime("%Y-%m-%d %H:%M:%S") dt = proto_dt for cell in cells: for wild_mon in cell["wild_pokemon"]: spawn_ids.append(int(str(wild_mon['spawnpoint_id']), 16)) spawndef = self._get_spawndef(spawn_ids) for cell in cells: for wild_mon in cell["wild_pokemon"]: spawnid = int(str(wild_mon["spawnpoint_id"]), 16) lat, lng, _ = S2Helper.get_position_from_cell( int(str(wild_mon["spawnpoint_id"]) + "00000", 16)) despawntime = wild_mon["time_till_hidden"] minpos = self._get_current_spawndef_pos() # 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( self.default_spawndef, 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 spawnpoint_args_unseen.append( (spawnid, lat, lng, earliest_unseen, last_non_scanned, newspawndef)) self._db_exec.executemany(query_spawnpoints, spawnpoint_args, commit=True) self._db_exec.executemany(query_spawnpoints_unseen, spawnpoint_args_unseen, commit=True)