Esempio n. 1
0
    def stop_details(self, stop_proto: dict):
        """
        Update/Insert pokestop details from a GMO
        :param stop_proto:
        :return:
        """
        cache = get_cache(self._args)
        logger.debug3("DbPogoProtoSubmit::pokestops_details called")

        query_stops = (
            "INSERT INTO pokestop (pokestop_id, enabled, latitude, longitude, last_modified, "
            "last_updated, name, image) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE last_updated=VALUES(last_updated), lure_expiration=VALUES(lure_expiration), "
            "latitude=VALUES(latitude), longitude=VALUES(longitude), name=VALUES(name), image=VALUES(image)"
        )

        stop_args = self._extract_args_single_stop_details(stop_proto)
        if stop_args is not None:
            alt_modified_time = int(
                math.ceil(datetime.utcnow().timestamp() / 1000)) * 1000
            cache_key = "stopdetail{}{}".format(
                stop_proto["fort_id"],
                stop_proto.get("last_modified_timestamp_ms",
                               alt_modified_time))
            if cache.exists(cache_key):
                return
            cache.set(cache_key, 1, ex=900)
            self._db_exec.execute(query_stops, stop_args, commit=True)
        return True
Esempio n. 2
0
    def stops(self, origin: str, map_proto: dict):
        """
        Update/Insert pokestops from a map_proto dict
        """
        cache = get_cache(self._args)
        origin_logger = get_origin_logger(logger, origin=origin)
        origin_logger.debug3("DbPogoProtoSubmit::stops called with data received")
        cells = map_proto.get("cells", None)
        if cells is None:
            return False

        query_stops = (
            "INSERT INTO pokestop (pokestop_id, enabled, latitude, longitude, last_modified, lure_expiration, "
            "last_updated, active_fort_modifier, incident_start, incident_expiration, incident_grunt_type) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE last_updated=VALUES(last_updated), lure_expiration=VALUES(lure_expiration), "
            "last_modified=VALUES(last_modified), latitude=VALUES(latitude), longitude=VALUES(longitude), "
            "active_fort_modifier=VALUES(active_fort_modifier), incident_start=VALUES(incident_start), "
            "incident_expiration=VALUES(incident_expiration), incident_grunt_type=VALUES(incident_grunt_type)"
        )

        stops_args = []
        for cell in cells:
            for fort in cell["forts"]:
                if fort["type"] == 1:
                    stop = self._extract_args_single_stop(fort)
                    alt_modified_time = int(math.ceil(datetime.utcnow().timestamp() / 1000)) * 1000
                    cache_key = "stop{}{}".format(fort["id"], fort.get("last_modified_timestamp_ms", alt_modified_time))
                    if cache.exists(cache_key):
                        continue
                    stops_args.append(stop)

        self._db_exec.executemany(query_stops, stops_args, commit=True)
        return True
Esempio n. 3
0
    def weather(self, origin, map_proto, received_timestamp):
        """
        Update/Insert weather from a map_proto dict
        """
        cache = get_cache(self._args)
        origin_logger = get_origin_logger(logger, origin=origin)
        origin_logger.debug3(
            "DbPogoProtoSubmit::weather called with data received")
        cells = map_proto.get("cells", None)
        if cells is None:
            return False

        query_weather = (
            "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) "
            "ON DUPLICATE KEY UPDATE fog_level=VALUES(fog_level), cloud_level=VALUES(cloud_level), "
            "snow_level=VALUES(snow_level), wind_direction=VALUES(wind_direction), "
            "world_time=VALUES(world_time), gameplay_weather=VALUES(gameplay_weather), "
            "last_updated=VALUES(last_updated)")

        list_of_weather_args = []
        for client_weather in map_proto["client_weather"]:
            time_of_day = map_proto.get("time_of_day_value", 0)
            weather = self._extract_args_single_weather(
                client_weather, time_of_day, received_timestamp)

            cache_key = "weather{}{}{}{}{}{}{}".format(weather[0], weather[4],
                                                       weather[5], weather[6],
                                                       weather[7], weather[8],
                                                       weather[9])
            if cache.exists(cache_key):
                continue

            list_of_weather_args.append(weather)
            cache.set(cache_key, 1, ex=900)
        self._db_exec.executemany(query_weather,
                                  list_of_weather_args,
                                  commit=True)
        return True
