Exemple #1
0
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
            evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})
            awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0)
            candy = inventory.candies().get(pokemon.pokemon_id)

            candy.consume(pokemon.evolution_cost - awarded_candies)

            self.emit_event(
                'pokemon_evolved',
                formatted="*Evolved {}* (IV {}) (CP {}) ({} candies) (+{} xp)".format(pokemon.name, pokemon.iv, pokemon.cp, candy.quantity, xp),
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp,
                    'candy': candy.quantity,
                    'xp': xp,
                }
            )

            inventory.pokemons().remove(pokemon.unique_id)
            new_pokemon = inventory.Pokemon(evolution)
            inventory.pokemons().add(new_pokemon)
            inventory.player().exp += xp

            action_delay(self.min_evolve_speed, self.max_evolve_speed)
            evolve_result = True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            evolve_result = False

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute('''INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)''', (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'evolve_log',
                    sender=self,
                    level='info',
                    formatted="evolve_log table not found, skipping log"
                )
                break

        return evolve_result
    def _execute_pokemon_evolve(self, pokemon, cache):
        if pokemon.name in cache:
            return False

        response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1:
            xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
            evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})
            awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0)
            candy = inventory.candies().get(pokemon.pokemon_id)

            candy.consume(pokemon.evolution_cost - awarded_candies)

            self.emit_event(
                'pokemon_evolved',
                formatted="*Evolved {}* (IV {}) (CP {}) ({} candies) (+{} xp)".format(pokemon.name, pokemon.iv, pokemon.cp, candy.quantity, xp),
                data={
                    'pokemon': pokemon.name,
                    'iv': pokemon.iv,
                    'cp': pokemon.cp,
                    'candy': candy.quantity,
                    'xp': xp,
                }
            )

            inventory.pokemons().remove(pokemon.unique_id)
            new_pokemon = inventory.Pokemon(evolution)
            inventory.pokemons().add(new_pokemon)
            inventory.player().exp += xp

            action_delay(self.min_evolve_speed, self.max_evolve_speed)
            evolve_result = True
        else:
            # cache pokemons we can't evolve. Less server calls
            cache[pokemon.name] = 1
            sleep(0.7)
            evolve_result = False

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

        result = c.fetchone()

        while True:
            if result[0] == 1:
                conn.execute('''INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)''', (pokemon.name, pokemon.iv, pokemon.cp))
                break
            else:
                self.emit_event(
                    'evolve_log',
                    sender=self,
                    level='info',
                    formatted="evolve_log table not found, skipping log"
                )
                break

        return evolve_result
    def get_items_awarded_from_fort_spinned(self, response_dict):
        experience_awarded = response_dict['responses']['FORT_SEARCH'].get(
            'experience_awarded', 0)
        inventory.player().exp += experience_awarded

        items_awarded = response_dict['responses']['FORT_SEARCH'].get(
            'items_awarded', {})
        loot = response_dict['responses']['FORT_SEARCH'].get('loot', {})
        bonus_loot = response_dict['responses']['FORT_SEARCH'].get(
            'bonus_loot', {})
        team_bonus_loot = response_dict['responses']['FORT_SEARCH'].get(
            'team_bonus_loot', {})
        tmp_count_items = {}

        if loot:
            # self.logger.info("Loot: %s" % loot)
            for item_awarded in loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        if bonus_loot:
            # self.logger.info("Bonus Loot: %s" % bonus_loot)
            for item_awarded in bonus_loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        if team_bonus_loot:
            # self.logger.info("Team Bonus Loot: %s" % team_bonus_loot)
            for item_awarded in team_bonus_loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        return tmp_count_items
    def evolve_pokemon(self, pokemon):
        while pokemon.unique_id in self.evolution_map:
            pokemon = self.evolution_map[pokemon.unique_id]

        if self.config_evolve and (not self.bot.config.test):
            response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": SUCCESS}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy_awarded = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        if self.config_evolve and (not self.bot.config.test):
            candy.consume(pokemon.evolution_cost - candy_awarded)
            inventory.player().exp += xp

        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "candy": candy.quantity,
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            new_pokemon = inventory.Pokemon(evolution)

            self.evolution_map[pokemon.unique_id] = new_pokemon

            inventory.pokemons().remove(pokemon.unique_id)
            inventory.pokemons().add(new_pokemon)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            sleep(self.config_evolve_time, 0.1)

        return True
    def evolve_pokemon(self, pokemon):
        while pokemon.unique_id in self.evolution_map:
            pokemon = self.evolution_map[pokemon.unique_id]

        if self.config_evolve and (not self.bot.config.test):
            response_dict = self.bot.api.evolve_pokemon(pokemon_id=pokemon.unique_id)
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": SUCCESS}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy_awarded = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        if self.config_evolve and (not self.bot.config.test):
            candy.consume(pokemon.evolution_cost - candy_awarded)
            inventory.player().exp += xp

        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "iv": pokemon.iv,
                              "cp": pokemon.cp,
                              "candy": candy.quantity,
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            new_pokemon = inventory.Pokemon(evolution)

            self.evolution_map[pokemon.unique_id] = new_pokemon

            inventory.pokemons().remove(pokemon.unique_id)
            inventory.pokemons().add(new_pokemon)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            sleep(self.config_evolve_time, 0.1)

        return True
Exemple #6
0
    def get_items_awarded_from_fort_spinned(self, response_dict):
        experience_awarded = response_dict['responses']['FORT_SEARCH'].get('experience_awarded', 0)
        inventory.player().exp += experience_awarded

        items_awarded = response_dict['responses']['FORT_SEARCH'].get('items_awarded', {})
        loot = response_dict['responses']['FORT_SEARCH'].get('loot', {})
        bonus_loot = response_dict['responses']['FORT_SEARCH'].get('bonus_loot', {})
        team_bonus_loot = response_dict['responses']['FORT_SEARCH'].get('team_bonus_loot', {})
        tmp_count_items = {}

        if loot:
            # self.logger.info("Loot: %s" % loot)
            for item_awarded in loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        if bonus_loot:
            # self.logger.info("Bonus Loot: %s" % bonus_loot)
            for item_awarded in bonus_loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        if team_bonus_loot:
            # self.logger.info("Team Bonus Loot: %s" % team_bonus_loot)
            for item_awarded in team_bonus_loot['loot_item']:
                item_awarded_id = item_awarded['item']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

        return tmp_count_items
Exemple #7
0
 def get_player_stats(self):
     stats = inventory.player().player_stats
     if stats:
         with self.bot.database as conn:
             cur = conn.cursor()
             cur.execute(
                 "SELECT COUNT(DISTINCT encounter_id) FROM catch_log WHERE dated >= datetime('now','-1 day')"
             )
             catch_day = cur.fetchone()[0]
             cur.execute(
                 "SELECT COUNT(pokestop) FROM pokestop_log WHERE dated >= datetime('now','-1 day')"
             )
             ps_day = cur.fetchone()[0]
             res = ("*" + self.bot.config.username + "*",
                    "_Level:_ " + str(stats["level"]),
                    "_XP:_ " + str(stats["experience"]) + "/" +
                    str(stats["next_level_xp"]), "_Pokemons Captured:_ " +
                    str(stats.get("pokemons_captured", 0)) + " (" +
                    str(catch_day) + " _last 24h_)",
                    "_Poke Stop Visits:_ " +
                    str(stats.get("poke_stop_visits", 0)) + " (" +
                    str(ps_day) + " _last 24h_)", "_KM Walked:_ " +
                    str("%.2f" % stats.get("km_walked", 0)))
         return (res)
     else:
         return ("Stats not loaded yet\n")
    def work(self):
        if self._should_run():
            self.current_level = inventory.player().level

            if self.collect_reward:
                # let's check level reward on bot initialization
                # to be able get rewards for old bots
                if self.previous_level == 0:
                    self._collect_level_reward()
                # level up situation
                elif self.current_level > self.previous_level:
                    self.emit_event(
                        'level_up',
                        formatted='Level up from {previous_level} to {current_level}',
                        data={
                            'previous_level': self.previous_level,
                            'current_level': self.current_level
                        }
                    )
                    self._collect_level_reward()

            if self.level_limit != -1 and self.current_level >= self.level_limit:
                sys.exit("You have reached your target level! Exiting now.")

            self.previous_level = self.current_level
    def get_player_stats(self):
        stats = inventory.player().player_stats
        dust = self.get_dust()
        if stats:
            with self.bot.database as conn:
                cur = conn.cursor()
                cur.execute(
                    "SELECT COUNT(DISTINCT encounter_id) FROM catch_log WHERE dated >= datetime('now','-1 day')")
                catch_day = cur.fetchone()[0]
                cur.execute("SELECT COUNT(pokestop) FROM pokestop_log WHERE dated >= datetime('now','-1 day')")
                ps_day = cur.fetchone()[0]
                res = (
                    self.bot.config.username,
                    str(stats["level"]),
                    str(stats["experience"]),
                    str(stats["next_level_xp"]),
                    str(stats["pokemons_captured"]),
                    str(catch_day),
                    str(stats["poke_stop_visits"]),
                    str(ps_day),
                    str("%.2f" % stats["km_walked"]),
                    str(dust)

                )
            return (res)
    def check_buddy(self):
        self.buddy = self.bot.player_data.get("buddy_pokemon", {})
        self.buddyid = self._get_buddyid()

        if not self.buddy:
            self.lock_buddy = False
            return

        pokemon = next((p for p in inventory.pokemons().all() if p.unique_id == self.buddy["id"]), None)

        if not pokemon:
            return

        km_walked = inventory.player().player_stats.get("km_walked", 0)
        last_km_awarded = self.buddy.setdefault("last_km_awarded", km_walked)
        distance_walked = km_walked - last_km_awarded
        distance_needed = pokemon.buddy_distance_needed

        if distance_walked >= distance_needed:
            self.get_buddy_walked(pokemon)
            # self.buddy["start_km_walked"] can be empty here
            if 'start_km_walked' not in self.buddy:
                self.buddy["start_km_walked"] = 0
            self.buddy["last_km_awarded"] = self.buddy["start_km_walked"] + distance_needed * int(distance_walked / distance_needed)
            self.lock_buddy = False
        else:
            now = time.time()

            if self.no_log_until < now:
                self.no_log_until = now + LOG_TIME_INTERVAL
                self.emit_event("buddy_walked",
                                formatted="Buddy {pokemon} walking: {distance_walked:.2f} / {distance_needed:.2f} km",
                                data={"pokemon": pokemon.name,
                                      "distance_walked": distance_walked,
                                      "distance_needed": distance_needed})
