From 8d788bff223cd6b8745016d166c193051e7cbf60 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Sun, 14 Aug 2016 21:45:13 +0200 Subject: [PATCH 01/11] Removed every call to the old inventory Added some messages to monitor item inventory Added some methods needed on the new inventory --- pokecli.py | 7 + pokemongo_bot/__init__.py | 213 +++++------------- pokemongo_bot/base_task.py | 7 + .../cell_workers/pokemon_catch_worker.py | 2 +- .../cell_workers/pokemon_optimizer.py | 1 - pokemongo_bot/cell_workers/recycle_items.py | 17 +- .../cell_workers/transfer_pokemon.py | 3 +- .../cell_workers/update_live_stats.py | 3 +- pokemongo_bot/inventory.py | 71 ++++-- pokemongo_bot/services/item_recycle_worker.py | 1 + 10 files changed, 138 insertions(+), 187 deletions(-) diff --git a/pokecli.py b/pokecli.py index 064c87c9ba..896171c90d 100644 --- a/pokecli.py +++ b/pokecli.py @@ -39,6 +39,7 @@ from pgoapi.exceptions import NotLoggedInException, ServerSideRequestThrottlingException, ServerBusyOrOfflineException from geopy.exc import GeocoderQuotaExceeded +from pokemongo_bot import inventory from pokemongo_bot import PokemonGoBot, TreeConfigBuilder from pokemongo_bot.base_dir import _base_dir from pokemongo_bot.health_record import BotEvent @@ -188,6 +189,12 @@ def report_summary(bot): metrics.num_evolutions(), metrics.num_new_mons())) logger.info('Threw {} pokeball{}'.format(metrics.num_throws(), '' if metrics.num_throws() == 1 else 's')) logger.info('Earned {} Stardust'.format(metrics.earned_dust())) + print("##############################") + print("# #") + print("# Refreshed the inventory #") + print("# {} times #".format(inventory._inventory.refresh_count)) + print("# #") + print("##############################") logger.info('') if metrics.highest_cp is not None: logger.info('Highest CP Pokemon: {}'.format(metrics.highest_cp['desc'])) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index ff5257c043..868d237e27 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -85,6 +85,8 @@ def start(self): self._setup_logging() self._setup_api() self._load_recent_forts() + init_inventory(self) + self._print_character_info() random.seed() @@ -702,10 +704,9 @@ def _setup_api(self): self.login() # chain subrequests (methods) into one RPC call - self._print_character_info() self.api.activate_signature(self.get_encryption_lib()) self.logger.info('') - self.update_inventory() + #self.update_inventory() # send empty map_cells and then our position self.update_web_location() @@ -735,7 +736,7 @@ def _print_character_info(self): pokecoins = '0' stardust = '0' - items_stock = self.current_inventory() + items_inventory = inventory.items() if 'amount' in player['currencies'][0]: pokecoins = player['currencies'][0]['amount'] @@ -743,17 +744,17 @@ def _print_character_info(self): stardust = player['currencies'][1]['amount'] self.logger.info('') self.logger.info('--- {username} ---'.format(**player)) - self.get_player_info() + #self.get_player_info() self.logger.info( 'Pokemon Bag: {}/{}'.format( - self.get_inventory_count('pokemon'), - player['max_pokemon_storage'] + inventory.Pokemons.get_space_used(), + inventory.get_pokemon_inventory_size() ) ) self.logger.info( 'Items: {}/{}'.format( - self.get_inventory_count('item'), - player['max_item_storage'] + inventory.Items.get_space_used(), + inventory.get_item_inventory_size() ) ) self.logger.info( @@ -762,116 +763,41 @@ def _print_character_info(self): ) # Items Output self.logger.info( - 'PokeBalls: ' + str(items_stock[1]) + - ' | GreatBalls: ' + str(items_stock[2]) + - ' | UltraBalls: ' + str(items_stock[3]) + - ' | MasterBalls: ' + str(items_stock[4])) + 'PokeBalls: ' + str(items_inventory.get(1).count) + + ' | GreatBalls: ' + str(items_inventory.get(2).count) + + ' | UltraBalls: ' + str(items_inventory.get(3).count) + + ' | MasterBalls: ' + str(items_inventory.get(4).count)) self.logger.info( - 'RazzBerries: ' + str(items_stock[701]) + - ' | BlukBerries: ' + str(items_stock[702]) + - ' | NanabBerries: ' + str(items_stock[703])) + 'RazzBerries: ' + str(items_inventory.get(701).count) + + ' | BlukBerries: ' + str(items_inventory.get(702).count) + + ' | NanabBerries: ' + str(items_inventory.get(703).count)) self.logger.info( - 'LuckyEgg: ' + str(items_stock[301]) + - ' | Incubator: ' + str(items_stock[902]) + - ' | TroyDisk: ' + str(items_stock[501])) + 'LuckyEgg: ' + str(items_inventory.get(301).count) + + ' | Incubator: ' + str(items_inventory.get(902).count) + + ' | TroyDisk: ' + str(items_inventory.get(501).count)) self.logger.info( - 'Potion: ' + str(items_stock[101]) + - ' | SuperPotion: ' + str(items_stock[102]) + - ' | HyperPotion: ' + str(items_stock[103]) + - ' | MaxPotion: ' + str(items_stock[104])) + 'Potion: ' + str(items_inventory.get(101).count) + + ' | SuperPotion: ' + str(items_inventory.get(102).count) + + ' | HyperPotion: ' + str(items_inventory.get(103).count) + + ' | MaxPotion: ' + str(items_inventory.get(104).count)) self.logger.info( - 'Incense: ' + str(items_stock[401]) + - ' | IncenseSpicy: ' + str(items_stock[402]) + - ' | IncenseCool: ' + str(items_stock[403])) + 'Incense: ' + str(items_inventory.get(401).count) + + ' | IncenseSpicy: ' + str(items_inventory.get(402).count) + + ' | IncenseCool: ' + str(items_inventory.get(403).count)) self.logger.info( - 'Revive: ' + str(items_stock[201]) + - ' | MaxRevive: ' + str(items_stock[202])) + 'Revive: ' + str(items_inventory.get(201).count) + + ' | MaxRevive: ' + str(items_inventory.get(202).count)) self.logger.info('') def use_lucky_egg(self): return self.api.use_item_xp_boost(item_id=301) - def get_inventory(self): - if self.latest_inventory is None: - self.latest_inventory = self.api.get_inventory() - return self.latest_inventory - - def update_inventory(self): - # TODO: transition to using this inventory class everywhere - init_inventory(self) - response = self.get_inventory() - self.inventory = list() - inventory_items = response.get('responses', {}).get('GET_INVENTORY', {}).get( - 'inventory_delta', {}).get('inventory_items', {}) - if inventory_items: - for item in inventory_items: - item_info = item.get('inventory_item_data', {}).get('item', {}) - if {"item_id", "count"}.issubset(set(item_info.keys())): - self.inventory.append(item['inventory_item_data']['item']) - - def current_inventory(self): - inventory_req = self.get_inventory() - inventory_dict = inventory_req['responses']['GET_INVENTORY'][ - 'inventory_delta']['inventory_items'] - - user_web_inventory = os.path.join(_base_dir, 'web', 'inventory-%s.json' % self.config.username) - - with open(user_web_inventory, 'w') as outfile: - json.dump(inventory_dict, outfile) - - # get player items stock - # ---------------------- - items_stock = {x.value: 0 for x in list(Item)} - - for item in inventory_dict: - item_dict = item.get('inventory_item_data', {}).get('item', {}) - item_count = item_dict.get('count') - item_id = item_dict.get('item_id') - - if item_count and item_id: - if item_id in items_stock: - items_stock[item_id] = item_count - return items_stock - - def item_inventory_count(self, id): - inventory_req = self.get_inventory() - inventory_dict = inventory_req['responses'][ - 'GET_INVENTORY']['inventory_delta']['inventory_items'] - - if id == 'all': - return self._all_items_inventory_count(inventory_dict) - else: - return self._item_inventory_count_per_id(id, inventory_dict) - - def _item_inventory_count_per_id(self, id, inventory_dict): - item_count = 0 - - for item in inventory_dict: - item_dict = item.get('inventory_item_data', {}).get('item', {}) - item_id = item_dict.get('item_id', False) - item_count = item_dict.get('count', False) - if item_id == int(id) and item_count: - return item_count - return 0 - - def _all_items_inventory_count(self, inventory_dict): - item_count_dict = {} - - for item in inventory_dict: - item_dict = item.get('inventory_item_data', {}).get('item', {}) - item_id = item_dict.get('item_id', False) - item_count = item_dict.get('count', False) - if item_id and item_count: - item_count_dict[item_id] = item_count - - return item_count_dict - def _set_starting_position(self): self.event_manager.emit( @@ -1021,63 +947,32 @@ def update_web_location_worker(self): self.web_update_queue.get() self.update_web_location() - def get_inventory_count(self, what): - response_dict = self.get_inventory() - inventory_items = response_dict.get('responses', {}).get('GET_INVENTORY', {}).get( - 'inventory_delta', {}).get('inventory_items', {}) - if inventory_items: - pokecount = 0 - itemcount = 1 - for item in inventory_items: - if 'inventory_item_data' in item: - if 'pokemon_data' in item['inventory_item_data']: - pokecount += 1 - itemcount += item['inventory_item_data'].get('item', {}).get('count', 0) - if 'pokemon' in what: - return pokecount - if 'item' in what: - return itemcount - return '0' - - def get_player_info(self): - response_dict = self.get_inventory() - inventory_items = response_dict.get('responses', {}).get('GET_INVENTORY', {}).get( - 'inventory_delta', {}).get('inventory_items', {}) - if inventory_items: - pokecount = 0 - itemcount = 1 - for item in inventory_items: - # print('item {}'.format(item)) - playerdata = item.get('inventory_item_data', {}).get('player_stats') - if playerdata: - nextlvlxp = (int(playerdata.get('next_level_xp', 0)) - int(playerdata.get('experience', 0))) - - if 'level' in playerdata and 'experience' in playerdata: - self.logger.info( - 'Level: {level}'.format( - **playerdata) + - ' (Next Level: {} XP)'.format( - nextlvlxp) + - ' (Total: {experience} XP)' - ''.format(**playerdata)) - - if 'pokemons_captured' in playerdata and 'poke_stop_visits' in playerdata: - self.logger.info( - 'Pokemon Captured: ' - '{pokemons_captured}'.format( - **playerdata) + - ' | Pokestops Visited: ' - '{poke_stop_visits}'.format( - **playerdata)) - - def has_space_for_loot(self): - number_of_things_gained_by_stop = 5 - enough_space = ( - self.get_inventory_count('item') < - self._player['max_item_storage'] - number_of_things_gained_by_stop - ) - - return enough_space + # def get_player_info(self): + # pokecount = 0 + # itemcount = 1 + # for item in inventory.items().all(): + # # print('item {}'.format(item)) + # playerdata = item.get('inventory_item_data', {}).get('player_stats') + # if playerdata: + # nextlvlxp = (int(playerdata.get('next_level_xp', 0)) - int(playerdata.get('experience', 0))) + # + # if 'level' in playerdata and 'experience' in playerdata: + # self.logger.info( + # 'Level: {level}'.format( + # **playerdata) + + # ' (Next Level: {} XP)'.format( + # nextlvlxp) + + # ' (Total: {experience} XP)' + # ''.format(**playerdata)) + # + # if 'pokemons_captured' in playerdata and 'poke_stop_visits' in playerdata: + # self.logger.info( + # 'Pokemon Captured: ' + # '{pokemons_captured}'.format( + # **playerdata) + + # ' | Pokestops Visited: ' + # '{poke_stop_visits}'.format( + # **playerdata)) def get_forts(self, order_by_distance=False): forts = [fort diff --git a/pokemongo_bot/base_task.py b/pokemongo_bot/base_task.py index 1b610d31aa..e643ee7c07 100644 --- a/pokemongo_bot/base_task.py +++ b/pokemongo_bot/base_task.py @@ -5,6 +5,13 @@ class BaseTask(object): TASK_API_VERSION = 1 def __init__(self, bot, config): + """ + + :param bot: + :type bot: pokemongo_bot.PokemonGoBot + :param config: + :return: + """ self.bot = bot self.config = config self._validate_work_exists() diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index d30718eaea..09c9e594c0 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -395,7 +395,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): ) # We could refresh here too, but adding 3 saves a inventory request - candy = inventory.candies(True).get(pokemon.pokemon_id) + candy = inventory.candies().get(pokemon.pokemon_id) self.emit_event( 'gained_candy', formatted='You now have {quantity} {type} candy!', diff --git a/pokemongo_bot/cell_workers/pokemon_optimizer.py b/pokemongo_bot/cell_workers/pokemon_optimizer.py index 81f78ddf33..f2fdaade17 100644 --- a/pokemongo_bot/cell_workers/pokemon_optimizer.py +++ b/pokemongo_bot/cell_workers/pokemon_optimizer.py @@ -54,7 +54,6 @@ def work(self): evo_all = evo_all_best + evo_all_crap self.apply_optimization(transfer_all, evo_all) - inventory.refresh_inventory() return WorkerResult.SUCCESS diff --git a/pokemongo_bot/cell_workers/recycle_items.py b/pokemongo_bot/cell_workers/recycle_items.py index 79c9e9efc4..814b8bb694 100644 --- a/pokemongo_bot/cell_workers/recycle_items.py +++ b/pokemongo_bot/cell_workers/recycle_items.py @@ -40,6 +40,15 @@ class RecycleItems(BaseTask): """ SUPPORTED_TASK_API_VERSION = 1 + def __init__(self, bot, config): + """ + + :param bot: + :type bot: pokemongo_bot.PokemonGoBot + :param config: + :return: + """ + super(RecycleItems, self).__init__(bot, config) def initialize(self): self.items_filter = self.config.get('item_filter', {}) @@ -78,11 +87,10 @@ def work(self): :rtype: WorkerResult """ - # TODO: Use new inventory everywhere and then remove this inventory update - inventory.refresh_inventory() - worker_result = WorkerResult.SUCCESS if self.should_run(): + print("Inventory BEFORE item recycling : ") + self.bot._print_character_info() for item_in_inventory in inventory.items().all(): @@ -92,7 +100,8 @@ def work(self): # If at any recycling process call we got an error, we consider that the result of this task is error too. if ItemRecycler(self.bot, item_in_inventory, self.get_amount_to_recycle(item_in_inventory)).work() == WorkerResult.ERROR: worker_result = WorkerResult.ERROR - + print("Inventory AFTER item recycling : ") + self.bot._print_character_info() return worker_result def item_should_be_recycled(self, item): diff --git a/pokemongo_bot/cell_workers/transfer_pokemon.py b/pokemongo_bot/cell_workers/transfer_pokemon.py index f9a6da6fc4..4c659bd8c0 100644 --- a/pokemongo_bot/cell_workers/transfer_pokemon.py +++ b/pokemongo_bot/cell_workers/transfer_pokemon.py @@ -66,8 +66,7 @@ def work(self): def _release_pokemon_get_groups(self): pokemon_groups = {} - # TODO: Use new inventory everywhere and then remove the inventory update - for pokemon in inventory.pokemons(True).all(): + for pokemon in inventory.pokemons().all(): if pokemon.in_fort or pokemon.is_favorite: continue diff --git a/pokemongo_bot/cell_workers/update_live_stats.py b/pokemongo_bot/cell_workers/update_live_stats.py index e51253edc5..fd1459e18f 100644 --- a/pokemongo_bot/cell_workers/update_live_stats.py +++ b/pokemongo_bot/cell_workers/update_live_stats.py @@ -262,7 +262,8 @@ def _get_player_stats(self): :return: The player stats object. :rtype: dict """ - inventory_items = self.bot.get_inventory() \ + # TODO : find a better solution than calling the api + inventory_items = self.bot.api.get_inventory() \ .get('responses', {}) \ .get('GET_INVENTORY', {}) \ .get('inventory_delta', {}) \ diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index c59ba4b046..7dee23b59a 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -216,7 +216,7 @@ def get_space_left(cls): :return: The space left in item inventory. 0 if the player has more item than his item inventory can carry. :rtype: int """ - _inventory.retrieve_item_inventory_size() + _inventory.retrieve_inventories_size() space_left = _inventory.item_inventory_size - cls.get_space_used() # Space left should never be negative. Returning 0 if the computed value is negative. return space_left if space_left >= 0 else 0 @@ -259,6 +259,26 @@ def process_static_data(cls, data): return data + @classmethod + def get_space_used(cls): + """ + Counts the space used in pokemon inventory. + :return: The space used in pokemon inventory. + :rtype: int + """ + return len(_inventory.pokemons.all()) + + @classmethod + def get_space_left(cls): + """ + Compute the space left in pokemon inventory. + :return: The space left in pokemon inventory. + :rtype: int + """ + _inventory.retrieve_inventories_size() + space_left = _inventory.pokemon_inventory_size - cls.get_space_used() + return space_left + @classmethod def data_for(cls, pokemon_id): # type: (int) -> PokemonInfo @@ -304,7 +324,7 @@ def all(self): def add(self, pokemon): if pokemon.id <= 0: - raise ValueError("Can't add a pokemin whitout id") + raise ValueError("Can't add a pokemon whitout id") if pokemon.id in self._data: raise ValueError("Pokemon already present in the inventory") self._data[pokemon.id] = pokemon @@ -1059,14 +1079,21 @@ def __init__(self, bot): self.candy = Candies() self.items = Items() self.pokemons = Pokemons() + self.refresh_count = 0 self.refresh() self.item_inventory_size = None + self.pokemon_inventory_size = None def refresh(self): - # TODO: it would be better if this class was used for all - # inventory management. For now, I'm just clearing the old inventory field - self.bot.latest_inventory = None - inventory = self.bot.get_inventory()['responses']['GET_INVENTORY']['inventory_delta']['inventory_items'] + self.refresh_count += 1 + print("##############################") + print("# #") + print("# Refreshing the inventory #") + print("# Nr : {} #".format(self.refresh_count)) + print("# #") + print("##############################") + inventory = self.bot.api.get_inventory() + inventory = inventory['responses']['GET_INVENTORY']['inventory_delta']['inventory_items'] for i in (self.pokedex, self.candy, self.items, self.pokemons): i.refresh(inventory) @@ -1074,15 +1101,17 @@ def refresh(self): with open(user_web_inventory, 'w') as outfile: json.dump(inventory, outfile) - def retrieve_item_inventory_size(self): + def retrieve_inventories_size(self): """ Retrieves the item inventory size :return: Nothing. :rtype: None """ - # TODO: Force update of _item_inventory_size if the player upgrades its size - if self.item_inventory_size is None: - self.item_inventory_size = self.bot.api.get_player()['responses']['GET_PLAYER']['player_data']['max_item_storage'] + # TODO: Force update of it if the player upgrades its size + if self.item_inventory_size is None or self.pokemon_inventory_size is None: + player_data = self.bot.api.get_player()['responses']['GET_PLAYER']['player_data'] + self.item_inventory_size = player_data['max_item_storage'] + self.pokemon_inventory_size = player_data['max_pokemon_storage'] # @@ -1177,39 +1206,43 @@ def get_item_inventory_size(): :return: Item inventory size. :rtype: int """ - _inventory.retrieve_item_inventory_size() + _inventory.retrieve_inventories_size() return _inventory.item_inventory_size +def get_pokemon_inventory_size(): + """ + Access to the Item inventory size. + :return: Item inventory size. + :rtype: int + """ + _inventory.retrieve_inventories_size() + return _inventory.pokemon_inventory_size + def pokedex(): """ :return: :rtype: Pokedex """ + # Are new pokemons added to the pokedex ? return _inventory.pokedex -def candies(refresh=False): +def candies(): """ - :param refresh: :return: :rtype: Candies """ - if refresh: - refresh_inventory() return _inventory.candy -def pokemons(refresh=False): +def pokemons(): """ - :param refresh: :return: :rtype: Pokemons """ - if refresh: - refresh_inventory() return _inventory.pokemons diff --git a/pokemongo_bot/services/item_recycle_worker.py b/pokemongo_bot/services/item_recycle_worker.py index aa02b366a2..c34d8bb08c 100644 --- a/pokemongo_bot/services/item_recycle_worker.py +++ b/pokemongo_bot/services/item_recycle_worker.py @@ -13,6 +13,7 @@ def __init__(self, bot, item_to_recycle, amount_to_recycle): """ Initialise an instance of ItemRecycler :param bot: The instance of the Bot + :type bot: pokemongo_bot.PokemonGoBot :param item_to_recycle: The item to recycle :type item_to_recycle: inventory.Item :param amount_to_recycle: The amount to recycle From 394bbf7660ab097f757fa0fdb7e48ac178c43c60 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 01:40:33 +0200 Subject: [PATCH 02/11] Removed print --- pokecli.py | 6 ------ pokemongo_bot/inventory.py | 6 ------ 2 files changed, 12 deletions(-) diff --git a/pokecli.py b/pokecli.py index 896171c90d..6d17dff512 100644 --- a/pokecli.py +++ b/pokecli.py @@ -189,12 +189,6 @@ def report_summary(bot): metrics.num_evolutions(), metrics.num_new_mons())) logger.info('Threw {} pokeball{}'.format(metrics.num_throws(), '' if metrics.num_throws() == 1 else 's')) logger.info('Earned {} Stardust'.format(metrics.earned_dust())) - print("##############################") - print("# #") - print("# Refreshed the inventory #") - print("# {} times #".format(inventory._inventory.refresh_count)) - print("# #") - print("##############################") logger.info('') if metrics.highest_cp is not None: logger.info('Highest CP Pokemon: {}'.format(metrics.highest_cp['desc'])) diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index 7dee23b59a..0acd59e875 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -1086,12 +1086,6 @@ def __init__(self, bot): def refresh(self): self.refresh_count += 1 - print("##############################") - print("# #") - print("# Refreshing the inventory #") - print("# Nr : {} #".format(self.refresh_count)) - print("# #") - print("##############################") inventory = self.bot.api.get_inventory() inventory = inventory['responses']['GET_INVENTORY']['inventory_delta']['inventory_items'] for i in (self.pokedex, self.candy, self.items, self.pokemons): From 5165d82ad811db4f87416b2f2459da0250989203 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 01:40:58 +0200 Subject: [PATCH 03/11] Removed print --- pokemongo_bot/cell_workers/recycle_items.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pokemongo_bot/cell_workers/recycle_items.py b/pokemongo_bot/cell_workers/recycle_items.py index 814b8bb694..7ae01748f0 100644 --- a/pokemongo_bot/cell_workers/recycle_items.py +++ b/pokemongo_bot/cell_workers/recycle_items.py @@ -89,9 +89,6 @@ def work(self): worker_result = WorkerResult.SUCCESS if self.should_run(): - print("Inventory BEFORE item recycling : ") - self.bot._print_character_info() - for item_in_inventory in inventory.items().all(): if self.item_should_be_recycled(item_in_inventory): @@ -100,8 +97,6 @@ def work(self): # If at any recycling process call we got an error, we consider that the result of this task is error too. if ItemRecycler(self.bot, item_in_inventory, self.get_amount_to_recycle(item_in_inventory)).work() == WorkerResult.ERROR: worker_result = WorkerResult.ERROR - print("Inventory AFTER item recycling : ") - self.bot._print_character_info() return worker_result def item_should_be_recycled(self, item): From 45f9421e67feee5ef92f4c4b21e0420b87ed8176 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 16:17:02 +0200 Subject: [PATCH 04/11] Keeps track of candy on pokemon catch --- pokemongo_bot/cell_workers/pokemon_catch_worker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index 09c9e594c0..78c49c339a 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -395,7 +395,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): ) # We could refresh here too, but adding 3 saves a inventory request - candy = inventory.candies().get(pokemon.pokemon_id) + candy = inventory.candies().get(pokemon.pokemon_id).add(3) self.emit_event( 'gained_candy', formatted='You now have {quantity} {type} candy!', From a01d7e20c154b3c95c78a56eb12a03fb8594552b Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 17:37:08 +0200 Subject: [PATCH 05/11] Dynamically count candy gained --- pokemongo_bot/cell_workers/pokemon_catch_worker.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index 78c49c339a..21425e8ecf 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +import json import time from random import random from pokemongo_bot import inventory @@ -394,8 +394,9 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): } ) - # We could refresh here too, but adding 3 saves a inventory request - candy = inventory.candies().get(pokemon.pokemon_id).add(3) + candy = inventory.candies().get(pokemon.pokemon_id) + candy.add(self.get_candy_gained_count(response_dict)) + self.emit_event( 'gained_candy', formatted='You now have {quantity} {type} candy!', @@ -409,6 +410,12 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): break + def get_candy_gained_count(self, response_dict): + total_candy_gained = 0 + for candy_gained in response_dict['responses']['CATCH_POKEMON']['capture_award']['candy']: + total_candy_gained += candy_gained + return total_candy_gained + def generate_spin_parameter(self, throw_parameters): spin_success_rate = self.config.catch_throw_parameters_spin_success_rate if random() <= spin_success_rate: From 59a3cd1de8d17eef7d859c85c4b080c45b0f5462 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 17:38:36 +0200 Subject: [PATCH 06/11] Rename pokemon id in pokemon unique id --- pokemongo_bot/cell_workers/pokemon_catch_worker.py | 2 +- pokemongo_bot/cell_workers/transfer_pokemon.py | 4 ++-- pokemongo_bot/inventory.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index 21425e8ecf..0a6488e1e8 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -375,7 +375,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): # pokemon caught! elif catch_pokemon_status == CATCH_STATUS_SUCCESS: - pokemon.id = response_dict['responses']['CATCH_POKEMON']['captured_pokemon_id'] + 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) inventory.pokemons().add(pokemon) self.emit_event( diff --git a/pokemongo_bot/cell_workers/transfer_pokemon.py b/pokemongo_bot/cell_workers/transfer_pokemon.py index 4c659bd8c0..b1cbbd0bf3 100644 --- a/pokemongo_bot/cell_workers/transfer_pokemon.py +++ b/pokemongo_bot/cell_workers/transfer_pokemon.py @@ -142,7 +142,7 @@ def release_pokemon(self, pokemon): if self.bot.config.test: candy_awarded = 1 else: - response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.id) + response_dict = self.bot.api.release_pokemon(pokemon_id=pokemon.unique_id) candy_awarded = response_dict['responses']['RELEASE_POKEMON']['candy_awarded'] except KeyError: return @@ -150,7 +150,7 @@ def release_pokemon(self, pokemon): # We could refresh here too, but adding 1 saves a inventory request candy = inventory.candies().get(pokemon.pokemon_id) candy.add(candy_awarded) - inventory.pokemons().remove(pokemon.id) + inventory.pokemons().remove(pokemon.unique_id) self.bot.metrics.released_pokemon() self.emit_event( 'pokemon_release', diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index 0acd59e875..8ee3099ee8 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -756,7 +756,7 @@ class Pokemon(object): def __init__(self, data): self._data = data # Unique ID for this particular Pokemon - self.id = data.get('id', 0) + self.unique_id = data.get('id', 0) # Id of the such pokemons in pokedex self.pokemon_id = data['pokemon_id'] # Static information From ab66a89a1c069ad302df95da69ed5521fdbd3fa8 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Mon, 15 Aug 2016 17:44:57 +0200 Subject: [PATCH 07/11] Fixed typo Some clean up --- pokemongo_bot/__init__.py | 1 - pokemongo_bot/inventory.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 868d237e27..ab7c7844d7 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -706,7 +706,6 @@ def _setup_api(self): self.api.activate_signature(self.get_encryption_lib()) self.logger.info('') - #self.update_inventory() # send empty map_cells and then our position self.update_web_location() diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index 8ee3099ee8..144088c168 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -324,7 +324,7 @@ def all(self): def add(self, pokemon): if pokemon.id <= 0: - raise ValueError("Can't add a pokemon whitout id") + raise ValueError("Can't add a pokemon without id") if pokemon.id in self._data: raise ValueError("Pokemon already present in the inventory") self._data[pokemon.id] = pokemon From 81a3be5d672a75ed87be9fe946513a939e2b8492 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Tue, 16 Aug 2016 23:00:53 +0200 Subject: [PATCH 08/11] Renamed pokemon id in unique_id --- pokemongo_bot/cell_workers/evolve_pokemon.py | 6 +++--- pokemongo_bot/cell_workers/transfer_pokemon.py | 6 +++--- pokemongo_bot/inventory.py | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pokemongo_bot/cell_workers/evolve_pokemon.py b/pokemongo_bot/cell_workers/evolve_pokemon.py index 4de40fdb7d..bb1f1d2b6f 100644 --- a/pokemongo_bot/cell_workers/evolve_pokemon.py +++ b/pokemongo_bot/cell_workers/evolve_pokemon.py @@ -85,7 +85,7 @@ def _sort_and_filter(self): } for pokemon in inventory.pokemons().all(): - if pokemon.id > 0 and pokemon.has_next_evolution() and (logic_to_function[self.cp_iv_logic](pokemon)): + if pokemon.unique_id > 0 and pokemon.has_next_evolution() and (logic_to_function[self.cp_iv_logic](pokemon)): pokemons.append(pokemon) if self.first_evolve_by == "cp": @@ -99,7 +99,7 @@ def _execute_pokemon_evolve(self, pokemon, cache): if pokemon.name in cache: return False - response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.id) + response_dict = self.api.evolve_pokemon(pokemon_id=pokemon.unique_id) if response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('result', 0) == 1: self.emit_event( 'pokemon_evolved', @@ -115,7 +115,7 @@ def _execute_pokemon_evolve(self, pokemon, cache): ) awarded_candies = response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('candy_awarded', 0) inventory.candies().get(pokemon.pokemon_id).consume(pokemon.evolution_cost - awarded_candies) - inventory.pokemons().remove(pokemon.id) + inventory.pokemons().remove(pokemon.unique_id) pokemon = Pokemon(response_dict.get('responses', {}).get('EVOLVE_POKEMON', {}).get('evolved_pokemon_data', {})) inventory.pokemons().add(pokemon) sleep(self.evolve_speed) diff --git a/pokemongo_bot/cell_workers/transfer_pokemon.py b/pokemongo_bot/cell_workers/transfer_pokemon.py index b1cbbd0bf3..1fa612be3a 100644 --- a/pokemongo_bot/cell_workers/transfer_pokemon.py +++ b/pokemongo_bot/cell_workers/transfer_pokemon.py @@ -22,13 +22,13 @@ def work(self): if keep_best_cp >= 1: cp_limit = keep_best_cp best_cp_pokemons = sorted(group, key=lambda x: (x.cp, x.iv), reverse=True)[:cp_limit] - best_pokemon_ids = set(pokemon.id for pokemon in best_cp_pokemons) + best_pokemon_ids = set(pokemon.unique_id for pokemon in best_cp_pokemons) order_criteria = 'cp' if keep_best_iv >= 1: iv_limit = keep_best_iv best_iv_pokemons = sorted(group, key=lambda x: (x.iv, x.cp), reverse=True)[:iv_limit] - best_pokemon_ids |= set(pokemon.id for pokemon in best_iv_pokemons) + best_pokemon_ids |= set(pokemon.unique_id for pokemon in best_iv_pokemons) if order_criteria == 'cp': order_criteria = 'cp and iv' else: @@ -39,7 +39,7 @@ def work(self): best_pokemons = [] for best_pokemon_id in best_pokemon_ids: for pokemon in all_pokemons: - if best_pokemon_id == pokemon.id: + if best_pokemon_id == pokemon.unique_id: all_pokemons.remove(pokemon) best_pokemons.append(pokemon) diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index 144088c168..6412e25e17 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -323,16 +323,16 @@ def all(self): return [p for p in super(Pokemons, self).all() if not isinstance(p, Egg)] def add(self, pokemon): - if pokemon.id <= 0: + if pokemon.unique_id <= 0: raise ValueError("Can't add a pokemon without id") - if pokemon.id in self._data: + if pokemon.unique_id in self._data: raise ValueError("Pokemon already present in the inventory") - self._data[pokemon.id] = pokemon + self._data[pokemon.unique_id] = pokemon - def remove(self, pokemon_id): - if pokemon_id not in self._data: + def remove(self, pokemon_unique_id): + if pokemon_unique_id not in self._data: raise ValueError("Pokemon not present in the inventory") - self._data.pop(pokemon_id) + self._data.pop(pokemon_unique_id) # From 60ae043ed2d10427ab33636a46a3a2bcc89f49b1 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Wed, 17 Aug 2016 19:16:40 +0200 Subject: [PATCH 09/11] Now display again stats on start --- pokemongo_bot/__init__.py | 56 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 1c61a198f0..52ee9e629d 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -86,6 +86,7 @@ def start(self): self._setup_api() self._load_recent_forts() init_inventory(self) + self.display_player_info() self._print_character_info() random.seed() @@ -956,32 +957,35 @@ def update_web_location_worker(self): self.web_update_queue.get() self.update_web_location() - # def get_player_info(self): - # pokecount = 0 - # itemcount = 1 - # for item in inventory.items().all(): - # # print('item {}'.format(item)) - # playerdata = item.get('inventory_item_data', {}).get('player_stats') - # if playerdata: - # nextlvlxp = (int(playerdata.get('next_level_xp', 0)) - int(playerdata.get('experience', 0))) - # - # if 'level' in playerdata and 'experience' in playerdata: - # self.logger.info( - # 'Level: {level}'.format( - # **playerdata) + - # ' (Next Level: {} XP)'.format( - # nextlvlxp) + - # ' (Total: {experience} XP)' - # ''.format(**playerdata)) - # - # if 'pokemons_captured' in playerdata and 'poke_stop_visits' in playerdata: - # self.logger.info( - # 'Pokemon Captured: ' - # '{pokemons_captured}'.format( - # **playerdata) + - # ' | Pokestops Visited: ' - # '{poke_stop_visits}'.format( - # **playerdata)) + def display_player_info(self): + inventory_items = self.api.get_inventory() + inventory_items = inventory_items['responses']['GET_INVENTORY']['inventory_delta']['inventory_items'] + player_stats = next((x["inventory_item_data"]["player_stats"] + for x in inventory_items + if x.get("inventory_item_data", {}).get("player_stats", {})), + None) + + if player_stats: + + nextlvlxp = (int(player_stats.get('next_level_xp', 0)) - int(player_stats.get('experience', 0))) + + if 'level' in player_stats and 'experience' in player_stats: + self.logger.info( + 'Level: {level}'.format( + **player_stats) + + ' (Next Level: {} XP)'.format( + nextlvlxp) + + ' (Total: {experience} XP)' + ''.format(**player_stats)) + + if 'pokemons_captured' in player_stats and 'poke_stop_visits' in player_stats: + self.logger.info( + 'Pokemon Captured: ' + '{pokemons_captured}'.format( + **player_stats) + + ' | Pokestops Visited: ' + '{poke_stop_visits}'.format( + **player_stats)) def get_forts(self, order_by_distance=False): forts = [fort From 62c9619263f73dd9c8ae74f3babc051ce070154d Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Thu, 18 Aug 2016 22:14:14 +0200 Subject: [PATCH 10/11] Now use ultraball on non vip too --- .../cell_workers/pokemon_catch_worker.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index 8d391276df..d2607e88d6 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -102,11 +102,9 @@ def work(self, response_dict=None): return WorkerResult.SUCCESS is_vip = self._is_vip_pokemon(pokemon) - if pokeballs < 1: - if superballs < 1: - if ultraballs < 1: - return WorkerResult.SUCCESS - if not is_vip: + if inventory.items().get(ITEM_POKEBALL).count < 1: + if inventory.items().get(ITEM_GREATBALL).count < 1: + if inventory.items().get(ITEM_ULTRABALL).count < 1: return WorkerResult.SUCCESS # log encounter @@ -132,11 +130,6 @@ def work(self, response_dict=None): if is_vip: self.emit_event('vip_pokemon', formatted='This is a VIP pokemon. Catch!!!') - # check for VIP pokemon - is_vip = self._is_vip_pokemon(pokemon) - if is_vip: - self.emit_event('vip_pokemon', formatted='This is a VIP pokemon. Catch!!!') - # check catch limits before catch with self.bot.database as conn: c = conn.cursor() @@ -498,8 +491,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): }, ) - self.bot.softban = False - + self.bot.softban = False break def get_candy_gained_count(self, response_dict): @@ -552,3 +544,4 @@ def generate_throw_quality_parameters(self, throw_parameters): throw_parameters['normalized_reticle_size'] = 1.25 + 0.70 * random() throw_parameters['normalized_hit_position'] = 0.0 throw_parameters['throw_type_label'] = 'OK' + From a036b593fbc9663951bce0fd21f8164b3506d186 Mon Sep 17 00:00:00 2001 From: SAUNIER DEBES Brice Date: Thu, 18 Aug 2016 23:18:55 +0200 Subject: [PATCH 11/11] Merge branch 'dev' of https://github.com/PokemonGoF/PokemonGo-Bot into remove-old-inventory # Conflicts: # pokemongo_bot/__init__.py Now move to map use cached inventory Removed log.logger() --- pokemongo_bot/__init__.py | 7 ++---- .../cell_workers/move_to_map_pokemon.py | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index b361bf1fae..cde856e6da 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -101,6 +101,8 @@ def start(self): init_inventory(self) self.display_player_info() self._print_character_info() + if self.config.pokemon_bag_show_at_start and self.config.pokemon_bag_pokemon_info: + self._print_list_pokemon() random.seed() @@ -756,9 +758,6 @@ def _setup_api(self): self.login() # chain subrequests (methods) into one RPC call - self._print_character_info() - if self.config.pokemon_bag_show_at_start and self.config.pokemon_bag_pokemon_info: - self._print_list_pokemon() self.api.activate_signature(self.get_encryption_lib()) self.logger.info('') # send empty map_cells and then our position @@ -850,8 +849,6 @@ def _print_character_info(self): self.logger.info('') def _print_list_pokemon(self): - init_inventory(self) - # get pokemon list pokemon_list = inventory.pokemons().all() pokemon_list = sorted(pokemon_list, key=lambda k: k.pokemon_id) diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index a598a9f69f..8c275a2528 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -54,6 +54,8 @@ import json import base64 import requests + +from pokemongo_bot import inventory from pokemongo_bot.base_dir import _base_dir from pokemongo_bot.cell_workers.utils import distance, format_dist, format_time from pokemongo_bot.step_walker import StepWalker @@ -64,6 +66,9 @@ # Update the map if more than N meters away from the center. (AND'd with # UPDATE_MAP_MIN_TIME_MINUTES) +ULTRABALL_ID = 3 +GREATBALL_ID = 2 +POKEBALL_ID = 1 UPDATE_MAP_MIN_DISTANCE_METERS = 500 # Update the map if it hasn't been updated in n seconds. (AND'd with @@ -181,7 +186,7 @@ def update_map_location(self): except ValueError: err = 'Map location data was not valid' self._emit_failure(err) - return log.logger(err, 'red') + return dist = distance( self.bot.position[0], @@ -235,11 +240,11 @@ def dump_caught_pokemon(self): def work(self): # check for pokeballs (excluding masterball) - pokeballs = self.bot.item_inventory_count(1) - superballs = self.bot.item_inventory_count(2) - ultraballs = self.bot.item_inventory_count(3) + pokeballs_quantity = inventory.items().get(POKEBALL_ID).count + superballs_quantity = inventory.items().get(GREATBALL_ID).count + ultraballs_quantity = inventory.items().get(ULTRABALL_ID).count - if (pokeballs + superballs + ultraballs) < 1: + if (pokeballs_quantity + superballs_quantity + ultraballs_quantity) < 1: return WorkerResult.SUCCESS self.update_map_location() @@ -257,11 +262,9 @@ def work(self): pokemon = pokemon_list[0] - if pokeballs < 1: - if superballs < 1: - if ultraballs < 1: - return WorkerResult.SUCCESS - if not pokemon['is_vip']: + if pokeballs_quantity < 1: + if superballs_quantity < 1: + if ultraballs_quantity < 1: return WorkerResult.SUCCESS if self.config['snipe']: