예제 #1
0
    def get_visible_pokemon(self):
        pokemon_to_catch = []
        if 'catchable_pokemons' in self.bot.cell:
            pokemon_to_catch = self.bot.cell['catchable_pokemons']

            if len(pokemon_to_catch) > 0:
                user_web_catchable = os.path.join(_base_dir, 'web', 'catchable-{}.json'.format(self.bot.config.username))
            for pokemon in pokemon_to_catch:
                # Update web UI
                with open(user_web_catchable, 'w') as outfile:
                    json.dump(pokemon, outfile)

                self.emit_event(
                    'catchable_pokemon',
                    level='debug',
                    data={
                        'pokemon_id': pokemon['pokemon_id'],
                        'spawn_point_id': pokemon['spawn_point_id'],
                        'encounter_id': pokemon['encounter_id'],
                        'latitude': pokemon['latitude'],
                        'longitude': pokemon['longitude'],
                        'expiration_timestamp_ms': pokemon['expiration_timestamp_ms'],
                        'pokemon_name': Pokemons.name_for(pokemon['pokemon_id']),
                    }
                )

                self.add_pokemon(pokemon)

        if 'wild_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['wild_pokemons']:
                self.add_pokemon(pokemon)
예제 #2
0
    def get_visible_pokemon(self):
        pokemon_to_catch = []
        if 'catchable_pokemons' in self.bot.cell:
            pokemon_to_catch = self.bot.cell['catchable_pokemons']

            if len(pokemon_to_catch) > 0:
                user_web_catchable = os.path.join(_base_dir, 'web', 'catchable-{}.json'.format(self.bot.config.username))
            for pokemon in pokemon_to_catch:
                # Update web UI
                with open(user_web_catchable, 'w') as outfile:
                    json.dump(pokemon, outfile)

                self.emit_event(
                    'catchable_pokemon',
                    level='debug',
                    data={
                        'pokemon_id': pokemon['pokemon_id'],
                        'spawn_point_id': pokemon['spawn_point_id'],
                        'encounter_id': pokemon['encounter_id'],
                        'latitude': pokemon['latitude'],
                        'longitude': pokemon['longitude'],
                        'expiration_timestamp_ms': pokemon['expiration_timestamp_ms'],
                        'pokemon_name': Pokemons.name_for(pokemon['pokemon_id']),
                    }
                )

                self.add_pokemon(pokemon)

        if 'wild_pokemons' in self.bot.cell:
            for pokemon in self.bot.cell['wild_pokemons']:
                self.add_pokemon(pokemon)
예제 #3
0
    def _get_pokemons_in_gym(self, gym_details):
        pokemon_names = []
        gym_info = gym_details.get('gym_status_and_defenders', None)
        if gym_info:
            defenders = gym_info.get('gym_defender', [])
            for defender in defenders:
                motivated_pokemon = defender.get('motivated_pokemon')
                pokemon_info = motivated_pokemon.get('pokemon')
                pokemon_id = pokemon_info.get('pokemon_id')
                pokemon_names.append(Pokemons.name_for(pokemon_id))

        return pokemon_names
예제 #4
0
    def _is_vip_pokemon(self, pokemon):
        if 'pokemon_id' not in pokemon:
            if not 'name' in pokemon:
                return False
            pokemon['pokemon_id'] = Pokemons.id_for(pokemon['name'])
        # having just a name present in the list makes them vip
        # Not seen pokemons also will become vip if it's not disabled in config
        if self.bot.config.vips.get(Pokemons.name_for(pokemon['pokemon_id'])) == {}:
            return True
        if (not inventory.pokedex().seen(pokemon['pokemon_id'])):
            return True
        # If we must treat family of VIP as VIP
        if self.config.get('treat_family_of_vip_as_vip', False):
            if self._is_family_of_vip(pokemon['pokemon_id']):
                return True
        # If we need the Pokemon for an evolution, catch it.
        if any(not inventory.pokedex().seen(fid) for fid in self.get_family_ids(pokemon['pokemon_id'])):
            # self.logger.info('Found a Pokemon whoes family is not yet complete in Pokedex!')
            return True

        return False
예제 #5
0
    def work(self):
        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            keep_best, keep_best_cp, keep_best_iv = self._validate_keep_best_config(pokemon_name)

            if keep_best:
                best_pokemon_ids = set()
                order_criteria = 'none'
                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)
                    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)
                    if order_criteria == 'cp':
                        order_criteria = 'cp and iv'
                    else:
                        order_criteria = 'iv'

                # remove best pokemons from all pokemons array
                all_pokemons = group
                best_pokemons = []
                for best_pokemon_id in best_pokemon_ids:
                    for pokemon in all_pokemons:
                        if best_pokemon_id == pokemon.id:
                            all_pokemons.remove(pokemon)
                            best_pokemons.append(pokemon)

                transfer_pokemons = [pokemon for pokemon in all_pokemons if self.should_release_pokemon(pokemon,True)]

                if transfer_pokemons:
                    if best_pokemons:
                        self.emit_event(
                            'keep_best_release',
                            formatted="Keeping best {amount} {pokemon}, based on {criteria}",
                            data={
                                'amount': len(best_pokemons),
                                'pokemon': pokemon_name,
                                'criteria': order_criteria
                            }
                        )
                    for pokemon in transfer_pokemons:
                        self.release_pokemon(pokemon)
            else:
                group = sorted(group, key=lambda x: x.cp, reverse=True)
                for pokemon in group:
                    if self.should_release_pokemon(pokemon):
                        self.release_pokemon(pokemon)