Exemple #11
0
    def work(self):
        if self._should_run():
            self.current_level = inventory.player().level

            if self.collect_reward:
                # let's check level reward on bot initialization
                # to be able get rewards for old bots
                if self.previous_level == 0:
                    self._collect_level_reward()
                # level up situation
                elif self.current_level > self.previous_level:
                    self.emit_event(
                        'level_up',
                        formatted=
                        'Level up from {previous_level} to {current_level}',
                        data={
                            'previous_level': self.previous_level,
                            'current_level': self.current_level
                        })
                    self._collect_level_reward()

            if self.level_limit != -1 and self.current_level >= self.level_limit:
                sys.exit("You have reached your target level! Exiting now.")

            self.previous_level = self.current_level
    def check_buddy(self):
        self.buddy = self.bot.player_data.get("buddy_pokemon", {})
        self.buddyid = self._get_buddyid()

        if not self.buddy:
            self.lock_buddy = False
            return

        pokemon = next((p for p in inventory.pokemons().all() if p.unique_id == self.buddy["id"]), None)

        if not pokemon:
            return

        km_walked = inventory.player().player_stats.get("km_walked", 0)
        last_km_awarded = self.buddy.setdefault("last_km_awarded", km_walked)
        distance_walked = km_walked - last_km_awarded
        distance_needed = pokemon.buddy_distance_needed

        if distance_walked >= distance_needed:
            self.get_buddy_walked(pokemon)
            # self.buddy["start_km_walked"] can be empty here
            if 'start_km_walked' not in self.buddy:
                self.buddy["start_km_walked"] = 0
            self.buddy["last_km_awarded"] = self.buddy["start_km_walked"] + distance_needed * int(distance_walked / distance_needed)
            self.lock_buddy = False
        else:
            now = time.time()

            if self.no_log_until < now:
                self.no_log_until = now + LOG_TIME_INTERVAL
                self.emit_event("buddy_walked",
                                formatted="Buddy {pokemon} walking: {distance_walked:.2f} / {distance_needed:.2f} km",
                                data={"pokemon": pokemon.name,
                                      "distance_walked": distance_walked,
                                      "distance_needed": distance_needed})
Exemple #13
0
    def get_items_awarded_from_fort_spinned(self, response_dict):
        experience_awarded = response_dict['responses']['FORT_SEARCH'].get('experience_awarded', 0)
        inventory.player().exp += experience_awarded

        items_awarded = response_dict['responses']['FORT_SEARCH'].get('items_awarded', {})
        if items_awarded:
            tmp_count_items = {}
            for item_awarded in items_awarded:

                item_awarded_id = item_awarded['item_id']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['item_count']

                if item_awarded_name not in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

            return tmp_count_items
Exemple #14
0
    def get_items_awarded_from_fort_spinned(self, response_dict):
        experience_awarded = response_dict['responses']['FORT_SEARCH'].get('experience_awarded', 0)
        inventory.player().exp += experience_awarded

        items_awarded = response_dict['responses']['FORT_SEARCH'].get('items_awarded', {})
        if items_awarded:
            tmp_count_items = {}
            for item_awarded in items_awarded:

                item_awarded_id = item_awarded['item_id']
                item_awarded_name = inventory.Items.name_for(item_awarded_id)
                item_awarded_count = item_awarded['item_count']

                if not item_awarded_name in tmp_count_items:
                    tmp_count_items[item_awarded_name] = item_awarded_count
                else:
                    tmp_count_items[item_awarded_name] += item_awarded_count

                self._update_inventory(item_awarded)

            return tmp_count_items
    def work(self):

        if self.tutorial_run:
            self.tutorial_run = False
            if not self._check_tutorial_state():
                return WorkerResult.ERROR

        if self.team_run and player()._level >= 5:
            self.team_run = False
            if not self._set_team():
                return WorkerResult.ERROR

        return WorkerResult.SUCCESS
    def work(self):

        if self.tutorial_run:
            self.tutorial_run = False
            if not self._check_tutorial_state():
                return WorkerResult.ERROR

        if self.team_run and player()._level >= 5:
            self.team_run = False
            if not self._set_team():
                return WorkerResult.ERROR

        return WorkerResult.SUCCESS
    def upgrade_pokemon(self, pokemon):
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)
        candy = inventory.candies().get(pokemon.pokemon_id)

        for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
            upgrade_cost = self.pokemon_upgrade_cost[i - 2]
            upgrade_candy_cost = upgrade_cost[0]
            upgrade_stardust_cost = upgrade_cost[1]

            if self.config_upgrade and (not self.bot.config.test):
                request = self.bot.api.create_request()
                request.upgrade_pokemon(pokemon_id=pokemon.unique_id)
                response_dict = request.call()
            else:
                response_dict = {"responses": {"UPGRADE_POKEMON": {"result": SUCCESS}}}

            if not response_dict:
                return False

            result = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("result", 0)

            if result != SUCCESS:
                return False

            upgrade = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("upgraded_pokemon", {})

            if self.config_upgrade and (not self.bot.config.test):
                candy.consume(upgrade_candy_cost)
                self.bot.stardust -= upgrade_stardust_cost

            new_pokemon = inventory.Pokemon(upgrade)
            self.emit_event("pokemon_upgraded",
                            formatted="Upgraded {pokemon} [IV {iv}] [CP {cp} -> {new_cp}] [{candy} candies] [{stardust} stardust]",
                            data={"pokemon": pokemon.name,
                                  "iv": pokemon.iv,
                                  "cp": pokemon.cp,
                                  "new_cp": new_pokemon.cp,
                                  "candy": candy.quantity,
                                  "stardust": self.bot.stardust})

            if self.config_upgrade and (not self.bot.config.test):
                inventory.pokemons().remove(pokemon.unique_id)

                new_pokemon = inventory.Pokemon(upgrade)
                inventory.pokemons().add(new_pokemon)
                pokemon = new_pokemon

                action_delay(self.config_action_wait_min, self.config_action_wait_max)

        return True
    def upgrade_pokemon(self, pokemon):
        level = int(pokemon.level * 2) - 1
        upgrade_level = min(self.config_upgrade_level, inventory.player().level * 2)
        candy = inventory.candies().get(pokemon.pokemon_id)

        for i in range(level, upgrade_level):
            upgrade_cost = self.pokemon_upgrade_cost[i - 1]
            upgrade_candy_cost = upgrade_cost[0]
            upgrade_stardust_cost = upgrade_cost[1]

            if self.config_upgrade and (not self.bot.config.test):
                response_dict = self.bot.api.upgrade_pokemon(pokemon_id=pokemon.unique_id)
            else:
                response_dict = {"responses": {"UPGRADE_POKEMON": {"result": SUCCESS}}}

            if not response_dict:
                return False

            result = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("result", 0)

            if result != SUCCESS:
                return False

            upgrade = response_dict.get("responses", {}).get("UPGRADE_POKEMON", {}).get("upgraded_pokemon", {})

            if self.config_upgrade and (not self.bot.config.test):
                candy.consume(upgrade_candy_cost)
                self.stardust_count -= upgrade_stardust_cost

            self.emit_event("pokemon_upgraded",
                            formatted="Upgraded {pokemon} [IV {iv}] [CP {cp}] [{candy} candies] [{stardust} stardust]",
                            data={"pokemon": pokemon.name,
                                  "iv": pokemon.iv,
                                  "cp": pokemon.cp,
                                  "candy": candy.quantity,
                                  "stardust": self.stardust_count})

            if self.config_upgrade and (not self.bot.config.test):
                inventory.pokemons().remove(pokemon.unique_id)

                new_pokemon = inventory.Pokemon(upgrade)
                inventory.pokemons().add(new_pokemon)

                action_delay(self.config_transfer_wait_min, self.config_transfer_wait_max)

        return True
 def _log_on_terminal(self, stats):
     """
     Logs the stats into the terminal using an event.
     :param stats: The stats to display.
     :type stats: string
     :return: Nothing.
     :rtype: None
     """
     self.emit_event(
         'log_stats',
         formatted="{stats}",
         data={
             'stats': stats,
             'stats_raw': self._get_stats(inventory.player().player_stats)
         }
     )
     self._compute_next_update()
 def _log_on_terminal(self, stats):
     """
     Logs the stats into the terminal using an event.
     :param stats: The stats to display.
     :type stats: string
     :return: Nothing.
     :rtype: None
     """
     self.emit_event(
         'log_stats',
         formatted="{stats}",
         data={
             'stats': stats,
             'stats_raw': self._get_stats(inventory.player().player_stats)
         }
     )
     self._compute_next_update()