Esempio n. 4
0
    def raids(self, origin: str, map_proto: dict, mitm_mapper):
        """
        Update/Insert raids from a map_proto dict
        """
        cache = get_cache(self._args)
        origin_logger = get_origin_logger(logger, origin=origin)
        origin_logger.debug3(
            "DbPogoProtoSubmit::raids called with data received")
        cells = map_proto.get("cells", None)
        if cells is None:
            return False
        raid_args = []
        now = datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%d %H:%M:%S")

        query_raid = (
            "INSERT INTO raid (gym_id, level, spawn, start, end, pokemon_id, cp, move_1, move_2, last_scanned, form, "
            "is_exclusive, gender, costume, evolution) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE level=VALUES(level), spawn=VALUES(spawn), start=VALUES(start), "
            "end=VALUES(end), pokemon_id=VALUES(pokemon_id), cp=VALUES(cp), move_1=VALUES(move_1), "
            "move_2=VALUES(move_2), last_scanned=VALUES(last_scanned), is_exclusive=VALUES(is_exclusive), "
            "form=VALUES(form), gender=VALUES(gender), costume=VALUES(costume), evolution=VALUES(evolution)"
        )

        for cell in cells:
            for gym in cell["forts"]:
                if gym["type"] == 0 and gym["gym_details"]["has_raid"]:
                    gym_has_raid = gym["gym_details"]["raid_info"][
                        "has_pokemon"]
                    if gym_has_raid:
                        raid_info = gym["gym_details"]["raid_info"]

                        pokemon_id = raid_info["raid_pokemon"]["id"]
                        cp = raid_info["raid_pokemon"]["cp"]
                        move_1 = raid_info["raid_pokemon"]["move_1"]
                        move_2 = raid_info["raid_pokemon"]["move_2"]
                        form = raid_info["raid_pokemon"]["display"][
                            "form_value"]
                        gender = raid_info["raid_pokemon"]["display"][
                            "gender_value"]
                        costume = raid_info["raid_pokemon"]["display"][
                            "costume_value"]
                        evolution = raid_info["raid_pokemon"]["display"].get(
                            "current_temp_evolution", 0)
                    else:
                        pokemon_id = None
                        cp = 0
                        move_1 = 1
                        move_2 = 2
                        form = None
                        gender = None
                        costume = None
                        evolution = 0

                    raid_end_sec = int(
                        gym["gym_details"]["raid_info"]["raid_end"] / 1000)
                    raid_spawn_sec = int(
                        gym["gym_details"]["raid_info"]["raid_spawn"] / 1000)
                    raid_battle_sec = int(
                        gym["gym_details"]["raid_info"]["raid_battle"] / 1000)

                    raidend_date = datetime.utcfromtimestamp(
                        float(raid_end_sec)).strftime("%Y-%m-%d %H:%M:%S")
                    raidspawn_date = datetime.utcfromtimestamp(
                        float(raid_spawn_sec)).strftime("%Y-%m-%d %H:%M:%S")
                    raidstart_date = datetime.utcfromtimestamp(
                        float(raid_battle_sec)).strftime("%Y-%m-%d %H:%M:%S")

                    is_exclusive = gym["gym_details"]["raid_info"][
                        "is_exclusive"]
                    level = gym["gym_details"]["raid_info"]["level"]
                    gymid = gym["id"]

                    mitm_mapper.collect_raid_stats(origin, gymid)

                    origin_logger.debug3(
                        "Adding/Updating gym {} with level {} ending at {}",
                        gymid, level, raidend_date)

                    cache_key = "raid{}{}{}".format(gymid, pokemon_id,
                                                    raid_end_sec)
                    if cache.exists(cache_key):
                        continue

                    raid_args.append(
                        (gymid, level, raidspawn_date, raidstart_date,
                         raidend_date, pokemon_id, cp, move_1, move_2, now,
                         form, is_exclusive, gender, costume, evolution))

                    cache.set(cache_key, 1, ex=900)

        self._db_exec.executemany(query_raid, raid_args, commit=True)
        origin_logger.debug3(
            "DbPogoProtoSubmit::raids: Done submitting raids with data received"
        )
        return True