예제 #6
0
    def _is_vip_pokemon(self, pokemon):
        if 'pokemon_id' not in pokemon:
            if not 'name' in pokemon:
                return False
            pokemon['pokemon_id'] = Pokemons.id_for(pokemon['name'])
        # having just a name present in the list makes them vip
        # Not seen pokemons also will become vip if it's not disabled in config
        if self.bot.config.vips.get(Pokemons.name_for(pokemon['pokemon_id'])) == {}:
            return True
        if (not inventory.pokedex().seen(pokemon['pokemon_id'])):
            return True
        # If we must treat family of VIP as VIP
        if self.config.get('treat_family_of_vip_as_vip', False):
            if self._is_family_of_vip(pokemon['pokemon_id']):
                return True
        # If we need the Pokemon for an evolution, catch it.
        if any(not inventory.pokedex().seen(fid) for fid in self.get_family_ids(pokemon['pokemon_id'])):
            # self.logger.info('Found a Pokemon whoes family is not yet complete in Pokedex!')
            return True

        return False
예제 #7
0
    def work(self):
        if not self._should_work():
            return

        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            self._release_pokemon_worst_in_group(group, pokemon_name)

        group = [p for p in inventory.pokemons().all()
                 if p.in_fort is False and p.is_favorite is False]
        self._release_pokemon_worst_in_group(group, 'all')
예제 #8
0
    def _get_pokemons_in_gym(self, gym_details):
        pokemon_names = []
        gym_info = gym_details.get('gym_status_and_defenders', None)
        if gym_info:
            defenders = gym_info.get('gym_defender', [])
            for defender in defenders:
                motivated_pokemon = defender.get('motivated_pokemon')
                pokemon_info = motivated_pokemon.get('pokemon')
                pokemon_id = pokemon_info.get('pokemon_id')
                pokemon_names.append(Pokemons.name_for(pokemon_id))

        return pokemon_names
예제 #9
0
    def _is_vip_pokemon(self, pokemon_id):
        # having just a name present in the list makes them vip
        # Not seen pokemons also will become vip if it's not disabled in config
        if self.bot.config.vips.get(Pokemons.name_for(pokemon_id)) == {}:
            return True
        if (not inventory.pokedex().seen(pokemon_id)):
            return True
        # If we need the Pokemon for an evolution, catch it.
        if any(not inventory.pokedex().seen(fid) for fid in self.get_family_ids(pokemon_id)):
            # self.logger.info('Found a Pokemon whoes family is not yet complete in Pokedex!')
            return True

        return False
    def work(self):
        if not self._should_work():
            return

        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            self._release_pokemon_worst_in_group(group, pokemon_name)

        if self.bot.config.release.get('all'):
            group = [p for p in inventory.pokemons().all()
                     if p.in_fort is False and p.is_favorite is False]
            self._release_pokemon_worst_in_group(group, 'all')
예제 #11
0
    def work(self):
        if not self._should_work():
            return

        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            self._release_pokemon_worst_in_group(group, pokemon_name)

        if self.bot.config.release.get('all'):
            group = [
                p for p in inventory.pokemons().all() if not p.in_fort
                and not p.is_favorite and not (p.unique_id == self.buddyid)
            ]
            self._release_pokemon_worst_in_group(group, 'all')
예제 #12
0
    def _parse_pokemons(self, pokemon_dictionary_list):
        result = []

        # Build up the pokemon. Pops are used to destroy random attribute names and keep the known ones!
        for pokemon in pokemon_dictionary_list:
            pokemon['iv'] = pokemon.get('iv', 100)
            pokemon['pokemon_name'] = pokemon.get('pokemon_name', Pokemons.name_for(pokemon.get('pokemon_id')))
            pokemon['vip'] = pokemon.get('pokemon_name') in self.bot.config.vips
            pokemon['missing'] = not self.pokedex.captured(pokemon.get('pokemon_id'))
            pokemon['priority'] = self.catch_list.get(pokemon.get('pokemon_name'), 0)

            # Check whether this is a valid target
            if self.is_snipeable(pokemon):
                result.append(pokemon)

        return result
예제 #13
0
    def request_snipe(self, update, pkm, lat, lng):
        snipeSuccess = False
        try:
            id = Pokemons.id_for(pkm)
        except:
            self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Invaild Pokemon")
            return

        #Set Telegram Snipe to true and let sniper do its work
        TelegramSnipe.ENABLED = True
        TelegramSnipe.ID = int(id)
        TelegramSnipe.POKEMON_NAME = str(pkm)
        TelegramSnipe.LATITUDE = float(lat)
        TelegramSnipe.LONGITUDE = float(lng)
        
        outMsg = 'Catching pokemon: ' + TelegramSnipe.POKEMON_NAME + ' at Latitude: ' + str(TelegramSnipe.LATITUDE) + ' Longitude: ' + str(TelegramSnipe.LONGITUDE) + '\n'
        self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="".join(outMsg))