Exemple #21
0
 def get_player_stats(self):
     stats = inventory.player().player_stats
     dust = self.get_dust()
     if stats:
         with self.bot.database as conn:
             cur = conn.cursor()
             cur.execute(
                 "SELECT COUNT(DISTINCT encounter_id) FROM catch_log WHERE dated >= datetime('now','-1 day')"
             )
             catch_day = cur.fetchone()[0]
             cur.execute(
                 "SELECT COUNT(pokestop) FROM pokestop_log WHERE dated >= datetime('now','-1 day')"
             )
             ps_day = cur.fetchone()[0]
             res = (self.bot.config.username, str(stats["level"]),
                    str(stats["experience"]), str(stats["next_level_xp"]),
                    str(stats["pokemons_captured"]), str(catch_day),
                    str(stats["poke_stop_visits"]), str(ps_day),
                    str("%.2f" % stats["km_walked"]), str(dust))
         return (res)
    def work(self):
        """
        Displays the stats if necessary.
        :return: Always returns WorkerResult.SUCCESS.
        :rtype: WorkerResult
        """
        if not self._should_display():
            return WorkerResult.SUCCESS
            
        player_stats = inventory.player().player_stats
        line = self._get_stats_line(player_stats)
        # If line is empty, it couldn't be generated.
        if not line:
            return WorkerResult.SUCCESS
                               
        if self.terminal_title:
            self._update_title(line, _platform)

        if self.terminal_log:
            self._log_on_terminal(line)
        return WorkerResult.SUCCESS
    def work(self):
        """
        Displays the stats if necessary.
        :return: Always returns WorkerResult.SUCCESS.
        :rtype: WorkerResult
        """
        if not self._should_display():
            return WorkerResult.SUCCESS

        player_stats = inventory.player().player_stats
        line = self._get_stats_line(self._get_stats(player_stats))
        # If line is empty, it couldn't be generated.
        if not line:
            return WorkerResult.SUCCESS

        if self.terminal_title:
            self._update_title(line, _platform)

        if self.terminal_log:
            self._log_on_terminal(line)
        return WorkerResult.SUCCESS
Exemple #24
0
    def work(self):
        forts = self.get_forts_in_range()
        current_level = inventory.player().level
        is_pokestop = False

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute("SELECT DISTINCT COUNT(pokestop) FROM pokestop_log WHERE dated >= datetime('now','-1 day')")
        if c.fetchone()[0] >= self.config.get('daily_spin_limit', 2000):
           if self.exit_on_limit_reached:
               self.emit_event('spin_limit', formatted='WARNING! You have reached your daily spin limit')
               sys.exit(2)

           if datetime.now() >= self.next_update:
               self.emit_event('spin_limit', formatted='WARNING! You have reached your daily spin limit')
               self._compute_next_update()
               return WorkerResult.SUCCESS

        if not self.should_run() or len(forts) == 0:
            return WorkerResult.SUCCESS

        fort = forts[0]

        if fort['id'] in self.streak_forts:
            self.fort_spins = 1
            self.streak_forts = [fort['id']]
        elif self.fort_spins >= 10:
            self.fort_spins = 1
            self.streak_forts = [fort['id']]
        else:
            self.fort_spins += 1

        lat = fort['latitude']
        lng = fort['longitude']

        details = fort_details(self.bot, fort['id'], lat, lng)

        fort_name = details.get('name', 'Unknown')
        check_fort_modifier = details.get('modifiers', {})
        if self.use_lure and check_fort_modifier:
            # check_fort_modifier_id = check_fort_modifier[0].get('item_id')
            self.emit_event('lure_info', formatted='A lure is already in fort, skip deploying lure')

        if "type" in fort and fort["type"] == 1:
            is_pokestop = True

        if self.use_lure and not check_fort_modifier and is_pokestop:
            # check lures availiblity
            lure_count = inventory.items().get(501).count

            if lure_count > 1: # Only use lures when there's more than one
                request = self.bot.api.create_request()
                request.add_fort_modifier(
                    modifier_type=501,
                    fort_id = fort['id'],
                    player_latitude = f2i(self.bot.position[0]),
                    player_longitude = f2i(self.bot.position[1])
                )
                response_dict = request.call()

                if ('responses' in response_dict) and ('ADD_FORT_MODIFIER' in response_dict['responses']):
                    add_modifier_deatils = response_dict['responses']['ADD_FORT_MODIFIER']
                    add_modifier_result = add_modifier_deatils.get('result', -1)
                    if (add_modifier_result == LURE_REQUEST_RESULT_SUCCESS):
                        self.emit_event('lure_success', formatted='You have successfully placed a lure')
                    if (add_modifier_result == LURE_REQUEST_FORT_ALREADY_HAS_MODIFIER):
                        self.emit_event('lure_failed', formatted='A lure has being placed before you try to do so')
                    if (add_modifier_result == LURE_REQUEST_TOO_FAR_AWAY):
                        self.emit_event('lure_failed', formatted='Pokestop out of range')
                    if (add_modifier_result == LURE_REQUEST_NO_ITEM_IN_INVENTORY):
                        self.emit_event('lure_not_enough', formatted='Not enough lure in inventory')
                    if (add_modifier_result == LURE_REQUEST_POI_INACCESSIBLE):
                        self.emit_event('lure_info', formatted='Unkown Error')
            else:
                self.emit_event('lure_not_enough', formatted='Not enough lure in inventory')
                
        if not is_pokestop and current_level < 5:
            self.logger.info("Player level is less than 5. Gym is not accessable at this time.")
            self.bot.fort_timeouts[fort["id"]] = (time.time() + 300) * 1000  # Don't spin for 5m
            return WorkerResult.ERROR
            
        request = self.bot.api.create_request()
        request.fort_search(
            fort_id=fort['id'],
            fort_latitude=lat,
            fort_longitude=lng,
            player_latitude=f2i(self.bot.position[0]),
            player_longitude=f2i(self.bot.position[1])
        )
        response_dict = request.call()

        if ('responses' in response_dict) and ('FORT_SEARCH' in response_dict['responses']):
            spin_details = response_dict['responses']['FORT_SEARCH']
            spin_result = spin_details.get('result', -1)

            if (spin_result == SPIN_REQUEST_RESULT_SUCCESS) or (spin_result == SPIN_REQUEST_RESULT_INVENTORY_FULL):
                self.bot.softban = False
                experience_awarded = spin_details.get('experience_awarded', 0)
                items_awarded = self.get_items_awarded_from_fort_spinned(response_dict)
                egg_awarded = spin_details.get('pokemon_data_egg', None)
                gym_badge_awarded = spin_details.get('awarded_gym_badge', None)
                chain_hack_sequence_number = spin_details.get('chain_hack_sequence_number', 0)
                raid_tickets_int = spin_details.get('raid_tickets', None)
                raid_tickets = None
                if raid_tickets_int:
                    raid_tickets = inventory.Items.name_for(1401)
                    
                if egg_awarded is not None:
                    items_awarded[u'Egg'] = egg_awarded['egg_km_walked_target']

                # if gym_badge_awarded is not None:
                #     self.logger.info("Gained a Gym Badge! %s" % gym_badge_awarded)
                #
                # if chain_hack_sequence_number > 0:
                #     self.logger.info("Chain hack sequence: %s" % chain_hack_sequence_number)

                if experience_awarded or items_awarded:
                    awards = ', '.join(["{}x {}".format(items_awarded[x], x) for x in items_awarded if x != u'Egg'])
                    if egg_awarded is not None:
                        awards += u', {} Egg'.format(egg_awarded['egg_km_walked_target'])     
                    if raid_tickets is not None:
                        awards += u', {}'.format(raid_tickets)
                        
                    self.fort_spins = chain_hack_sequence_number

                    if "type" in fort and fort["type"] == 1:
                        # It's a Pokestop
                        stop_kind = "pokestop"
                    else:
                        # It's a gym
                        stop_kind = "gym"

                    self.emit_event(
                        'spun_pokestop',
                        formatted="Spun {stop_kind} {pokestop} ({spin_amount_now} streak). Experience awarded: {exp}. Items awarded: {items}",
                        data={
                            'stop_kind': stop_kind,
                            'pokestop': fort_name,
                            'exp': experience_awarded,
                            'spin_amount_now': chain_hack_sequence_number,
                            'items': awards
                        }
                    )
                    #time.sleep(10)
                else:
                    self.emit_event(
                        'pokestop_empty',
                        formatted='Found nothing in pokestop {pokestop}.',
                        data={'pokestop': fort_name}
                    )
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='pokestop_log'")
                result = c.fetchone()
                while True:
                    if result[0] == 1:
                        conn.execute('''INSERT INTO pokestop_log (pokestop, exp, items) VALUES (?, ?, ?)''', (fort_name, str(experience_awarded), str(items_awarded)))
                        break
                    else:
                        self.emit_event('pokestop_log',
                                        sender=self,
                                        level='info',
                                        formatted="pokestop_log table not found, skipping log")
                        break
                pokestop_cooldown = spin_details.get(
                    'cooldown_complete_timestamp_ms')
                self.bot.fort_timeouts.update({fort["id"]: pokestop_cooldown})
                self.bot.recent_forts = self.bot.recent_forts[1:] + [fort['id']]
            elif spin_result == SPIN_REQUEST_RESULT_OUT_OF_RANGE:
                self.emit_event(
                    'pokestop_out_of_range',
                    formatted="Pokestop {pokestop} out of range.",
                    data={'pokestop': fort_name}
                )
            elif spin_result == SPIN_REQUEST_RESULT_IN_COOLDOWN_PERIOD:
                pokestop_cooldown = spin_details.get(
                    'cooldown_complete_timestamp_ms')
                if pokestop_cooldown:
                    self.bot.fort_timeouts.update({fort["id"]: pokestop_cooldown})
                    seconds_since_epoch = time.time()
                    minutes_left = format_time(
                        (pokestop_cooldown / 1000) - seconds_since_epoch
                    )
                    self.emit_event(
                        'pokestop_on_cooldown',
                        formatted="Pokestop {pokestop} on cooldown. Time left: {minutes_left}.",
                        data={'pokestop': fort_name, 'minutes_left': minutes_left}
                    )
            elif spin_result == SPIN_REQUEST_RESULT_POI_INACCESSIBLE:
                self.logger.info("Pokestop not accessable at this time.")
                self.bot.fort_timeouts[fort["id"]] = (time.time() + 300) * 1000  # Don't spin for 5m
            else:
                self.emit_event(
                    'unknown_spin_result',
                    formatted="Unknown spint result {status_code}",
                    data={'status_code': str(spin_result)}
                )
            if 'chain_hack_sequence_number' in response_dict['responses'][
                    'FORT_SEARCH']:
                action_delay(self.spin_wait_min, self.spin_wait_max)
                return response_dict['responses']['FORT_SEARCH'][
                    'chain_hack_sequence_number']
            else:
                self.emit_event(
                    'pokestop_searching_too_often',
                    formatted="Possibly searching too often, take a rest."
                )
                if spin_result == 1 and not items_awarded and not experience_awarded and not pokestop_cooldown:
                    self.bot.softban = True
                    self.emit_event(
                        'softban',
                        formatted='Probably got softban.'
                    )
                    with self.bot.database as conn:
                        c = conn.cursor()
                        c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='softban_log'")
                    result = c.fetchone()

                    if result[0] == 1:
                        source = str("SpinFort")
                        status = str("Possible Softban")
                        conn.execute('''INSERT INTO softban_log (status, source) VALUES (?, ?)''', (status, source))
                    else:
                        self.emit_event('softban_log',
                                        sender=self,
                                        level='info',
                                        formatted="softban_log table not found, skipping log")

                self.bot.fort_timeouts[fort["id"]] = (time.time() + 300) * 1000  # Don't spin for 5m

                return WorkerResult.ERROR
        action_delay(self.spin_wait_min, self.spin_wait_max)

        if len(forts) > 1:
            return WorkerResult.RUNNING

        return WorkerResult.SUCCESS