Esempio n. 5
0
    def gyms(self, origin: str, map_proto: dict):
        """
        Update/Insert gyms from a map_proto dict
        """
        cache = get_cache(self._args)
        origin_logger = get_origin_logger(logger, origin=origin)
        origin_logger.debug3(
            "DbPogoProtoSubmit::gyms called with data received from")
        cells = map_proto.get("cells", None)
        if cells is None:
            return False
        gym_args = []
        gym_details_args = []
        now = datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%d %H:%M:%S")

        query_gym = (
            "INSERT INTO gym (gym_id, team_id, guard_pokemon_id, slots_available, enabled, latitude, longitude, "
            "total_cp, is_in_battle, last_modified, last_scanned, is_ex_raid_eligible) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE "
            "guard_pokemon_id=VALUES(guard_pokemon_id), team_id=VALUES(team_id), "
            "slots_available=VALUES(slots_available), last_scanned=VALUES(last_scanned), "
            "last_modified=VALUES(last_modified), latitude=VALUES(latitude), longitude=VALUES(longitude), "
            "is_ex_raid_eligible=VALUES(is_ex_raid_eligible)")
        query_gym_details = (
            "INSERT INTO gymdetails (gym_id, name, url, last_scanned) "
            "VALUES (%s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE last_scanned=VALUES(last_scanned), "
            "url=IF(VALUES(url) IS NOT NULL AND VALUES(url) <> '', VALUES(url), url)"
        )

        for cell in cells:
            for gym in cell["forts"]:
                if gym["type"] == 0:
                    guard_pokemon_id = gym["gym_details"]["guard_pokemon"]
                    gymid = gym["id"]
                    team_id = gym["gym_details"]["owned_by_team"]
                    latitude = gym["latitude"]
                    longitude = gym["longitude"]
                    slots_available = gym["gym_details"]["slots_available"]
                    last_modified_ts = gym["last_modified_timestamp_ms"] / 1000
                    last_modified = datetime.utcfromtimestamp(
                        last_modified_ts).strftime("%Y-%m-%d %H:%M:%S")
                    is_ex_raid_eligible = gym["gym_details"][
                        "is_ex_raid_eligible"]

                    cache_key = "gym{}{}".format(gymid, last_modified_ts)
                    if cache.exists(cache_key):
                        continue

                    gym_args.append((
                        gymid,
                        team_id,
                        guard_pokemon_id,
                        slots_available,
                        1,  # enabled
                        latitude,
                        longitude,
                        0,  # total CP
                        0,  # is_in_battle
                        last_modified,  # last_modified
                        now,  # last_scanned
                        is_ex_raid_eligible))

                    gym_details_args.append(
                        (gym["id"], "unknown", gym["image_url"], now))

                    cache.set(cache_key, 1, ex=900)
        self._db_exec.executemany(query_gym, gym_args, commit=True)
        self._db_exec.executemany(query_gym_details,
                                  gym_details_args,
                                  commit=True)
        return True