예제 #14
0
    def request_snipe(self, update, pkm, lat, lng):
        snipeSuccess = False
        try:
            id = Pokemons.id_for(pkm)
        except:
            self.sendMessage(chat_id=update.message.chat_id,
                             parse_mode='Markdown',
                             text="Invaild Pokemon")
            return

        #Set Telegram Snipe to true and let sniper do its work
        TelegramSnipe.ENABLED = True
        TelegramSnipe.ID = int(id)
        TelegramSnipe.POKEMON_NAME = str(pkm)
        TelegramSnipe.LATITUDE = float(lat)
        TelegramSnipe.LONGITUDE = float(lng)

        outMsg = 'Catching pokemon: ' + TelegramSnipe.POKEMON_NAME + ' at Latitude: ' + str(
            TelegramSnipe.LATITUDE) + ' Longitude: ' + str(
                TelegramSnipe.LONGITUDE) + '\n'
        self.sendMessage(chat_id=update.message.chat_id,
                         parse_mode='Markdown',
                         text="".join(outMsg))
예제 #15
0
    def work(self):
        # make sure we have SOME balls
        if sum([inventory.items().get(ball.value).count for ball in
    [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]]) <= 0:
            return WorkerResult.ERROR

        if self.bot.softban:
            if not hasattr(self.bot, "softban_global_warning") or \
                        (hasattr(self.bot, "softban_global_warning") and not self.bot.softban_global_warning):
                self.logger.info("Possible softban! Not trying to catch Pokemon.")
            self.bot.softban_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.softban_global_warning = False

	# Don't try to catch a Pokemon when catching is disabled.
        if self.bot.catch_disabled:
            if not hasattr(self.bot,"all_disabled_global_warning") or \
                        (hasattr(self.bot,"all_disabled_global_warning") and not self.bot.all_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Ignoring all Pokemon till then.".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.all_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.all_disabled_global_warning = False

        # check if we have already loaded a list
        if len(self.pokemon) <= 0:
            # load available pokemon by config settings
            if self.config.get('catch_visible_pokemon', True):
                self.get_visible_pokemon()
            if self.config.get('catch_lured_pokemon', True):
                self.get_lured_pokemon()
            if self._have_applied_incense() and self.config.get('catch_incensed_pokemon', True):
                self.get_incensed_pokemon()

            random.shuffle(self.pokemon)

        # Filter out already ignored mons
        if hasattr(self.bot,"hunter_locked_target"):
            if self.bot.hunter_locked_target != None:
                self.pokemon = filter(lambda x: x["pokemon_id"] not in self.ignored_while_looking, self.pokemon)
            elif len(self.ignored_while_looking) > 0:
                self.logger.info("No longer hunting for a Pokémon, resuming normal operations.")
                # Reset the ignored list when no longer needed.
                self.ignored_while_looking = []

        if hasattr(self.bot, "skipped_pokemon"):
            # Skip pokemon the catcher told us to ignore
            self.pokemon = [ p for p in self.pokemon if p not in self.bot.skipped_pokemon ]

        num_pokemon = len(self.pokemon)

        if num_pokemon > 0:
            # try catching
            mon_to_catch = self.pokemon.pop()
            is_vip = hasattr(mon_to_catch, "pokemon_id") and self._is_vip_pokemon(mon_to_catch['pokemon_id'])
            # Always catch VIP Pokemons!
            if hasattr(self.bot,"hunter_locked_target") and self.bot.hunter_locked_target != None:
                bounty = self.bot.hunter_locked_target
                mon_name = Pokemons.name_for(mon_to_catch['pokemon_id'])
                bounty_name = Pokemons.name_for(bounty['pokemon_id'])

                if mon_name != bounty_name and is_vip == False:
                    # This is not the Pokémon you are looking for...
                    self.logger.info("[Hunter locked a {}] Ignoring a {}".format(bounty_name, mon_name))
                    self.ignored_while_looking.append(mon_to_catch['pokemon_id'])

                    if num_pokemon > 1:
                        return WorkerResult.RUNNING
                    else:
                        return WorkerResult.SUCCESS
                else:
                    # We have found a vip or our target...
                    if bounty_name == mon_name:
                        self.bot.hunter_locked_target = None
                        self.logger.info("Found my target {}!".format(bounty_name))
                    else:
                        self.logger.info("While on the hunt for {}, I found a {}! I need that Pokemon! Will try to catch...".format(bounty_name, mon_name))
            try:
                if self.catch_pokemon(mon_to_catch) == WorkerResult.ERROR:
                    # give up incase something went wrong in our catch worker (ran out of balls, etc)
                    return WorkerResult.ERROR
                elif num_pokemon > 1:
                    # we have more pokemon to catch
                    return WorkerResult.RUNNING
            except ValueError:
                return WorkerResult.ERROR

        # all pokemon have been processed
        return WorkerResult.SUCCESS
예제 #16
0
    def work(self):
        num_catchable_pokemon = 0
        if 'catchable_pokemons' in self.bot.cell:
            num_catchable_pokemon = len(self.bot.cell['catchable_pokemons'])

        num_wild_pokemon = 0
        if 'wild_pokemons' in self.bot.cell:
            num_wild_pokemon = len(self.bot.cell['wild_pokemons'])

        num_available_pokemon = num_catchable_pokemon + num_wild_pokemon

        if num_catchable_pokemon > 0:
            # Sort all by distance from current pos- eventually this should
            # build graph & A* it
            self.bot.cell['catchable_pokemons'].sort(
                key=lambda x: distance(self.bot.position[0], self.bot.position[
                    1], x['latitude'], x['longitude']))
            user_web_catchable = os.path.join(
                _base_dir, 'web',
                'catchable-{}.json'.format(self.bot.config.username))
            for pokemon in self.bot.cell['catchable_pokemons']:
                with open(user_web_catchable, 'w') as outfile:
                    json.dump(pokemon, outfile)
                self.emit_event('catchable_pokemon',
                                level='debug',
                                data={
                                    'pokemon_id':
                                    pokemon['pokemon_id'],
                                    'spawn_point_id':
                                    pokemon['spawn_point_id'],
                                    'encounter_id':
                                    pokemon['encounter_id'],
                                    'latitude':
                                    pokemon['latitude'],
                                    'longitude':
                                    pokemon['longitude'],
                                    'expiration_timestamp_ms':
                                    pokemon['expiration_timestamp_ms'],
                                    'pokemon_name':
                                    Pokemons.name_for(pokemon['pokemon_id']),
                                })
                if not self.was_encountered(pokemon):
                    self.catch_pokemon(pokemon)
                    self.add_encountered(pokemon)
                    return WorkerResult.RUNNING

            return WorkerResult.SUCCESS

        if num_available_pokemon > 0:
            # Sort all by distance from current pos- eventually this should
            # build graph & A* it
            self.bot.cell['wild_pokemons'].sort(
                key=lambda x: distance(self.bot.position[0], self.bot.position[
                    1], x['latitude'], x['longitude']))

            for pokemon in self.bot.cell['wild_pokemons']:
                if not self.was_encountered(pokemon):
                    self.catch_pokemon(pokemon)
                    self.add_encountered(pokemon)
                    return WorkerResult.RUNNING

            return WorkerResult.SUCCESS
예제 #17
0
    def work(self):
        # make sure we have SOME balls
        if sum([inventory.items().get(ball.value).count for ball in
    [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]]) <= 0:
            return WorkerResult.ERROR

	# Don't try to catch a Pokemon when catching is disabled.
        if self.bot.catch_disabled:
            if not hasattr(self.bot,"all_disabled_global_warning") or \
                        (hasattr(self.bot,"all_disabled_global_warning") and not self.bot.all_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Ignoring all Pokemon till then.".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.all_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.all_disabled_global_warning = False

        # check if we have already loaded a list
        if len(self.pokemon) <= 0:
            # load available pokemon by config settings
            if self.config.get('catch_visible_pokemon', True):
                self.get_visible_pokemon()
            if self.config.get('catch_lured_pokemon', True):
                self.get_lured_pokemon()
            if self._have_applied_incense() and self.config.get('catch_incensed_pokemon', True):
                self.get_incensed_pokemon()

            random.shuffle(self.pokemon)

        # Filter out already ignored mons
        if hasattr(self.bot,"hunter_locked_target"):
            if self.bot.hunter_locked_target != None:
                self.pokemon = filter(lambda x: x["pokemon_id"] not in self.ignored_while_looking, self.pokemon)
            elif len(self.ignored_while_looking) > 0:
                self.logger.info("No longer hunting for a Pokémon, resuming normal operations.")
                # Reset the ignored list when no longer needed.
                self.ignored_while_looking = []

        num_pokemon = len(self.pokemon)
        if num_pokemon > 0:
            # try catching
            mon_to_catch = self.pokemon.pop()

            if hasattr(self.bot,"hunter_locked_target") and self.bot.hunter_locked_target != None:
                bounty = self.bot.hunter_locked_target
                mon_name = Pokemons.name_for(mon_to_catch['pokemon_id'])
                bounty_name = Pokemons.name_for(bounty['pokemon_id'])

                if mon_name != bounty_name:
                    # This is not the Pokémon you are looking for...
                    self.logger.info("[Hunter locked a {}] Ignoring a {}".format(bounty_name, mon_name))
                    self.ignored_while_looking.append(mon_to_catch['pokemon_id'])
                    if num_pokemon > 1:
                        return WorkerResult.RUNNING
                    else:
                        return WorkerResult.SUCCESS

            try:
                if self.catch_pokemon(mon_to_catch) == WorkerResult.ERROR:
                    # give up incase something went wrong in our catch worker (ran out of balls, etc)
                    return WorkerResult.ERROR
                elif num_pokemon > 1:
                    # we have more pokemon to catch
                    return WorkerResult.RUNNING
            except ValueError:
                return WorkerResult.ERROR

        # all pokemon have been processed
        return WorkerResult.SUCCESS
예제 #18
0
 def uniq_caught(self):
     # generate pokemon string 'Snorlax, Pikachu' from list of ids
     return ', '.join([Pokemons.name_for(pok_id) for pok_id in self.uniq_pokemons_caught]) if self.uniq_pokemons_caught else ''
예제 #19
0
    def work(self):
        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            keep_best, keep_best_cp, keep_best_iv = self._validate_keep_best_config(
                pokemon_name)

            if keep_best:
                best_pokemon_ids = set()
                order_criteria = 'none'
                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)
                    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)
                    if order_criteria == 'cp':
                        order_criteria = 'cp and iv'
                    else:
                        order_criteria = 'iv'

                # remove best pokemons from all pokemons array
                all_pokemons = group
                best_pokemons = []
                for best_pokemon_id in best_pokemon_ids:
                    for pokemon in all_pokemons:
                        if best_pokemon_id == pokemon.id:
                            all_pokemons.remove(pokemon)
                            best_pokemons.append(pokemon)

                transfer_pokemons = [
                    pokemon for pokemon in all_pokemons
                    if self.should_release_pokemon(pokemon, True)
                ]

                if transfer_pokemons:
                    if best_pokemons:
                        self.emit_event(
                            'keep_best_release',
                            formatted=
                            "Keeping best {amount} {pokemon}, based on {criteria}",
                            data={
                                'amount': len(best_pokemons),
                                'pokemon': pokemon_name,
                                'criteria': order_criteria
                            })
                    for pokemon in transfer_pokemons:
                        self.release_pokemon(pokemon)
            else:
                group = sorted(group, key=lambda x: x.cp, reverse=True)
                for pokemon in group:
                    if self.should_release_pokemon(pokemon):
                        self.release_pokemon(pokemon)