Exemple #25
0
 def _get_player_stats(self):
     return inventory.player().player_stats
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            candies += 1
            evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level * 2)

        for pokemon in try_upgrade:
            level = int(pokemon.level * 2) - 1

            if level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(level, upgrade_level):
                upgrade_cost = self.pokemon_upgrade_cost[i - 1]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if self.config_evolve_for_xp:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]

            # If not much to evolve, better keep the candies
            if len(xp) < math.ceil(self.max_pokemon_storage * 0.02):
                xp = []

            transfer = [p for p in crap if p not in xp]
        else:
            xp = []
            transfer = crap

        return (transfer, evolve, upgrade, xp)
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity
        family_name = inventory.Pokemons().name_for(family_id)

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite and not (p.unique_id == self.buddyid)]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            pokemon_id = pokemon.pokemon_id
            needed_evolution_item = inventory.pokemons().evolution_item_for(pokemon_id)
            if needed_evolution_item is not None:
                if self.config_use_evolution_items:
                    # We need a special Item to evolve this Pokemon!
                    item = inventory.items().get(needed_evolution_item)
                    needed = inventory.pokemons().evolution_items_needed_for(pokemon_id)
                    if item.count < needed:
                        self.logger.info("To evolve a {} we need {} of {}. We have {}".format(pokemon.name, needed, item.name, item.count))
                        continue
                else:
                    # pass for this Pokemon
                    continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id
                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies -= inventory.pokemons().evolution_cost_for(pokemon_id)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies += 1
                    evolve.append(pokemon)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies += 1
                evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)
        # Highest CP on top.
        if len(try_upgrade) > 0:
            try_upgrade.sort(key=lambda p: (p.cp), reverse=True)
        for pokemon in try_upgrade:
            # self.log("Considering %s for upgrade" % pokemon.name)
            if pokemon.level >= upgrade_level:
                # self.log("Pokemon already at target level. %s" % pokemon.level)
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
                upgrade_cost = self.pokemon_upgrade_cost[i - 2]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                # self.log("Not enough candy: %s" % candies)
                # self.log("or stardust %s" % self.ongoing_stardust_count)
                # We didn' t use the stardust, so refund it...
                self.ongoing_stardust_count += full_upgrade_stardust_cost
                continue
            # self.log("Pokemon can be upgraded!!")
            upgrade.append(pokemon)

        if (not self.config_evolve_for_xp) or (family_name in self.config_evolve_for_xp_blacklist):
            xp = []
            transfer = crap
        elif self.config_evolve_for_xp_whitelist and (family_name not in self.config_evolve_for_xp_whitelist):
            xp = []
            transfer = crap
        else:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]
            transfer = [p for p in crap if p not in xp]

        return (transfer, evolve, upgrade, xp)