Esempio n. 6
0
    def mons(self, origin: str, timestamp: float, map_proto: dict,
             mitm_mapper):
        """
        Update/Insert mons from a map_proto dict
        """
        cache = get_cache(self._args)

        origin_logger = get_origin_logger(logger, origin=origin)
        origin_logger.debug3(
            "DbPogoProtoSubmit::mons called with data received")
        cells = map_proto.get("cells", None)
        if cells is None:
            return False

        query_mons = (
            "INSERT INTO pokemon (encounter_id, spawnpoint_id, pokemon_id, latitude, longitude, disappear_time, "
            "individual_attack, individual_defense, individual_stamina, move_1, move_2, cp, cp_multiplier, "
            "weight, height, gender, catch_prob_1, catch_prob_2, catch_prob_3, rating_attack, rating_defense, "
            "weather_boosted_condition, last_modified, costume, form) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
            "%s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE last_modified=VALUES(last_modified), disappear_time=VALUES(disappear_time)"
        )

        mon_args = []
        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"]
                mon_id = wild_mon["pokemon_data"]["id"]
                encounter_id = wild_mon["encounter_id"]

                if encounter_id < 0:
                    encounter_id = encounter_id + 2**64

                mitm_mapper.collect_mon_stats(origin, str(encounter_id))

                now = datetime.utcfromtimestamp(
                    time.time()).strftime("%Y-%m-%d %H:%M:%S")

                # get known spawn end time and feed into despawn time calculation
                getdetspawntime = self._get_detected_endtime(str(spawnid))
                despawn_time_unix = gen_despawn_timestamp(
                    getdetspawntime, timestamp)
                despawn_time = datetime.utcfromtimestamp(
                    despawn_time_unix).strftime("%Y-%m-%d %H:%M:%S")

                if getdetspawntime is None:
                    origin_logger.debug3(
                        "adding mon (#{}) at {}, {}. Despawns at {} (init) ({})",
                        mon_id, lat, lon, despawn_time, spawnid)
                else:
                    origin_logger.debug3(
                        "adding mon (#{}) at {}, {}. Despawns at {} (non-init) ({})",
                        mon_id, lat, lon, despawn_time, spawnid)

                cache_key = "mon{}".format(encounter_id)
                if cache.exists(cache_key):
                    continue

                mon_args.append((
                    encounter_id,
                    spawnid,
                    mon_id,
                    lat,
                    lon,
                    despawn_time,
                    # TODO: consider .get("XXX", None)  # noqa: E800
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    None,
                    wild_mon["pokemon_data"]["display"]["gender_value"],
                    None,
                    None,
                    None,
                    None,
                    None,
                    wild_mon["pokemon_data"]["display"]
                    ["weather_boosted_value"],
                    now,
                    wild_mon["pokemon_data"]["display"]["costume_value"],
                    wild_mon["pokemon_data"]["display"]["form_value"]))

                cache_time = int(despawn_time_unix -
                                 int(datetime.now().timestamp()))
                if cache_time > 0:
                    cache.set(cache_key, 1, ex=cache_time)

        self._db_exec.executemany(query_mons, mon_args, commit=True)
        return True