예제 #20
0
    def work(self):
        # make sure we have SOME balls
        if sum([inventory.items().get(ball.value).count for ball in
    [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]]) <= 0:
            return WorkerResult.ERROR

        if self.bot.softban:
            if not hasattr(self.bot, "softban_global_warning") or \
                        (hasattr(self.bot, "softban_global_warning") and not self.bot.softban_global_warning):
                self.logger.info("Possible softban! Not trying to catch Pokemon.")
            self.bot.softban_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.softban_global_warning = False

	# Don't try to catch a Pokemon when catching is disabled.
        if self.bot.catch_disabled:
            if not hasattr(self.bot,"all_disabled_global_warning") or \
                        (hasattr(self.bot,"all_disabled_global_warning") and not self.bot.all_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Ignoring all Pokemon till then.".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.all_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.all_disabled_global_warning = False

        # check if we have already loaded a list
        if len(self.pokemon) <= 0:
            # load available pokemon by config settings
            if self.config.get('catch_visible_pokemon', True):
                self.get_visible_pokemon()
            if self.config.get('catch_lured_pokemon', True):
                self.get_lured_pokemon()
            if self._have_applied_incense() and self.config.get('catch_incensed_pokemon', True):
                self.get_incensed_pokemon()

            random.shuffle(self.pokemon)

        # Filter out already ignored mons
        if hasattr(self.bot,"hunter_locked_target"):
            if self.bot.hunter_locked_target != None:
                self.pokemon = filter(lambda x: x["pokemon_id"] not in self.ignored_while_looking, self.pokemon)
            elif len(self.ignored_while_looking) > 0:
                self.logger.info("No longer hunting for a Pokémon, resuming normal operations.")
                # Reset the ignored list when no longer needed.
                self.ignored_while_looking = []

        if hasattr(self.bot, "skipped_pokemon"):
            # Skip pokemon the catcher told us to ignore
            self.pokemon = [p for p in self.pokemon if p not in self.bot.skipped_pokemon]

        num_pokemon = len(self.pokemon)
        always_catch_family_of_vip = self.config.get('always_catch_family_of_vip', False)
        always_catch_trash = self.config.get('always_catch_trash', False)
        trash_pokemon = ["Caterpie", "Weedle", "Pidgey", "Pidgeotto", "Pidgeot", "Kakuna", "Beedrill", "Metapod", "Butterfree"]

        if num_pokemon > 0:
            # try catching
            mon_to_catch = self.pokemon.pop()
            is_vip = self._is_vip_pokemon(mon_to_catch) # hasattr(mon_to_catch, "pokemon_id") and self._is_vip_pokemon(mon_to_catch['pokemon_id'])
            # Always catch VIP Pokemons!
            if hasattr(self.bot,"hunter_locked_target") and self.bot.hunter_locked_target != None:
                bounty = self.bot.hunter_locked_target
                mon_name = Pokemons.name_for(mon_to_catch['pokemon_id'])
                bounty_name = Pokemons.name_for(bounty['pokemon_id'])

                family_catch = False
                trash_catch = False

                if always_catch_trash:
                    if mon_name in trash_pokemon:
                        self.logger.info("While on the hunt for {}, I found a {}! I want that Pokemon! Will try to catch...".format(bounty_name, mon_name))
                        trash_catch = True

                if always_catch_family_of_vip:
                    if mon_name != bounty_name:
                        if self._is_family_of_vip(mon_to_catch['pokemon_id']):
                            self.logger.info("While on the hunt for {}, I found a {}! I want that Pokemon! Will try to catch...".format(bounty_name, mon_name))
                            family_catch = True

                if not family_catch and not trash_catch:
                    if (mon_name != bounty_name and is_vip is False):
                        # This is not the Pokémon you are looking for...
                        self.logger.info("[Hunter locked a {}] Ignoring a {}".format(bounty_name, mon_name))
                        self.ignored_while_looking.append(mon_to_catch['pokemon_id'])

                        if num_pokemon > 1:
                            return WorkerResult.RUNNING
                        else:
                            return WorkerResult.SUCCESS
                    else:
                        # We have found a vip or our target...
                        if bounty_name == mon_name:
                            self.bot.hunter_locked_target = None
                            self.logger.info("Found my target {}!".format(bounty_name))
                        else:
                            self.logger.info("While on the hunt for {}, I found a {}! I want that Pokemon! Will try to catch...".format(bounty_name, mon_name))
            try:
                if self.catch_pokemon(mon_to_catch) == WorkerResult.ERROR:
                    # give up incase something went wrong in our catch worker (ran out of balls, etc)
                    return WorkerResult.ERROR
                elif num_pokemon > 1:
                    # we have more pokemon to catch
                    return WorkerResult.RUNNING
            except ValueError:
                return WorkerResult.ERROR

        # all pokemon have been processed
        return WorkerResult.SUCCESS
예제 #21
0
 def uniq_caught(self):
     # generate pokemon string 'Snorlax, Pikachu' from list of ids
     return ', '.join([
         Pokemons.name_for(pok_id) for pok_id in self.uniq_pokemons_caught
     ]) if self.uniq_pokemons_caught else ''
    def work(self):

        if not self._should_work():
            return

        pokemon_groups = self._release_pokemon_get_groups()
        for pokemon_id, group in pokemon_groups.iteritems():
            pokemon_name = Pokemons.name_for(pokemon_id)
            keep_best, keep_best_cp, keep_best_iv = self._validate_keep_best_config(pokemon_name)
            #TODO continue list possible criteria
            keep_best_possible_criteria = ['cp','iv', 'iv_attack', 'iv_defense', 'iv_stamina', 'moveset.attack_perfection','moveset.defense_perfection','hp','hp_max']
            keep_best_custom, keep_best_criteria, keep_amount = self._validate_keep_best_config_custom(pokemon_name, keep_best_possible_criteria)

            best_pokemon_ids = set()
            order_criteria = 'none'
            if keep_best:
                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.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.unique_id for pokemon in best_iv_pokemons)
                    if order_criteria == 'cp':
                        order_criteria = 'cp and iv'
                    else:
                        order_criteria = 'iv'
            elif keep_best_custom:
                limit = keep_amount
                keep_best_criteria = [str(keep_best_criteria[x]) for x in range(len(keep_best_criteria))] # not sure if the u of unicode will stay, so make it go away
                best_pokemons = sorted(group, key=attrgetter(*keep_best_criteria), reverse=True)[:limit]
                best_pokemon_ids = set(pokemon.unique_id for pokemon in best_pokemons)
                order_criteria = ' then '.join(keep_best_criteria)

            if keep_best or keep_best_custom:
                # remove best pokemons from all pokemons array
                all_pokemons = group
                best_pokemons = []
                for best_pokemon_id in best_pokemon_ids:
                    for pokemon in all_pokemons:
                        if best_pokemon_id == pokemon.unique_id:
                            all_pokemons.remove(pokemon)
                            best_pokemons.append(pokemon)

                transfer_pokemons = [pokemon for pokemon in all_pokemons if self.should_release_pokemon(pokemon,True)]

                if transfer_pokemons:
                    if best_pokemons:
                        self.emit_event(
                            'keep_best_release',
                            formatted="Keeping best {amount} {pokemon}, based on {criteria}",
                            data={
                                'amount': len(best_pokemons),
                                'pokemon': pokemon_name,
                                'criteria': order_criteria
                            }
                        )
                    for pokemon in transfer_pokemons:
                        self.release_pokemon(pokemon)
            else:
                group = sorted(group, key=lambda x: x.cp, reverse=True)
                for pokemon in group:
                    if self.should_release_pokemon(pokemon):
                        self.release_pokemon(pokemon)