Exemple #28
0
 def initialize(self):
     self._process_config()
     self.current_level = inventory.player().level
     self.previous_level = 0
    def evolve_pokemon(self, pokemon, transfer=False):
        while pokemon.unique_id in self.evolution_map:
            pokemon = self.evolution_map[pokemon.unique_id]

        if self.config_evolve and (not self.bot.config.test):
            needed_evolution_item = inventory.pokemons().evolution_item_for(pokemon.pokemon_id)
            if needed_evolution_item is not None:
                if self.config_use_evolution_items:
                    # We need evolution_item_requirement with some!!
                    request = self.bot.api.create_request()
                    request.evolve_pokemon(pokemon_id=pokemon.unique_id, evolution_item_requirement=needed_evolution_item)
                    response_dict = request.call()
                else:
                    return False
            else:
                request = self.bot.api.create_request()
                request.evolve_pokemon(pokemon_id=pokemon.unique_id)
                response_dict = request.call()
        else:
            response_dict = {"responses": {"EVOLVE_POKEMON": {"result": SUCCESS}}}

        if not response_dict:
            return False

        result = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("result", 0)

        if result != SUCCESS:
            self.logger.info("Can't evolve %s" % pokemon.name)
            self.logger.info(response_dict)
            self.logger.info(result)
            return False

        xp = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("experience_awarded", 0)
        candy_awarded = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("candy_awarded", 0)
        candy = inventory.candies().get(pokemon.pokemon_id)
        evolution = response_dict.get("responses", {}).get("EVOLVE_POKEMON", {}).get("evolved_pokemon_data", {})

        if self.config_evolve and (not self.bot.config.test):
            candy.consume(pokemon.evolution_cost - candy_awarded)
            inventory.player().exp += xp
        new_pokemon = inventory.Pokemon(evolution)
        self.emit_event("pokemon_evolved",
                        formatted="Evolved {pokemon} [CP {old_cp}] into {new} [IV {iv}] [CP {cp}] [{candy} candies] [+{xp} xp]",
                        data={"pokemon": pokemon.name,
                              "new": new_pokemon.name,
                              "iv": pokemon.iv,
                              "old_cp": pokemon.cp,
                              "cp": new_pokemon.cp,
                              "candy": candy.quantity,
                              "xp": xp})

        if self.config_evolve and (not self.bot.config.test):
            new_pokemon = inventory.Pokemon(evolution)

            self.evolution_map[pokemon.unique_id] = new_pokemon

            inventory.pokemons().remove(pokemon.unique_id)
            inventory.pokemons().add(new_pokemon)

            with self.bot.database as db:
                cursor = db.cursor()
                cursor.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='evolve_log'")

                db_result = cursor.fetchone()

                if db_result[0] == 1:
                    db.execute("INSERT INTO evolve_log (pokemon, iv, cp) VALUES (?, ?, ?)", (pokemon.name, pokemon.iv, pokemon.cp))

            sleep(self.config_evolve_time, 0.1)
        if transfer and not self.used_lucky_egg:
            # Transfer the new Pokemon imediately!
            self.transfer_pokemon([new_pokemon], True)

        return True
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve,
                           try_upgrade):
        candies = inventory.candies().get(family_id).quantity

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            candies += 1
            evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level,
                            inventory.player().level * 2)

        for pokemon in try_upgrade:
            level = int(pokemon.level * 2) - 1

            if level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(level, upgrade_level):
                upgrade_cost = self.pokemon_upgrade_cost[i - 1]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if self.config_evolve_for_xp:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(
                family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [
                p for p in crap if p.has_next_evolution()
                and p.evolution_cost == lowest_evolution_cost
            ][:keep_for_xp]

            # If not much to evolve, better keep the candies
            if len(xp) < math.ceil(self.max_pokemon_storage * 0.02):
                xp = []

            transfer = [p for p in crap if p not in xp]
        else:
            xp = []
            transfer = crap

        return (transfer, evolve, upgrade, xp)
 def initialize(self):
     self._process_config()
     self.current_level = inventory.player().level
     self.previous_level = 0
Exemple #32
0
 def _hatch_eggs(self):
     response_dict = self.bot.api.get_hatched_eggs()
     log_color = 'green'
     try:
         result = reduce(dict.__getitem__,
                         ["responses", "GET_HATCHED_EGGS"], response_dict)
     except KeyError:
         return
     pokemon_ids = []
     if 'pokemon_id' in result:
         pokemon_ids = [id for id in result['pokemon_id']]
     stardust = result.get('stardust_awarded', "error")
     candy = result.get('candy_awarded', "error")
     xp = result.get('experience_awarded', "error")
     sleep(self.hatching_animation_delay)
     try:
         pokemon_data = self._check_inventory(pokemon_ids)
         for pokemon in pokemon_data:
             # pokemon ids seem to be offset by one
             if pokemon['pokemon_id'] != -1:
                 pokemon['name'] = self.bot.pokemon_list[(
                     pokemon.get('pokemon_id') - 1)]['Name']
                 #remove as egg and add as pokemon
                 inventory.pokemons().remove(pokemon['id'])
                 inventory.pokemons().add(inventory.Pokemon(pokemon))
             else:
                 pokemon['name'] = "error"
     except:
         pokemon_data = [{"name": "error", "cp": "error", "iv": "error"}]
     if not pokemon_ids or not pokemon_data or pokemon_data[0][
             'name'] == "error":
         self.emit_event('egg_hatched',
                         data={
                             'pokemon': 'error',
                             'cp': 'error',
                             'iv': 'error',
                             'exp': 'error',
                             'stardust': 'error',
                             'candy': 'error',
                         })
         return
     for i in range(len(pokemon_data)):
         msg = "Egg hatched with a {pokemon} (CP {cp} - IV {iv}), {exp} exp, {stardust} stardust and {candy} candies."
         self.bot.metrics.hatched_eggs(1)
         self.emit_event(
             'egg_hatched',
             formatted=msg,
             data={
                 'pokemon':
                 pokemon_data[i]['name'],
                 'cp':
                 pokemon_data[i]['cp'],
                 'iv':
                 "{} {}".format(
                     "/".join(map(str, pokemon_data[i]['iv'])),
                     round(sum(pokemon_data[i]['iv']) / self.max_iv, 2)),
                 'exp':
                 xp[i],
                 'stardust':
                 stardust[i],
                 'candy':
                 candy[i],
             })
         # hatching egg gets exp too!
         inventory.player().exp += xp[i]
Exemple #33
0
 def should_run(self):
     # Check if we have any Pokemons and are level > 5 and have selected a team
     return player()._level >= 5 and len(
         self.pokemons) > 0 and self.team > TEAM_NOT_SET
Exemple #34
0
 def _km_walked(self):
     return inventory.player().player_stats.get("km_walked", 0)
 def _get_player_stats(self):
     return inventory.player().player_stats
    def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False):
        # settings that may be exposed at some point
        """

        :type pokemon: Pokemon
        """
        berry_count = self.inventory.get(ITEM_RAZZBERRY).count
        ball_count = {}
        for ball_id in [ITEM_POKEBALL, ITEM_GREATBALL, ITEM_ULTRABALL]:
            ball_count[ball_id] = self.inventory.get(ball_id).count

        # use `min_ultraball_to_keep` from config if is not None
        min_ultraball_to_keep = ball_count[ITEM_ULTRABALL]
        if self.min_ultraball_to_keep is not None and self.min_ultraball_to_keep >= 0:
            min_ultraball_to_keep = self.min_ultraball_to_keep

        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_GREATBALL if ball_count[ITEM_ULTRABALL] < min_ultraball_to_keep else ITEM_ULTRABALL
        ideal_catch_rate_before_throw = self.vip_berry_threshold if is_vip else self.berry_threshold

        used_berry = False
        original_catch_rate_by_ball = catch_rate_by_ball
        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while ball_count[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if ball_count[current_ball] == 0:
                self.emit_event('no_pokeballs', formatted='No pokeballs left! Fleeing...')
                return WorkerResult.ERROR

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += ball_count[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            changed_ball = False
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berries_to_spare and not used_berry:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and ball_count[best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball
                    changed_ball = True

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                new_catch_rate_by_ball = self._use_berry(berry_id, berry_count, encounter_id, catch_rate_by_ball, current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # If we change ball then wait to simulate user selecting it
            if changed_ball:
                action_delay(self.catchsim_changeball_wait_min, self.catchsim_changeball_wait_max)

            # Randomize the quality of the throw
            # Default structure
            throw_parameters = {'normalized_reticle_size': 1.950,
                                'spin_modifier': 1.0,
                                'normalized_hit_position': 1.0,
                                'throw_type_label': 'Excellent'}
            self.generate_spin_parameter(throw_parameters)
            self.generate_throw_quality_parameters(throw_parameters)

            # try to catch pokemon!
            ball_count[current_ball] -= 1
            self.inventory.get(current_ball).remove(1)
            # Take some time to throw the ball from config options
            action_delay(self.catchsim_catch_wait_min, self.catchsim_catch_wait_max)
            self.emit_event(
                'threw_pokeball',
                formatted='{throw_type}{spin_label} throw! Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'throw_type': throw_parameters['throw_type_label'],
                    'spin_label': throw_parameters['spin_label'],
                    'ball_name': self.inventory.get(current_ball).name,
                    'success_percentage': self._pct(catch_rate_by_ball[current_ball]),
                    'count_left': ball_count[current_ball]
                }
            )

            hit_pokemon = 1
            if random() >= self.catch_throw_parameters_hit_rate and not is_vip:
                hit_pokemon = 0

            response_dict = self.bot.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=throw_parameters['normalized_reticle_size'],
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=hit_pokemon,
                spin_modifier=throw_parameters['spin_modifier'],
                normalized_hit_position=throw_parameters['normalized_hit_position']
            )

            try:
                catch_pokemon_status = response_dict['responses']['CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                used_berry = False
                catch_rate_by_ball = original_catch_rate_by_ball

                # sleep according to flee_count and flee_duration config settings
                # randomly chooses a number of times to 'show' wobble animation between 1 and flee_count
                # multiplies this by flee_duration to get total sleep
                if self.catchsim_flee_count:
                    sleep((randrange(self.catchsim_flee_count)+1) * self.catchsim_flee_duration)

                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                #insert into DB
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='vanish_log'")
                result = c.fetchone()

                while True:
                    if result[0] == 1:
                        conn.execute('''INSERT INTO vanish_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''', (pokemon.name, pokemon.cp, pokemon.iv, str(encounter_id), pokemon.pokemon_id))
                    break
                else:
                    self.emit_event(
                        'vanish_log',
                        sender=self,
                        level='info',
                        formatted="vanish_log table not found, skipping log"
                    )
                    break

                self.emit_event(
                    'pokemon_vanished',
                    formatted='{} vanished!'.format(pokemon.name),
                    data={
                        'pokemon': pokemon.name,
                        'encounter_id': self.pokemon['encounter_id'],
                        'latitude': self.pokemon['latitude'],
                        'longitude': self.pokemon['longitude'],
                        'pokemon_id': pokemon.pokemon_id
                    }
                )

                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute("SELECT DISTINCT COUNT(encounter_id) FROM vanish_log WHERE dated > (SELECT dated FROM catch_log WHERE dated IN (SELECT MAX(dated) FROM catch_log))")

                result = c.fetchone()
                self.consecutive_vanishes_so_far = result[0]

                if self.rest_completed == False and self.consecutive_vanishes_so_far >= self.consecutive_vanish_limit:
                    self.start_rest()

                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                if self.rest_completed == True:
                    self.rest_completed = False
                pokemon.unique_id = response_dict['responses']['CATCH_POKEMON']['captured_pokemon_id']
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp, pokemon.iv_display, pokemon.iv)

                awards = response_dict['responses']['CATCH_POKEMON']['capture_award']
                exp_gain, candy_gain, stardust_gain = self.extract_award(awards)

                self.emit_event(
                    'pokemon_caught',
                    formatted='Captured {pokemon}! [CP {cp}] [NCP {ncp}] [Potential {iv}] [{iv_display}] ({caught_last_24_hour}/{daily_catch_limit}) [+{exp} exp] [+{stardust} stardust]',
                    data={
                        'pokemon': pokemon.name,
                        'ncp': round(pokemon.cp_percent, 2),
                        'cp': pokemon.cp,
                        'iv': pokemon.iv,
                        'iv_display': pokemon.iv_display,
                        'exp': exp_gain,
                        'stardust': stardust_gain,
                        'encounter_id': self.pokemon['encounter_id'],
                        'latitude': self.pokemon['latitude'],
                        'longitude': self.pokemon['longitude'],
                        'pokemon_id': pokemon.pokemon_id,
                        'caught_last_24_hour': self.caught_last_24_hour + 1,
                        'daily_catch_limit': self.daily_catch_limit
                    }
                )

                inventory.pokemons().add(pokemon)
                inventory.player().exp += exp_gain
                self.bot.stardust += stardust_gain
                candy = inventory.candies().get(pokemon.pokemon_id)
                candy.add(candy_gain)

                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data = {
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False


                try:
                    with self.bot.database as conn:
                        c = conn.cursor()
                        c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='catch_log'")
                    result = c.fetchone()

                    while True:
                        if result[0] == 1:
                            conn.execute('''INSERT INTO catch_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''', (pokemon.name, pokemon.cp, pokemon.iv, str(encounter_id), pokemon.pokemon_id))
                        break
                    else:
                        self.emit_event(
                            'catch_log',
                            sender=self,
                            level='info',
                            formatted="catch_log table not found, skipping log"
                        )
                        break
                    user_data_caught = os.path.join(_base_dir, 'data', 'caught-%s.json' % self.bot.config.username)
                    with open(user_data_caught, 'ab') as outfile:
                        outfile.write(str(datetime.now()))
                        json.dump({
                            'pokemon': pokemon.name,
                            'cp': pokemon.cp,
                            'iv': pokemon.iv,
                            'encounter_id': self.pokemon['encounter_id'],
                            'pokemon_id': pokemon.pokemon_id
                        }, outfile)
                        outfile.write('\n')

                    # if it is a new pokemon to our dex, simulate app animation delay
                    if exp_gain >= 500:
                        sleep (randrange(self.catchsim_newtodex_wait_min, self.catchsim_newtodex_wait_max))

                except IOError as e:
                    self.logger.info('[x] Error while opening location file: %s' % e)

            elif catch_pokemon_status == CATCH_STATUS_MISSED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='Pokeball thrown to {pokemon} missed.. trying again!',
                    data={'pokemon': pokemon.name}
                )
                # Take some time to throw the ball from config options
                action_delay(self.catchsim_catch_wait_min, self.catchsim_catch_wait_max)
                continue

            break
 def _km_walked(self):
     return inventory.player().player_stats.get("km_walked", 0)
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity
        family_name = inventory.Pokemons().name_for(family_id)

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite and not (p.unique_id == self.buddyid)]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            pokemon_id = pokemon.pokemon_id
            needed_evolution_item = inventory.pokemons().evolution_item_for(pokemon_id)
            if needed_evolution_item is not None:
                # We need a special Item to evolve this Pokemon!
                item = inventory.items().get(needed_evolution_item)
                needed = inventory.pokemons().evolution_items_needed_for(pokemon_id)
                if item.count < needed:
                    self.logger.info("To evolve a {} we need {} of {}. We have {}".format(pokemon.name, needed, item.name, item.count))
                    continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id
                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies -= inventory.pokemons().evolution_cost_for(pokemon_id)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies += 1
                    evolve.append(pokemon)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies += 1
                evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)

        for pokemon in try_upgrade:
            if pokemon.level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
                upgrade_cost = self.pokemon_upgrade_cost[i - 2]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if (not self.config_evolve_for_xp) or (family_name in self.config_evolve_for_xp_blacklist):
            xp = []
            transfer = crap
        elif self.config_evolve_for_xp_whitelist and (family_name not in self.config_evolve_for_xp_whitelist):
            xp = []
            transfer = crap
        else:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]
            transfer = [p for p in crap if p not in xp]

        return (transfer, evolve, upgrade, xp)
    def get_evolution_plan(self, family_id, family_list, keep, try_evolve, try_upgrade):
        candies = inventory.candies().get(family_id).quantity
        family_name = inventory.Pokemons().name_for(family_id)

        # All the rest is crap, for now
        crap = list(family_list)
        crap = [p for p in crap if p not in keep]
        crap = [p for p in crap if not p.in_fort and not p.is_favorite and not (p.unique_id == self.buddyid)]
        crap.sort(key=lambda p: (p.iv, p.cp), reverse=True)

        # We will gain a candy whether we choose to transfer or evolve these Pokemon
        candies += len(crap)

        evolve = []

        for pokemon in try_evolve:
            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies -= inventory.pokemons().evolution_cost_for(pokemon_id)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies -= pokemon.evolution_cost

            if candies < 0:
                continue

            if self.config_evolve_to_final:
                pokemon_id = pokemon.pokemon_id

                while inventory.pokemons().has_next_evolution(pokemon_id):
                    candies += 1
                    evolve.append(pokemon)
                    pokemon_id = inventory.pokemons().next_evolution_ids_for(pokemon_id)[0]
            else:
                candies += 1
                evolve.append(pokemon)

        upgrade = []
        upgrade_level = min(self.config_upgrade_level, inventory.player().level + 1.5, 40)

        for pokemon in try_upgrade:
            if pokemon.level >= upgrade_level:
                continue

            full_upgrade_candy_cost = 0
            full_upgrade_stardust_cost = 0

            for i in range(int(pokemon.level * 2), int(upgrade_level * 2)):
                upgrade_cost = self.pokemon_upgrade_cost[i - 2]
                full_upgrade_candy_cost += upgrade_cost[0]
                full_upgrade_stardust_cost += upgrade_cost[1]

            candies -= full_upgrade_candy_cost
            self.ongoing_stardust_count -= full_upgrade_stardust_cost

            if (candies < 0) or (self.ongoing_stardust_count < 0):
                continue

            upgrade.append(pokemon)

        if (not self.config_evolve_for_xp) or (family_name in self.config_evolve_for_xp_blacklist):
            xp = []
            transfer = crap
        elif self.config_evolve_for_xp_whitelist and (family_name not in self.config_evolve_for_xp_whitelist):
            xp = []
            transfer = crap
        else:
            # Compute how many crap we should keep if we want to batch evolve them for xp
            lowest_evolution_cost = inventory.pokemons().evolution_cost_for(family_id)

            # transfer + keep_for_xp = len(crap)
            # leftover_candies = candies - len(crap) + transfer * 1
            # keep_for_xp = (leftover_candies - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - len(crap) + transfer - 1) / (lowest_evolution_cost - 1)
            # keep_for_xp = (candies - keep_for_xp - 1) / (lowest_evolution_cost - 1)

            if (candies > 0) and lowest_evolution_cost:
                keep_for_xp = int((candies - 1) / lowest_evolution_cost)
            else:
                keep_for_xp = 0

            xp = [p for p in crap if p.has_next_evolution() and p.evolution_cost == lowest_evolution_cost][:keep_for_xp]
            transfer = [p for p in crap if p not in xp]

        return (transfer, evolve, upgrade, xp)
    def _hatch_eggs(self):
        request = self.bot.api.create_request()
        request.get_hatched_eggs()
        response_dict = request.call()

        try:
            result = reduce(dict.__getitem__,
                            ["responses", "GET_HATCHED_EGGS"], response_dict)
        except KeyError:
            return WorkerResult.ERROR
        pokemon_ids = []
        if 'pokemon_id' in result:
            pokemon_ids = [id for id in result['pokemon_id']]
        stardust = result.get('stardust_awarded', [])
        candy = result.get('candy_awarded', [])
        xp = result.get('experience_awarded', [])
        sleep(self.hatching_animation_delay)
        try:
            pokemon_data = self._check_inventory(pokemon_ids)
            pokemon_list = [inventory.Pokemon(p) for p in pokemon_data]
            for pokemon in pokemon_list:
                inventory.pokemons().remove(pokemon.unique_id)
                inventory.pokemons().add(pokemon)
        except:
            pokemon_data = []
        if not pokemon_ids or not pokemon_data:
            self.emit_event('egg_hatched_fail',
                            formatted="Error trying to hatch egg.")
            return False

        for i in range(len(pokemon_list)):
            pokemon = pokemon_list[i]
            msg = "Egg hatched with a {name} (CP {cp} - NCP {ncp} - IV {iv_ads} {iv_pct}), {exp} exp, {stardust} stardust and {candy} candies."
            self.emit_event('egg_hatched',
                            formatted=msg,
                            data={
                                'name': pokemon.name,
                                'cp': str(int(pokemon.cp)),
                                'ncp': str(round(pokemon.cp_percent, 2)),
                                'iv_ads': str(pokemon.iv_display),
                                'iv_pct': str(pokemon.iv),
                                'exp': str(xp[i]),
                                'stardust': str(stardust[i]),
                                'candy': str(candy[i])
                            })
            # hatching egg gets exp too!
            inventory.player().exp += xp[i]
            self.bot.stardust += stardust[i]

            with self.bot.database as conn:
                c = conn.cursor()
                c.execute(
                    "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='eggs_hatched_log'"
                )
            result = c.fetchone()
            while True:
                if result[0] == 1:
                    conn.execute(
                        '''INSERT INTO eggs_hatched_log (pokemon, cp, iv, pokemon_id) VALUES (?, ?, ?, ?)''',
                        (pokemon.name, pokemon.cp, pokemon.iv,
                         pokemon.pokemon_id))
                    break
                else:
                    self.emit_event(
                        'eggs_hatched_log',
                        sender=self,
                        level='info',
                        formatted=
                        "eggs_hatched_log table not found, skipping log")
                    break

        self.bot.metrics.hatched_eggs(len(pokemon_list))
        return True
