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
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 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})
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})
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
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()
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
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
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)
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
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]
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
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
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
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