예제 #23
0
    def determin_new_destination(self):
        gyms = self.get_gyms(get_raids=False)
        if len(gyms) == 0:
            if len(self.recent_gyms) == 0 and self._should_print():
                self.logger.info("No Gyms in range to scan!")
            return WorkerResult.SUCCESS

        self.logger.info("Inspecting %s gyms." % len(gyms))
        self.logger.info("Recent gyms: %s" % len(self.recent_gyms))
        self.logger.info("Active raid gyms: %s" % len(self.raid_gyms))
        teams = []
        for gym in gyms:
            # Ignore after done for 5 mins
            self.recent_gyms.append(gym["id"])

            if 'enabled' in gym:
                # Gym can be closed for a raid or something, skipp to the next
                if not gym['enabled']:
                    continue

            if 'owned_by_team' in gym:
                if gym["owned_by_team"] == 1:
                    teams.append("Mystic")
                elif gym["owned_by_team"] == 2:
                    teams.append("Valor")
                elif gym["owned_by_team"] == 3:
                    teams.append("Instinct")
                # else:
                #     self.logger.info("Unknown team? %s" % gym)

                if gym["owned_by_team"] == self.team:
                    if 'gym_display' in gym:
                        display = gym['gym_display']
                        if 'slots_available' in display:
                            if self.leave_at_least_spots > 0:
                                if display[
                                        'slots_available'] > self.leave_at_least_spots:
                                    self.logger.info(
                                        "Gym has %s open spots!" %
                                        display['slots_available'])
                                    self.destination = gym
                                    break
                                else:
                                    self.logger.info(
                                        "Gym has %s open spots, but we don't drop Pokemon in it because that would leave less than %s open spots"
                                        % (display['slots_available'],
                                           self.leave_at_least_spots))
                            else:
                                self.logger.info("Gym has %s open spots!" %
                                                 display['slots_available'])
                                self.destination = gym
                                break
            else:
                # self.logger.info("Found a Neutral gym?")
                # self.logger.info("Info: %s" % gym)
                self.destination = gym
                break

        if len(teams) > 0:
            count_teams = Counter(teams)
            self.logger.info(
                "Gym Teams %s", ", ".join('{}({})'.format(key, val)
                                          for key, val in count_teams.items()))

        # let's go for a raid if enabled and has raid tickets

        self.found_raid = False
        pokemon_in_raid = None
        if self.raid and (
                self.free_raid_tickets > 0 or self.paid_raid_tickets > 0
        ) and self.destination is None:  # Only check for raid if it's not slotting pokemons
            self.logger.info("Checking for eligable raids")
            self.recent_gyms = []
            gyms = self.get_gyms(get_raids=True)
            #print("\nRaw Gym Data: "+format(gyms)+"\n")
            for gym in gyms:
                # Ignore after done for 5 mins
                self.recent_gyms.append(gym["id"])
                if 'raid_info' in gym:
                    for level in self.raid_levels:
                        if level == gym['raid_info']['raid_level']:
                            org_time = int(
                                gym['raid_info']['raid_battle_ms']) / 1e3
                            raid_start_time = datetime.fromtimestamp(org_time)
                            org_time = int(
                                gym['raid_info']['raid_end_ms']) / 1e3
                            raid_end_time = datetime.fromtimestamp(org_time)
                            # check if raid has started
                            if raid_start_time < datetime.now():
                                #raid has started
                                timediff = raid_end_time - datetime.now()
                                results = divmod(
                                    timediff.days * 86400 + timediff.seconds,
                                    60)
                                details = fort_details(self.bot, gym['id'],
                                                       gym['latitude'],
                                                       gym['longitude'])
                                gym_name = details.get('name', 'Unknown')
                                #if on going raid, check if it's in list of raid pokemon
                                raid_pokemon_id = gym['raid_info'][
                                    'raid_pokemon']['pokemon_id']
                                raid_pokemon_name = Pokemons.name_for(
                                    raid_pokemon_id)
                                pokemon_in_raid = [
                                    p for p in self.raid_only
                                    if p in raid_pokemon_name
                                ]
                                if results[
                                        0] >= self.do_not_raid_last_x_mins and (
                                            len(pokemon_in_raid) > 0
                                            or len(self.raid_only) == 0):
                                    self.logger.info(
                                        "There is an on-going raid. Raid level: "
                                        + format(gym['raid_info']
                                                 ['raid_level']) + " Name: " +
                                        gym_name + " Ending in: " +
                                        format(results[0]) + " mins")
                                    self.logger.info("Raid Boss: " +
                                                     format(raid_pokemon_name))
                                    self.logger.info(
                                        "We have enough time for raid!")
                                    self.found_raid = True
                                    self.destination = gym
                                    break
                            else:
                                timediff = raid_start_time - datetime.now()
                                results = divmod(
                                    timediff.days * 86400 + timediff.seconds,
                                    60)
                                details = fort_details(self.bot, gym['id'],
                                                       gym['latitude'],
                                                       gym['longitude'])
                                gym_name = details.get('name', 'Unknown')
                                if results[0] <= self.wait_raid_start_mins:
                                    self.logger.info(
                                        "A raid is starting soon. Raid level: "
                                        + format(gym['raid_info']
                                                 ['raid_level']) + " Name: " +
                                        gym_name + " Raid starting in " +
                                        format(results[0]) + " mins")
                                    self.logger.info(
                                        "It is within " +
                                        format(self.wait_raid_start_mins) +
                                        " mins")
                                    self.found_raid = True
                                    self.destination = gym
                                    break
                    if self.found_raid:
                        break  # Get out from the 1st loop as well
                    else:
                        self.logger.info("No suitable raids available")