Exemple #41
0
    def _hatch_eggs(self):
        response_dict = self.bot.api.get_hatched_eggs()
        try:
            result = reduce(dict.__getitem__, ["responses", "GET_HATCHED_EGGS"], response_dict)
        except KeyError:
            return WorkerResult.ERROR
        pokemon_ids = []
        if 'pokemon_id' in result:
            pokemon_ids = [id for id in result['pokemon_id']]
        stardust = result.get('stardust_awarded', [])
        candy = result.get('candy_awarded', [])
        xp = result.get('experience_awarded', [])
        sleep(self.hatching_animation_delay)
        try:
            pokemon_data = self._check_inventory(pokemon_ids)
            pokemon_list = [inventory.Pokemon(p) for p in pokemon_data]
            for pokemon in pokemon_list:
                inventory.pokemons().remove(pokemon.unique_id)
                inventory.pokemons().add(pokemon)
        except:
            pokemon_data = []
        if not pokemon_ids or not pokemon_data:
            self.emit_event(
                'egg_hatched_fail',
                formatted= "Error trying to hatch egg."
            )
            return False

        for i in range(len(pokemon_list)):
            pokemon = pokemon_list[i]
            msg = "Egg hatched with a {name} (CP {cp} - NCP {ncp} - IV {iv_ads} {iv_pct}), {exp} exp, {stardust} stardust and {candy} candies."
            self.emit_event(
                'egg_hatched',
                formatted=msg,
                data={
                    'name': pokemon.name,
                    'cp': pokemon.cp,
                    'ncp': round(pokemon.cp_percent, 2),
                    'iv_ads': pokemon.iv_display,
                    'iv_pct': pokemon.iv,
                    'exp': xp[i],
                    'stardust': stardust[i],
                    'candy': candy[i]
                }
            )
            # hatching egg gets exp too!
            inventory.player().exp += xp[i]
            self.bot.stardust += stardust[i]

            with self.bot.database as conn:
                c = conn.cursor()
                c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='eggs_hatched_log'")
            result = c.fetchone()
            while True:
                if result[0] == 1:
                    conn.execute('''INSERT INTO eggs_hatched_log (pokemon, cp, iv, pokemon_id) VALUES (?, ?, ?, ?)''', (pokemon.name, pokemon.cp, pokemon.iv, pokemon.pokemon_id))
                    break
                else:
                    self.emit_event(
                        'eggs_hatched_log',
                        sender=self,
                        level='info',
                        formatted="eggs_hatched_log table not found, skipping log"
                    )
                    break

        self.bot.metrics.hatched_eggs(len(pokemon_list))
        return True