Esempio n. 7
0
    def mon_iv(self, origin: str, timestamp: float, encounter_proto: dict,
               mitm_mapper):
        """
        Update/Insert a mon with IVs
        """
        cache = get_cache(self._args)
        origin_logger = get_origin_logger(logger, origin=origin)
        wild_pokemon = encounter_proto.get("wild_pokemon", None)
        if wild_pokemon is None or wild_pokemon.get(
                "encounter_id",
                0) == 0 or not str(wild_pokemon["spawnpoint_id"]):
            return

        origin_logger.debug3("Updating IV sent for encounter at {}", timestamp)

        now = datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%d %H:%M:%S")

        spawnid = int(str(wild_pokemon["spawnpoint_id"]), 16)

        getdetspawntime = self._get_detected_endtime(str(spawnid))
        despawn_time_unix = gen_despawn_timestamp(getdetspawntime, timestamp)
        despawn_time = datetime.utcfromtimestamp(despawn_time_unix).strftime(
            "%Y-%m-%d %H:%M:%S")

        latitude = wild_pokemon.get("latitude")
        longitude = wild_pokemon.get("longitude")
        pokemon_data = wild_pokemon.get("pokemon_data")
        encounter_id = wild_pokemon["encounter_id"]
        shiny = wild_pokemon["pokemon_data"]["display"].get("is_shiny", 0)
        pokemon_display = pokemon_data.get("display", {})
        weather_boosted = pokemon_display.get('weather_boosted_value', None)

        if encounter_id < 0:
            encounter_id = encounter_id + 2**64

        cache_key = "moniv{}{}".format(encounter_id, weather_boosted)
        if cache.exists(cache_key):
            return

        mitm_mapper.collect_mon_iv_stats(origin, encounter_id, int(shiny))

        if getdetspawntime is None:
            origin_logger.debug3(
                "updating IV mon #{} at {}, {}. Despawning at {} (init)",
                pokemon_data["id"], latitude, longitude, despawn_time)
        else:
            origin_logger.debug3(
                "updating IV mon #{} at {}, {}. Despawning at {} (non-init)",
                pokemon_data["id"], latitude, longitude, despawn_time)

        capture_probability = encounter_proto.get("capture_probability")
        capture_probability_list = capture_probability.get(
            "capture_probability_list")
        if capture_probability_list is not None:
            capture_probability_list = capture_probability_list.replace(
                "[", "").replace("]", "").split(",")

        # ditto detector
        if is_mon_ditto(origin_logger, pokemon_data):
            # mon must be a ditto :D
            mon_id = 132
            gender = 3
            move_1 = 242
            move_2 = 133
            form = 0
        else:
            mon_id = pokemon_data.get("id")
            gender = pokemon_display.get("gender_value", None)
            move_1 = pokemon_data.get("move_1")
            move_2 = pokemon_data.get("move_2")
            form = pokemon_display.get("form_value", None)

        query = (
            "INSERT INTO pokemon (encounter_id, spawnpoint_id, pokemon_id, latitude, longitude, disappear_time, "
            "individual_attack, individual_defense, individual_stamina, move_1, move_2, cp, cp_multiplier, "
            "weight, height, gender, catch_prob_1, catch_prob_2, catch_prob_3, rating_attack, rating_defense, "
            "weather_boosted_condition, last_modified, costume, form) "
            "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
            "%s, %s, %s, %s, %s) "
            "ON DUPLICATE KEY UPDATE last_modified=VALUES(last_modified), disappear_time=VALUES(disappear_time), "
            "individual_attack=VALUES(individual_attack), individual_defense=VALUES(individual_defense), "
            "individual_stamina=VALUES(individual_stamina), move_1=VALUES(move_1), move_2=VALUES(move_2), "
            "cp=VALUES(cp), cp_multiplier=VALUES(cp_multiplier), weight=VALUES(weight), height=VALUES(height), "
            "gender=VALUES(gender), catch_prob_1=VALUES(catch_prob_1), catch_prob_2=VALUES(catch_prob_2), "
            "catch_prob_3=VALUES(catch_prob_3), rating_attack=VALUES(rating_attack), "
            "rating_defense=VALUES(rating_defense), weather_boosted_condition=VALUES(weather_boosted_condition), "
            "costume=VALUES(costume), form=VALUES(form), pokemon_id=VALUES(pokemon_id)"
        )
        insert_values = (encounter_id, spawnid, mon_id, latitude, longitude,
                         despawn_time, pokemon_data.get("individual_attack"),
                         pokemon_data.get("individual_defense"),
                         pokemon_data.get("individual_stamina"), move_1,
                         move_2, pokemon_data.get("cp"),
                         pokemon_data.get("cp_multiplier"),
                         pokemon_data.get("weight"),
                         pokemon_data.get("height"), gender,
                         float(capture_probability_list[0]),
                         float(capture_probability_list[1]),
                         float(capture_probability_list[2]), None, None,
                         weather_boosted, now,
                         pokemon_display.get("costume_value", None), form)

        self._db_exec.execute(query, insert_values, commit=True)
        cache_time = int(despawn_time_unix - datetime.now().timestamp())
        if cache_time > 0:
            cache.set(cache_key, 1, ex=int(cache_time))
        origin_logger.debug3("Done updating mon in DB")
        return True