예제 #24
0
    def fetch(self):
        pokemons = []

        try:
            results = self.fetch_raw()

            # Parse results
            for result in results:
                iv = result.get(self.mappings.iv.param)
                id = result.get(self.mappings.id.param)
                name = self._get_closest_name(self._fixname(result.get(self.mappings.name.param)))
                latitude = result.get(self.mappings.latitude.param)
                longitude = result.get(self.mappings.longitude.param)
                expiration = result.get(self.mappings.expiration.param)
                encounter = result.get(self.mappings.encounter.param)
                spawnpoint = result.get(self.mappings.spawnpoint.param)

                # If this is a composite param, split it ("coords": "-31.415553, -64.190480")
                if self.mappings.latitude.param == self.mappings.longitude.param:
                    position = result.get(self.mappings.latitude.param).replace(" ", "").split(",")
                    latitude = position[0]
                    longitude = position[1]

                # Some sources block access to all pokemon, need to skip those!
                try:
                    float(latitude)
                    float(longitude)
                except ValueError:
                    # Seems to be blacked out, do next.
                    continue

                # Format the time accordingly. Pokemon times are in milliseconds!
                if self.mappings.expiration.exists and expiration:
                    if self.mappings.expiration.format == SniperSourceMappingTimeFormat.SECONDS:
                        expiration = expiration * 1000
                    elif self.mappings.expiration.format == SniperSourceMappingTimeFormat.UTC:
                        utc_date = datetime.strptime(expiration.replace("T", " ")[:19], self.time_mask)
                        unix_timestamp = calendar.timegm(utc_date.timetuple())
                        local_date = datetime.fromtimestamp(unix_timestamp)
                        local_date = local_date.replace(microsecond=utc_date.microsecond)
                        expiration = time.mktime(local_date.timetuple()) * 1000
                else:
                    minutes_to_expire = 3
                    seconds_per_minute = 60
                    expiration = (time.time() + minutes_to_expire * seconds_per_minute) * 1000

                # If either name or ID are invalid, fix it using each other
                if not name or not id:
                    if not name and id:
                        name = Pokemons.name_for(id)
                    if not id and name:
                        id = Pokemons.id_for(name)

                # Some type castings were specified for a better readability
                pokemons.append({
                    'iv': float(iv or 0),
                    'pokemon_id': int(id or 0),
                    'pokemon_name': str(name or ''),
                    'latitude': float(latitude or .0),
                    'longitude': float(longitude or .0),
                    'expiration_timestamp_ms': long(expiration or 0),
                    'last_modified_timestamp_ms': long(expiration or 0),
                    'encounter_id': long(encounter or 0),
                    'spawn_point_id': str(spawnpoint or '')
                })
        except requests.exceptions.Timeout:
            raise Exception("Fetching has timed out")
        except requests.exceptions.ConnectionError:
            raise Exception("Source not available")
        except:
            raise

        return pokemons