Exemple #42
0
    def _do_catch(self,
                  pokemon,
                  encounter_id,
                  catch_rate_by_ball,
                  is_vip=False):
        # settings that may be exposed at some point
        """

        :type pokemon: Pokemon
        """
        berry_count = self.inventory.get(ITEM_RAZZBERRY).count
        ball_count = {}
        for ball_id in [ITEM_POKEBALL, ITEM_GREATBALL, ITEM_ULTRABALL]:
            ball_count[ball_id] = self.inventory.get(ball_id).count

        # use `min_ultraball_to_keep` from config if is not None
        min_ultraball_to_keep = ball_count[ITEM_ULTRABALL]
        if self.min_ultraball_to_keep is not None and self.min_ultraball_to_keep >= 0:
            min_ultraball_to_keep = self.min_ultraball_to_keep

        berry_id = ITEM_RAZZBERRY
        maximum_ball = ITEM_GREATBALL if ball_count[
            ITEM_ULTRABALL] < min_ultraball_to_keep else ITEM_ULTRABALL
        ideal_catch_rate_before_throw = self.vip_berry_threshold if is_vip else self.berry_threshold

        used_berry = False
        original_catch_rate_by_ball = catch_rate_by_ball
        while True:

            # find lowest available ball
            current_ball = ITEM_POKEBALL
            while ball_count[current_ball] == 0 and current_ball < maximum_ball:
                current_ball += 1
            if ball_count[current_ball] == 0:
                self.emit_event('no_pokeballs',
                                formatted='No pokeballs left! Fleeing...')
                return WorkerResult.ERROR

            # check future ball count
            num_next_balls = 0
            next_ball = current_ball
            while next_ball < maximum_ball:
                next_ball += 1
                num_next_balls += ball_count[next_ball]

            # check if we've got berries to spare
            berries_to_spare = berry_count > 0 if is_vip else berry_count > num_next_balls + 30

            # use a berry if we are under our ideal rate and have berries to spare
            changed_ball = False
            if catch_rate_by_ball[
                    current_ball] < ideal_catch_rate_before_throw and berries_to_spare and not used_berry:
                new_catch_rate_by_ball = self._use_berry(
                    berry_id, berry_count, encounter_id, catch_rate_by_ball,
                    current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # pick the best ball to catch with
            best_ball = current_ball
            while best_ball < maximum_ball:
                best_ball += 1
                if catch_rate_by_ball[
                        current_ball] < ideal_catch_rate_before_throw and ball_count[
                            best_ball] > 0:
                    # if current ball chance to catch is under our ideal rate, and player has better ball - then use it
                    current_ball = best_ball
                    changed_ball = True

            # if the rate is still low and we didn't throw a berry before, throw one
            if catch_rate_by_ball[
                    current_ball] < ideal_catch_rate_before_throw and berry_count > 0 and not used_berry:
                new_catch_rate_by_ball = self._use_berry(
                    berry_id, berry_count, encounter_id, catch_rate_by_ball,
                    current_ball)
                if new_catch_rate_by_ball != catch_rate_by_ball:
                    catch_rate_by_ball = new_catch_rate_by_ball
                    self.inventory.get(ITEM_RAZZBERRY).remove(1)
                    berry_count -= 1
                    used_berry = True

            # If we change ball then wait to simulate user selecting it
            if changed_ball:
                action_delay(self.catchsim_changeball_wait_min,
                             self.catchsim_changeball_wait_max)

            # Randomize the quality of the throw
            # Default structure
            throw_parameters = {
                'normalized_reticle_size': 1.950,
                'spin_modifier': 1.0,
                'normalized_hit_position': 1.0,
                'throw_type_label': 'Excellent'
            }
            self.generate_spin_parameter(throw_parameters)
            self.generate_throw_quality_parameters(throw_parameters)

            # try to catch pokemon!
            ball_count[current_ball] -= 1
            self.inventory.get(current_ball).remove(1)
            # Take some time to throw the ball from config options
            action_delay(self.catchsim_catch_wait_min,
                         self.catchsim_catch_wait_max)
            self.emit_event(
                'threw_pokeball',
                formatted=
                '{throw_type}{spin_label} throw! Used {ball_name}, with chance {success_percentage} ({count_left} left)',
                data={
                    'throw_type':
                    throw_parameters['throw_type_label'],
                    'spin_label':
                    throw_parameters['spin_label'],
                    'ball_name':
                    self.inventory.get(current_ball).name,
                    'success_percentage':
                    self._pct(catch_rate_by_ball[current_ball]),
                    'count_left':
                    ball_count[current_ball]
                })

            hit_pokemon = 1
            if random() >= self.catch_throw_parameters_hit_rate and not is_vip:
                hit_pokemon = 0

            response_dict = self.bot.api.catch_pokemon(
                encounter_id=encounter_id,
                pokeball=current_ball,
                normalized_reticle_size=throw_parameters[
                    'normalized_reticle_size'],
                spawn_point_id=self.spawn_point_guid,
                hit_pokemon=hit_pokemon,
                spin_modifier=throw_parameters['spin_modifier'],
                normalized_hit_position=throw_parameters[
                    'normalized_hit_position'])

            try:
                catch_pokemon_status = response_dict['responses'][
                    'CATCH_POKEMON']['status']
            except KeyError:
                break

            # retry failed pokemon
            if catch_pokemon_status == CATCH_STATUS_FAILED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted='{pokemon} capture failed.. trying again!',
                    data={'pokemon': pokemon.name})
                used_berry = False
                catch_rate_by_ball = original_catch_rate_by_ball

                # sleep according to flee_count and flee_duration config settings
                # randomly chooses a number of times to 'show' wobble animation between 1 and flee_count
                # multiplies this by flee_duration to get total sleep
                if self.catchsim_flee_count:
                    sleep((randrange(self.catchsim_flee_count) + 1) *
                          self.catchsim_flee_duration)

                continue

            # abandon if pokemon vanished
            elif catch_pokemon_status == CATCH_STATUS_VANISHED:
                #insert into DB
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='vanish_log'"
                    )
                result = c.fetchone()

                while True:
                    if result[0] == 1:
                        conn.execute(
                            '''INSERT INTO vanish_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''',
                            (pokemon.name, pokemon.cp, pokemon.iv,
                             str(encounter_id), pokemon.pokemon_id))
                    break
                else:
                    self.emit_event(
                        'vanish_log',
                        sender=self,
                        level='info',
                        formatted="vanish_log table not found, skipping log")
                    break

                self.emit_event('pokemon_vanished',
                                formatted='{} vanished!'.format(pokemon.name),
                                data={
                                    'pokemon': pokemon.name,
                                    'encounter_id':
                                    self.pokemon['encounter_id'],
                                    'latitude': self.pokemon['latitude'],
                                    'longitude': self.pokemon['longitude'],
                                    'pokemon_id': pokemon.pokemon_id
                                })

                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT DISTINCT COUNT(encounter_id) FROM vanish_log WHERE dated > (SELECT dated FROM catch_log WHERE dated IN (SELECT MAX(dated) FROM catch_log))"
                    )

                result = c.fetchone()
                self.consecutive_vanishes_so_far = result[0]

                if self.rest_completed == False and self.consecutive_vanishes_so_far >= self.consecutive_vanish_limit:
                    self.start_rest()

                if self._pct(catch_rate_by_ball[current_ball]) == 100:
                    self.bot.softban = True

            # pokemon caught!
            elif catch_pokemon_status == CATCH_STATUS_SUCCESS:
                if self.rest_completed == True:
                    self.rest_completed = False
                pokemon.unique_id = response_dict['responses'][
                    'CATCH_POKEMON']['captured_pokemon_id']
                self.bot.metrics.captured_pokemon(pokemon.name, pokemon.cp,
                                                  pokemon.iv_display,
                                                  pokemon.iv)

                awards = response_dict['responses']['CATCH_POKEMON'][
                    'capture_award']
                exp_gain, candy_gain, stardust_gain = self.extract_award(
                    awards)
                with self.bot.database as conn:
                    c = conn.cursor()
                    c.execute(
                        "SELECT DISTINCT COUNT(encounter_id) FROM catch_log WHERE dated >= datetime('now','-1 day')"
                    )

                result = c.fetchone()

                if is_vip:
                    self.emit_event(
                        'pokemon_vip_caught',
                        formatted=
                        'Vip Captured {pokemon}! (CP: {cp} IV: {iv} {iv_display} NCP: {ncp}) Catch Limit: ({caught_last_24_hour}/{daily_catch_limit}) +{exp} exp +{stardust} stardust',
                        data={
                            'pokemon': pokemon.name,
                            'ncp': str(round(pokemon.cp_percent, 2)),
                            'cp': str(int(pokemon.cp)),
                            'iv': str(pokemon.iv),
                            'iv_display': str(pokemon.iv_display),
                            'exp': str(exp_gain),
                            'stardust': stardust_gain,
                            'encounter_id': str(self.pokemon['encounter_id']),
                            'latitude': str(self.pokemon['latitude']),
                            'longitude': str(self.pokemon['longitude']),
                            'pokemon_id': str(pokemon.pokemon_id),
                            'caught_last_24_hour': str(result[0]),
                            'daily_catch_limit': str(self.daily_catch_limit)
                        })

                else:
                    self.emit_event(
                        'pokemon_caught',
                        formatted=
                        'Captured {pokemon}! (CP: {cp} IV: {iv} {iv_display} NCP: {ncp}) Catch Limit: ({caught_last_24_hour}/{daily_catch_limit}) +{exp} exp +{stardust} stardust',
                        data={
                            'pokemon': pokemon.name,
                            'ncp': str(round(pokemon.cp_percent, 2)),
                            'cp': str(int(pokemon.cp)),
                            'iv': str(pokemon.iv),
                            'iv_display': str(pokemon.iv_display),
                            'exp': str(exp_gain),
                            'stardust': stardust_gain,
                            'encounter_id': str(self.pokemon['encounter_id']),
                            'latitude': str(self.pokemon['latitude']),
                            'longitude': str(self.pokemon['longitude']),
                            'pokemon_id': str(pokemon.pokemon_id),
                            'caught_last_24_hour': str(result[0]),
                            'daily_catch_limit': str(self.daily_catch_limit)
                        })

                inventory.pokemons().add(pokemon)
                inventory.player().exp += exp_gain
                self.bot.stardust += stardust_gain
                candy = inventory.candies().get(pokemon.pokemon_id)
                candy.add(candy_gain)

                self.emit_event(
                    'gained_candy',
                    formatted='You now have {quantity} {type} candy!',
                    data={
                        'quantity': candy.quantity,
                        'type': candy.type,
                    },
                )

                self.bot.softban = False

                try:
                    with self.bot.database as conn:
                        c = conn.cursor()
                        c.execute(
                            "SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='catch_log'"
                        )
                    result = c.fetchone()

                    while True:
                        if result[0] == 1:
                            conn.execute(
                                '''INSERT INTO catch_log (pokemon, cp, iv, encounter_id, pokemon_id) VALUES (?, ?, ?, ?, ?)''',
                                (pokemon.name, pokemon.cp, pokemon.iv,
                                 str(encounter_id), pokemon.pokemon_id))
                        break
                    else:
                        self.emit_event(
                            'catch_log',
                            sender=self,
                            level='info',
                            formatted="catch_log table not found, skipping log"
                        )
                        break
                    user_data_caught = os.path.join(
                        _base_dir, 'data',
                        'caught-%s.json' % self.bot.config.username)
                    with open(user_data_caught, 'ab') as outfile:
                        json.dump(
                            OrderedDict({
                                'datetime':
                                str(datetime.now()),
                                'pokemon':
                                pokemon.name,
                                'cp':
                                pokemon.cp,
                                'iv':
                                pokemon.iv,
                                'encounter_id':
                                self.pokemon['encounter_id'],
                                'pokemon_id':
                                pokemon.pokemon_id,
                                'latitude':
                                self.pokemon['latitude'],
                                'longitude':
                                self.pokemon['longitude']
                            }), outfile)
                        outfile.write('\n')

                    # if it is a new pokemon to our dex, simulate app animation delay
                    if exp_gain >= 500:
                        sleep(
                            randrange(self.catchsim_newtodex_wait_min,
                                      self.catchsim_newtodex_wait_max))

                except IOError as e:
                    self.logger.info(
                        '[x] Error while opening location file: %s' % e)

            elif catch_pokemon_status == CATCH_STATUS_MISSED:
                self.emit_event(
                    'pokemon_capture_failed',
                    formatted=
                    'Pokeball thrown to {pokemon} missed.. trying again!',
                    data={'pokemon': pokemon.name})
                # Take some time to throw the ball from config options
                action_delay(self.catchsim_catch_wait_min,
                             self.catchsim_catch_wait_max)
                continue

            break
 def should_run(self):
     # Check if we have any Pokemons and are level > 5 and have selected a team
     return player()._level >= 5 and len(self.pokemons) > 0 and self.team > TEAM_NOT_SET