예제 #25
0
    def determin_new_destination(self):
        gyms = self.get_gyms(get_raids=False)
        if len(gyms) == 0:
            if len(self.recent_gyms) == 0 and self._should_print():
                self.logger.info("No Gyms in range to scan!")
            return WorkerResult.SUCCESS

        self.logger.info("Inspecting %s gyms." % len(gyms))
        self.logger.info("Recent gyms: %s" % len(self.recent_gyms))
        self.logger.info("Active raid gyms: %s" % len(self.raid_gyms))
        teams = []
        for gym in gyms:
            # Ignore after done for 5 mins
            self.recent_gyms.append(gym["id"])

            if 'enabled' in gym:
                # Gym can be closed for a raid or something, skipp to the next
                if not gym['enabled']:
                    continue
                    
            if 'owned_by_team' in gym:
                if gym["owned_by_team"] == 1:
                    teams.append("Mystic")
                elif gym["owned_by_team"] == 2:
                    teams.append("Valor")
                elif gym["owned_by_team"] == 3:
                    teams.append("Instinct")
                # else:
                #     self.logger.info("Unknown team? %s" % gym)

                if gym["owned_by_team"] == self.team:
                    if 'gym_display' in gym:
                        display = gym['gym_display']
                        if 'slots_available' in display:
                            if self.leave_at_least_spots > 0:
                                if display['slots_available'] > self.leave_at_least_spots:
                                    self.logger.info("Gym has %s open spots!" % display['slots_available'])
                                    self.destination = gym
                                    break
                                else:
                                    self.logger.info("Gym has %s open spots, but we don't drop Pokemon in it because that would leave less than %s open spots" % (display['slots_available'], self.leave_at_least_spots))
                            else:
                                self.logger.info("Gym has %s open spots!" % display['slots_available'])
                                self.destination = gym
                                break
            else:
                # self.logger.info("Found a Neutral gym?")
                # self.logger.info("Info: %s" % gym)
                self.destination = gym
                break
                
        if len(teams) > 0:
            count_teams = Counter(teams)
            self.logger.info("Gym Teams %s", ", ".join('{}({})'.format(key, val) for key, val in count_teams.items()))
                
        # let's go for a raid if enabled and has raid tickets
        
        self.found_raid = False
        pokemon_in_raid = None
        if self.raid and (self.free_raid_tickets > 0 or self.paid_raid_tickets > 0) and self.destination is None: # Only check for raid if it's not slotting pokemons 
            self.logger.info("Checking for eligable raids")
            self.recent_gyms = []
            gyms = self.get_gyms(get_raids=True)
            #print("\nRaw Gym Data: "+format(gyms)+"\n")
            for gym in gyms:
                # Ignore after done for 5 mins
                self.recent_gyms.append(gym["id"])
                if 'raid_info' in gym:
                    for level in self.raid_levels:
                        if level == gym['raid_info']['raid_level']:
                            org_time= int(gym['raid_info']['raid_battle_ms']) / 1e3
                            raid_start_time = datetime.fromtimestamp(org_time)
                            org_time= int(gym['raid_info']['raid_end_ms']) / 1e3
                            raid_end_time = datetime.fromtimestamp(org_time)
                            # check if raid has started
                            if raid_start_time < datetime.now():
                                #raid has started
                                timediff = raid_end_time - datetime.now()
                                results = divmod(timediff.days * 86400 + timediff.seconds, 60)
                                details = fort_details(self.bot, gym['id'], gym['latitude'], gym['longitude'])
                                gym_name = details.get('name', 'Unknown')
                                #if on going raid, check if it's in list of raid pokemon
                                raid_pokemon_id = gym['raid_info']['raid_pokemon']['pokemon_id']
                                raid_pokemon_name = Pokemons.name_for(raid_pokemon_id)
                                pokemon_in_raid = [p for p in self.raid_only if p in raid_pokemon_name]
                                if results[0] >= self.do_not_raid_last_x_mins and (len(pokemon_in_raid)>0 or len(self.raid_only)==0):
                                    self.logger.info("There is an on-going raid. Raid level: " + format(gym['raid_info']['raid_level'])+" Name: " + gym_name + " Ending in: "+format(results[0]) + " mins")
                                    self.logger.info("Raid Boss: " + format(raid_pokemon_name))
                                    self.logger.info("We have enough time for raid!")
                                    self.found_raid = True
                                    self.destination = gym
                                    break
                            else:
                                timediff = raid_start_time - datetime.now()
                                results = divmod(timediff.days * 86400 + timediff.seconds, 60)
                                details = fort_details(self.bot, gym['id'], gym['latitude'], gym['longitude'])
                                gym_name = details.get('name', 'Unknown')
                                if results[0] <= self.wait_raid_start_mins:
                                    self.logger.info("A raid is starting soon. Raid level: " + format(gym['raid_info']['raid_level'])+" Name: " + gym_name + " Raid starting in " + format(results[0]) + " mins")
                                    self.logger.info("It is within "+format(self.wait_raid_start_mins)+" mins")
                                    self.found_raid = True
                                    self.destination = gym
                                    break
                    if self.found_raid:
                        break # Get out from the 1st loop as well
                    else:
                        self.logger.info("No suitable raids available")