Example #1
0
 def work(self):
     if not self.next_point:
         self.next_point = next(self.points)
     point = self.next_point
     step_walker = StepWalker(self.bot, point['lat'], point['lng'])
     if step_walker.step():
         self.next_point = None
     return [point['lat'], point['lng']]
 def work(self):
     if not self.next_point:
         self.next_point = next(self.points)
     point = self.next_point
     step_walker = StepWalker(self.bot, point['lat'], point['lng'])
     if step_walker.step():
         self.next_point = None
     return [point['lat'], point['lng']]
Example #3
0
    def work(self):
        last_lat, last_lng, last_alt = self.bot.api.get_position()

        point = self.points[self.ptr]
        self.cnt += 1

        dist = distance(
            last_lat,
            last_lng,
            point['lat'],
            point['lng']
        )

        alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
        if self.bot.config.walk_max > 0:
            step_walker = StepWalker(
                self.bot,
                point['lat'],
                point['lng']
            )

            if self.cnt == 1:
                self.emit_event(
                    'position_update',
                    formatted="Walking from {last_position} to {current_position} ({distance} {distance_unit})",
                    data={
                        'last_position': (last_lat, last_lng, last_alt),
                        'current_position': (point['lat'], point['lng'], alt),
                        'distance': dist,
                        'distance_unit': 'm'
                    }
                )

            if step_walker.step():
                step_walker = None
        else:
            self.bot.api.set_position(point['lat'], point['lng'], alt)
            self.emit_event(
                'position_update',
                formatted="Teleported from {last_position} to {current_position} ({distance} {distance_unit})",
                data={
                    'last_position': (last_lat, last_lng, last_alt),
                    'current_position': (point['lat'], point['lng'], alt),
                    'distance': dist,
                    'distance_unit': 'm'
                }
            )

        if dist <= 1 or (self.bot.config.walk_min > 0 and step_walker == None):
            if self.ptr + self.direction >= len(self.points) or self.ptr + self.direction <= -1:
                self.direction *= -1
            if len(self.points) != 1:
                self.ptr += self.direction
            else:
                self.ptr = 0
            self.cnt = 0

        return [point['lat'], point['lng']]
Example #4
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                self.destination = worth_pokemons[0]
                self.lost_counter = 0

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join(p["name"] for p in pokemons))
                    self.no_log_until = now + 120

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.destination = None
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
            self.no_log_until = now + 30

        return WorkerResult.RUNNING
Example #5
0
    def work(self):
        last_lat = self.bot.api._position_lat
        last_lng = self.bot.api._position_lng
        last_alt = self.bot.api._position_alt

        point = self.points[self.ptr]
        lat = float(point['lat'])
        lng = float(point['lng'])
        alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
        if 'alt' in point:
            alt = float(point['alt'])

        if self.bot.config.walk_max > 0:
            step_walker = StepWalker(self.bot, lat, lng)

            is_at_destination = False
            if step_walker.step():
                is_at_destination = True

        else:
            self.bot.api.set_position(lat, lng, alt)

        dist = distance(last_lat, last_lng, lat, lng)

        self.emit_event(
            'position_update',
            formatted=
            "Walking from {last_position} to {current_position}, distance left: ({distance} {distance_unit}) ..",
            data={
                'last_position': (last_lat, last_lng, last_alt),
                'current_position': (lat, lng, alt),
                'distance': dist,
                'distance_unit': 'm'
            })

        if dist <= 1 or (self.bot.config.walk_min > 0 and is_at_destination):
            if (self.ptr + 1) == len(self.points):
                self.ptr = 0
                if self.path_mode == 'linear':
                    self.points = list(reversed(self.points))
                if self.number_lap_max >= 0:
                    self.number_lap += 1
                    self.emit_event(
                        'path_lap_update',
                        formatted=
                        "number lap : {number_lap} / {number_lap_max}",
                        data={
                            'number_lap': str(self.number_lap),
                            'number_lap_max': str(self.number_lap_max)
                        })
                    if self.number_lap >= self.number_lap_max:
                        self.endLaps()
            else:
                self.ptr += 1

        return [lat, lng]
def walker_factory(name, bot, dest_lat, dest_lng, *args, **kwargs):
    '''
    Charlie and the Walker Factory
    '''
    if 'StepWalker' == name:
        ret = StepWalker(bot, dest_lat, dest_lng)
    elif 'PolylineWalker' == name:
        try:
            ret = PolylineWalker(bot, dest_lat, dest_lng)
        except:
            ret = StepWalker(bot, dest_lat, dest_lng)
    return ret
Example #7
0
    def work(self):
        last_lat, last_lng, last_alt = self.bot.api.get_position()

        point = self.points[self.ptr]
        self.cnt += 1

        dist = distance(last_lat, last_lng, point['lat'], point['lng'])

        alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
        if self.bot.config.walk_max > 0:
            step_walker = StepWalker(self.bot, point['lat'], point['lng'])

            if self.cnt == 1:
                self.emit_event(
                    'position_update',
                    formatted=
                    "Walking from {last_position} to {current_position} ({distance} {distance_unit})",
                    data={
                        'last_position': (last_lat, last_lng, last_alt),
                        'current_position': (point['lat'], point['lng'], alt),
                        'distance': dist,
                        'distance_unit': 'm'
                    })

            if step_walker.step():
                step_walker = None
        else:
            self.bot.api.set_position(point['lat'], point['lng'], alt)
            self.emit_event(
                'position_update',
                formatted=
                "Teleported from {last_position} to {current_position} ({distance} {distance_unit})",
                data={
                    'last_position': (last_lat, last_lng, last_alt),
                    'current_position': (point['lat'], point['lng'], alt),
                    'distance': dist,
                    'distance_unit': 'm'
                })

        if dist <= 1 or (self.bot.config.walk_min > 0 and step_walker == None):
            if self.ptr + self.direction >= len(
                    self.points) or self.ptr + self.direction <= -1:
                self.direction *= -1
            if len(self.points) != 1:
                self.ptr += self.direction
            else:
                self.ptr = 0
            self.cnt = 0

        return [point['lat'], point['lng']]
Example #8
0
    def test_small_distance_same_spot(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        sw = StepWalker(self.bot, 0, 0, precision=0.0)
        self.assertEqual(sw.dest_lat, 0, 'dest_lat should be 0')
        self.assertEqual(sw.dest_lng, 0, 'dest_lng should be 0')

        @mock.patch('random.uniform')
        def run_step(mock_random):
            mock_random.return_value = 0.0
            return sw.step()

        moveInprecision = run_step()

        self.assertTrue(moveInprecision, 'step should return True')
        distance = Geodesic.WGS84.Inverse(0.0, 0.0, self.bot.position[0],
                                          self.bot.position[1])["s12"]
        self.assertTrue(0.0 <= distance <= (sw.precision + sw.epsilon))

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #9
0
    def test_normalized_distance_times_2(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 2
        self.bot.config.walk_min = 2

        sw = StepWalker(self.bot, 0.1, 0.1, precision=0.0)
        self.assertTrue(sw.dest_lat > 0)
        self.assertTrue(sw.dest_lng > 0)

        @mock.patch('random.uniform')
        def run_step(mock_random):
            mock_random.return_value = 0.0
            return sw.step()

        stayInPlace = run_step()
        self.assertFalse(stayInPlace)

        self.assertAlmostEqual(self.bot.position[0],
                               NORMALIZED_LAT_LNG_DISTANCE[0] * 2,
                               places=6)
        self.assertAlmostEqual(self.bot.position[1],
                               NORMALIZED_LAT_LNG_DISTANCE[1] * 2,
                               places=6)

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #10
0
    def test_teleport(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 4
        self.bot.config.walk_min = 2

        sw = StepWalker(self.bot, 10, 10, precision=0.0)
        self.assertEqual(sw.dest_lat, 10)
        self.assertEqual(sw.dest_lng, 10)

        @mock.patch('random.uniform')
        def run_step(mock_random):
            mock_random.return_value = 0.0
            return sw.step(speed=float("inf"))

        finishedWalking = run_step()
        self.assertTrue(finishedWalking, 'step should return True')
        total_distance = Geodesic.WGS84.Inverse(0.0, 0.0, 10, 10)["s12"]
        distance = Geodesic.WGS84.Inverse(0.0, 0.0, self.bot.position[0],
                                          self.bot.position[1])["s12"]
        self.assertTrue(0.0 <= abs(total_distance -
                                   distance) <= (sw.precision + sw.epsilon))

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #11
0
    def test_small_distance_small_step(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        # distance from origin 0,0 to 1e-6, 1e-6 is 0.157253373328 meters
        total_distance = Geodesic.WGS84.Inverse(0.0, 0.0, 1e-6, 1e-6)["s12"]
        # we take a precision bigger then the total value...
        sw = StepWalker(self.bot, 1e-6, 1e-6, precision=0.2)
        self.assertEqual(sw.dest_lat, 1e-6)
        self.assertEqual(sw.dest_lng, 1e-6)

        @mock.patch('random.uniform')
        def run_step(mock_random):
            mock_random.return_value = 0.0
            return sw.step()

        moveInprecistion = run_step()
        self.assertTrue(moveInprecistion, 'step should return True')

        distance = Geodesic.WGS84.Inverse(0.0, 0.0, self.bot.position[0],
                                          self.bot.position[1])["s12"]
        self.assertTrue(0.0 <= abs(total_distance -
                                   distance) <= (sw.precision + sw.epsilon))

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #12
0
    def test_small_distance_same_spot(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        sw = StepWalker(self.bot, 0, 0)
        self.assertEqual(sw.dLat, 0, 'dLat should be 0')
        self.assertEqual(sw.dLng, 0, 'dLng should be 0')

        self.assertTrue(sw.step(), 'step should return True')
        self.assertTrue(self.lat == self.bot.position[0])
        self.assertTrue(self.lng == self.bot.position[1])

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #13
0
    def test_normalized_distance_times_2(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 2
        self.bot.config.walk_min = 2

        sw = StepWalker(self.bot, 0.1, 0.1, precision=0.0)
        self.assertTrue(sw.dLat > 0)
        self.assertTrue(sw.dLng > 0)

        stayInPlace = sw.step()
        self.assertFalse(stayInPlace)

        self.assertTrue(float_equal(self.lat, NORMALIZED_LAT_LNG_DISTANCE[0] * 2))
        self.assertTrue(float_equal(self.lng, NORMALIZED_LAT_LNG_DISTANCE[1] * 2))

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #14
0
    def test_normalized_distance(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        sw = StepWalker(self.bot, 0.1, 0.1)
        self.assertGreater(sw.dLat, 0)
        self.assertGreater(sw.dLng, 0)

        stayInPlace = sw.step()
        self.assertFalse(stayInPlace)

        self.assertTrue(float_equal(self.lat, NORMALIZED_LAT_LNG_DISTANCE_STEP))
        self.assertTrue(float_equal(self.lng, NORMALIZED_LAT_LNG_DISTANCE_STEP))

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #15
0
    def test_small_distance_small_step(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        sw = StepWalker(self.bot, 1e-5, 1e-5)
        self.assertEqual(sw.dLat, 0)
        self.assertEqual(sw.dLng, 0)

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #16
0
    def test_big_distances(self):
        walk_max = self.bot.config.walk_max
        walk_min = self.bot.config.walk_min

        self.bot.config.walk_max = 1
        self.bot.config.walk_min = 1

        sw = StepWalker(self.bot, 10, 10, precision=0.0)
        self.assertEqual(sw.dest_lat, 10)
        self.assertEqual(sw.dest_lng, 10)

        @mock.patch('random.uniform')
        def run_step(mock_random):
            mock_random.return_value = 0.0
            return sw.step()

        finishedWalking = run_step()
        self.assertFalse(finishedWalking, 'step should return False')
        self.assertAlmostEqual(self.bot.position[0],
                               NORMALIZED_LAT_LNG_DISTANCE[0],
                               places=6)

        self.bot.config.walk_max = walk_max
        self.bot.config.walk_min = walk_min
Example #17
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.bot.catch_disabled:
            # When catching is disabled, drop the target.
            if self.destination is not None:
                self.destination = None
                self.last_cell_id = None

            if not hasattr(self.bot, "hunter_disabled_global_warning") or \
                        (hasattr(self.bot, "hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.bot.softban:
            # At softban, drop target
            if self.destination is not None:
                self.destination = None
                self.last_cell_id = None
                self.hunting_trash = False

            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

        if self.config_disabled_while_camping and hasattr(self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            self.hunting_trash = False
            return WorkerResult.SUCCESS

        if hasattr(self.bot,"hunter_locked_target"):
            if self.destination is not None and self.bot.hunter_locked_target is not None:
                if self.destination is not self.bot.hunter_locked_target:
                    self.logger.info("Locked on to a different target than destination??")
                    self.bot.hunter_locked_target = None

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info("We found a %(name)s while hunting.", self.destination)
                # self.recent_tries.append(self.destination['pokemon_id'])
                self.previous_destination = self.destination
                self.destination = None
                self.hunting_trash = False
                self.bot.hunter_locked_target = None
                self.lost_counter = 0
                self.lost_map_counter = 0
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                    return WorkerResult.SUCCESS
                else:
                    self.logger.info("Electing new target....")

            if self.destination_vanished():
                self.logger.info("Darn, target got away!")
                # self.recent_tries.append(self.destination['pokemon_id'])
                self.previous_destination = self.destination
                self.destination = None
                self.hunting_trash = False
                self.bot.hunter_locked_target = None
                self.lost_counter = 0
                self.lost_map_counter = 0
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                    return WorkerResult.SUCCESS
                else:
                    self.logger.info("Electing new target....")

        now = time.time()
        pokemons = self.get_nearby_pokemons()

        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries, pokemons)
        trash_mons = ["Caterpie", "Weedle", "Pidgey", "Pidgeotto", "Pidgeot", "Kakuna", "Beedrill", "Metapod", "Butterfree"]

        if self.destination is not None:
            target_mons = filter(lambda x: x["name"] is self.destination["name"], pokemons)
            if self.no_log_until < now:
                # self.logger.info("Targets on sightings: %s" % len(target_mons))
                if len(pokemons) > 0:
                    if len(target_mons) < 1:
                        # Target off sightings; must be getting close
                        # Drops of at about 120 meters to target...
                        distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
                        if (distance > 125 and self.lost_map_counter > 4) or self.lost_map_counter > 10:
                            # If > 120 meter => must be gone?
                            # Searching for 10 times, give up...
                            self.logger.info("It seems %(name)s is no longer there!", self.destination)
                            self.destination = None
                            self.hunting_trash = False
                            self.bot.hunter_locked_target = None
                            self.lost_map_counter = 0
                            self.lost_counter = 0
                            if self.config_enable_cooldown:
                                wait = uniform(120, 600)
                                self.no_hunt_until = time.time() + wait
                                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                                return WorkerResult.SUCCESS
                            else:
                                self.logger.info("Electing new target....")
                        else:
                            self.lost_map_counter += 1
                    else:
                        self.lost_map_counter = 0
                else:
                    self.logger.info("No sightings available at the moment...")

        if self.config_hunt_for_trash and self.hunting_trash is False and (self.destination is None or not self._is_vip_pokemon(self.destination) ):
            # Okay, we should hunt for trash if the bag is almost full
            pokemons.sort(key=lambda p: p["distance"])
            possible_targets = filter(lambda x: x["name"] in trash_mons, pokemons)
            if self.pokemon_slots_left() <= self.config_trash_hunt_open_slots:
                if self.no_log_until < now:
                    self.logger.info("Less than %s slots left to fill, starting hunt for trash" % self.config_trash_hunt_open_slots)
                    if len(possible_targets) is 0:
                        self.logger.info("No trash pokemon around...")
                for pokemon in possible_targets:
                    if self.destination is not None:
                        self.logger.info("Trash hunt takes priority! Changing target...")
                    self.hunting_trash = True
                    self.destination = pokemon
                    self.lost_counter = 0
                    self.hunt_started_at = datetime.now()
                    self.logger.info("Hunting for trash at %(distance).2f meters: %(name)s", self.destination)
                    self.set_target()
                    # We have a target
                    return WorkerResult.RUNNING

        if self.config_hunt_for_trash and self.hunting_trash:
            if self.pokemon_slots_left() > self.config_trash_hunt_open_slots:
                self.logger.info("No longer trying to fill the bag. Electing new target....")
                self.hunting_trash = False
                self.destination = None
            # Closer target?
            if self.no_log_until < now:
                # Don't check every tick!
                if self.destination is not None and len(pokemons) > 0:
                    pokemons.sort(key=lambda p: p["distance"])
                    possible_targets = filter(lambda x: x["name"] in trash_mons, pokemons)
                    # Check for a closer target
                    self.destination["distance"] = self.get_distance(self.bot.position, self.destination)
                    for pokemon in possible_targets:
                        if pokemon is not self.destination:
                            if round(pokemon["distance"], 2) >= round(self.destination["distance"], 2):
                                # further away!
                                break
                            self.logger.info("Found a closer target: %s < %s" % (pokemon["distance"], self.destination["distance"]))
                            if self.destination is not None:
                                self.logger.info("Closer trash hunt takes priority! Changing target...")
                            self.hunting_trash = True
                            self.destination = pokemon
                            self.lost_counter = 0
                            self.hunt_started_at = datetime.now()
                            self.logger.info("New target at %(distance).2f meters: %(name)s", self.destination)
                            self.set_target()
                            # We have a target
                            return WorkerResult.RUNNING

        if self.destination is None:
            
            # Use this time for shadowban check
            if self.shadowban_detection:
                if not self.check_rare_pokemons(pokemons):
                    self.no_rare_counts += 1
                    self.logger.info("[Shadow Ban Detection] I cannot find any rares/uncommon pokemons. Count: " + format(self.no_rare_counts))
                else:
                    # Reset to zero
                    self.logger.info("[Shadow Ban Detection] Rares/uncommon pokemons are spotted")
                    self.no_rare_counts = 0
                
                if self.no_rare_counts > 3: 
                    # If more than 3 times we can't find any rares, we alert user of possible shadow bans
                    self.emit_event(
                        'shadowban_alert',
                        formatted="\033[91m[Shadow Ban Alert]\033[0m More than 3 occassions we could not find any rare pokemons."
                        )
                    if self.no_rare_counts == 4: 
                        # Record in database once per run
                        try:
                            with self.bot.database as conn:
                                c = conn.cursor()
                                c.execute("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='shadowban_log'")
                            result = c.fetchone()

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

                        except IOError as e:
                            self.logger.info('[x] Error while opening location file: %s' % e)
                    
                    if self.exit_if_shadowbanned:
                        sys.exit(0)
 
            worth_pokemons = self.get_worth_pokemons(pokemons, self.config_hunt_closest_first)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                # random.shuffle(worth_pokemons)
                if self.config_hunt_closest_first:
                    # Priotize closer pokemon
                    worth_pokemons.sort(key=lambda p: p["distance"])
                else:
                    random.shuffle(worth_pokemons)
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]

                if self.previous_destination is not None:
                    # Check if we are hunting the same target again...
                    if self.previous_destination["pokemon_id"] == self.destination["pokemon_id"]:
                        # Hunting the same pokemon again?
                        if "fort_id" in self.previous_destination and "fort_id" in self.destination and \
                        self.previous_destination["fort_id"] == self.destination["fort_id"]:
                            # Hunting the same target again?
                            if len(worth_pokemons) > 1:
                                self.destination = worth_pokemons[1]
                        else:
                            # Checking if it's the same distance...
                            self.previous_destination["distance"] = self.get_distance(self.bot.start_position, self.previous_destination)
                            self.destination["distance"] = self.get_distance(self.bot.start_position, self.destination)
                            if round(self.previous_destination["distance"], 2) == round(self.destination["distance"], 2):
                                self.logger.info("Likely we are trying the same Pokemon again")
                                if len(worth_pokemons) > 1:
                                    self.destination = worth_pokemons[1]

                    if self.previous_destination == self.destination:
                        # We already caught that Pokemon!
                        if len(worth_pokemons) > 1:
                            self.destination = worth_pokemons[1]

                self.set_target()
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                if self._is_vip_pokemon(self.destination) and self.config_lock_on_target:
                    self.logger.info("This is a VIP Pokemon! Locking on to target!")
                    self.bot.hunter_locked_target = self.destination
                elif self._is_family_of_vip(self.destination) and self.config_treat_family_of_vip_as_vip and self.config_lock_on_target:
                    self.logger.info("This Pokemon is family of a VIP! Locking target!")
                    self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info("I need a %(name)s to complete the Pokedex! I have %(candies)s candies.", self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60
                # We have a target
                return WorkerResult.SUCCESS
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names) # unicode object, no lower? , key=str.lower)
                    if len(names) > 0:
                        self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join('{}({})'.format(key, val) for key, val in names.items()))
                    else:
                        self.logger.info("No sightings available at the moment...")
                    self.no_log_until = now + 120
                    self.destination = None
                    if self.config_enable_cooldown:
                        wait = uniform(120, 360)
                        self.no_hunt_until = now + wait
                        self.logger.info("Will look again around {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        # Make sure a VIP is treated that way
        if self.config_lock_on_target and self.bot.hunter_locked_target is None and self.destination is not None:
            if self._is_vip_pokemon(self.destination):
                self.bot.hunter_locked_target = self.destination
        #Check if we are treating Family of VIP as VIP
        if self.config_treat_family_of_vip_as_vip and self.destination is not None:
            if self._is_family_of_vip(self.destination):
                # We're hunting for family, so we need to check if we find a VIP
                if self.no_log_until < now:
                    # Not every tick please
                    possible_targets = filter(lambda p: self._is_vip_pokemon(p), pokemons)
                    # Update the distance to targets
                    for p in possible_targets:
                        p["distance"] = self.get_distance(self.bot.position, p)
                    possible_targets.sort(key=lambda p: p["distance"])
                    if len(possible_targets) > 0:
                        # Check if it's not the same mon...
                        if possible_targets[0]["name"] != self.destination["name"]:
                            self.logger.info("We found a real VIP while hunting for %(name)s", self.destination)
                            self.destination = possible_targets[0]
                            self.bot.hunter_locked_target = self.destination
                            self.lost_counter = 0
                            self.hunt_started_at = datetime.now()
                            self.logger.info("New VIP target at %(distance).2f meters: %(name)s", self.destination)
                            self.set_target()
                            # We have a target
                            return WorkerResult.RUNNING

        # Now we check if there is a VIP target closer by
        if self.destination is not None and self.bot.hunter_locked_target is self.destination:
            # Hunting a VIP, checking for closer VIP target
            if self.no_log_until < now:
                # Not every tick please
                possible_targets = filter(lambda p: self._is_vip_pokemon(p), pokemons)
                # Update the distance to targets
                for p in possible_targets:
                    p["distance"] = self.get_distance(self.bot.position, p)
                possible_targets.sort(key=lambda p: p["distance"])
                # Check for a closer target
                self.destination["distance"] = self.get_distance(self.bot.position, self.destination)
                for pokemon in possible_targets:
                    if pokemon is not self.destination:
                        if round(pokemon["distance"], 2) >= round(self.destination["distance"], 2):
                            # further away!
                            break
                        with self.bot.database as conn:
                            c = conn.cursor()
                            c.execute(
                                "SELECT COUNT(pokemon) FROM catch_log where pokemon = '{}' and  datetime(dated, 'localtime') > Datetime('{}')".format(pokemon["name"], self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))
                        # Now check if there is 1 or more caught
                        amount = c.fetchone()[0]
                        if amount > 0:
                            # We caught this pokemon recently, skip it
                            continue
                        if self.config_treat_family_of_vip_as_vip and self._is_family_of_vip(pokemon):
                            if self._is_vip_pokemon(self.destination):
                                self.logger.info("Seeing a familymember of a VIP at %(distance).2f meters: %(name)s", pokemon)
                                self.logger.info("Not hunting down because we are locked to a real VIP: %(name)s", self.destination)
                                continue
                            else:
                                self.logger.info("Closer (is distance) familymember of VIP found!")

                        self.logger.info("Found a closer VIP target: %s < %s" % (pokemon["distance"], self.destination["distance"]))
                        if self.destination is not None:
                            self.logger.info("Closer VIP hunt takes priority! Changing target...")
                        self.destination = pokemon
                        self.bot.hunter_locked_target = self.destination
                        self.lost_counter = 0
                        self.hunt_started_at = datetime.now()
                        self.logger.info("New VIP target at %(distance).2f meters: %(name)s", self.destination)
                        self.set_target()
                        # We have a target
                        return WorkerResult.RUNNING
                

        # Check if there is a VIP around to hunt
        if (self.destination is not None and
                self.config_lock_on_target and
                self.config_lock_vip_only and
                self.bot.hunter_locked_target is None):
            worth_pokemons = self.get_worth_pokemons(pokemons)
            # We have a none VIP target set, check for VIP targets!
            if len(worth_pokemons) > 0:
                for pokemon in worth_pokemons:
                    if self._is_vip_pokemon(pokemon):
                        self.hunting_trash = False
                        self.destination = pokemon
                        self.lost_counter = 0
                        self.hunt_started_at = datetime.now()
                        self.set_target()
                        if self.config_lock_on_target:
                            self.bot.hunter_locked_target = self.destination
                        self.logger.info("Spotted a VIP Pokemon! Looking for a %(name)s at %(distance).2f.", self.destination)
                        return WorkerResult.SUCCESS

        if self.destination is None:
            if self.no_log_until < now:
                self.logger.info("Nothing to hunt.")
            return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.previous_destination = self.destination
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        # Determin if we are allowed to run to a VIP
        different_target = False
        if self.destination is not None:
            if self.previous_destination is None:
                self.previous_destination = self.destination
            elif self.previous_destination is not self.destination:
                different_target = True
                self.previous_destination = self.destination

        if self.config_run_to_vip and self._is_vip_pokemon(self.destination):
            if self.runs_to_vips > 3:
                self.logger.info("Ran to 3 Pokemon in a row. Cooling down...")
                self.runs_to_vips = 0
                speed = None
            else:
                speed = self.bot.config.walk_max
                if different_target:
                    self.runs_to_vips += 1
        else:
            speed = None

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
            self.hunting_trash = False
        elif self.walker.step(speed):
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s", self.destination)
                if self.search_points == []:
                    self.walker = StepWalker(self.bot, self.destination['latitude'], self.destination['longitude'])
                else:
                    self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter is 3:
                # Try another walker
                self.logger.info("Having difficulty walking to target, changing walker!")
                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.distance_counter += 1

            if self.distance_counter >= 6:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info("I cant move toward %(name)s! Aborting search.", self.destination)
                self.hunting_trash = False
                self.bot.hunter_locked_target = None
                self.destination = None
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                unit = self.bot.config.distance_unit  # Unit to use when printing formatted distance
                if speed is not None:
                    self.emit_event(
                        'moving_to_hunter_target',
                        formatted="Running towards VIP target {target_name} - {distance}",
                        data={
                            'target_name': u"{}".format(self.destination["name"]),
                            'distance': format_dist(distance, unit),
                        }
                    )
                else:
                    self.emit_event(
                        'moving_to_hunter_target',
                        formatted="Moving towards target {target_name} - {distance}",
                        data={
                            'target_name': u"{}".format(self.destination["name"]),
                            'distance': format_dist(distance, unit),
                        }
                    )
                # self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 5

        return WorkerResult.RUNNING
Example #18
0
 def test_big_distances(self):
     # FIXME currently the StepWalker acts like it won't move if big distances gives as input
     # see args below
     # with self.assertRaises(RuntimeError):
     sw = StepWalker(self.bot, 10, 10)
     sw.step() # equals True i.e act like the distance is too short for a step
Example #19
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.config_disabled_while_camping and hasattr(
                self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info(
                    "All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled"
                    .format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        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

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info(
                    "We found a %(name)s while hunting. Aborting the current search.",
                    self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = time.time() + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()
        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries,
                          pokemons)

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                random.shuffle(worth_pokemons)
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info(
                    "New destination at %(distance).2f meters: %(name)s",
                    self.destination)
                if self._is_vip_pokemon(self.destination):
                    self.logger.info("This is a VIP Pokemon! Starting hunt.")
                    if self.config_lock_on_target:
                        self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info(
                        "I need a %(name)s to complete the Pokedex! I have %(candies)s candies.",
                        self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(
                        self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot,
                                                 self.search_points[0][0],
                                                 self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[
                        1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names)  # unicode object, no lower? , key=str.lower)

                    self.logger.info(
                        "There is no nearby pokemon worth hunting down [%s]",
                        ", ".join('{}({})'.format(key, val)
                                  for key, val in names.items()))
                    self.no_log_until = now + 120
                    self.destination = None
                    wait = uniform(120, 600)
                    self.no_hunt_until = now + wait
                    self.logger.info("Will look again around {}.".format(
                        (datetime.now() +
                         timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info(
                    "We found a %(name)s while hunting. Aborting the current search.",
                    self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"]
               for p in self.bot.cell["catchable_pokemons"] +
               self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"]
                       for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s",
                                 self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0],
                                         self.search_points[0][1])
                self.search_points = self.search_points[
                    1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(
                self.bot.position,
                (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter >= 3:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info(
                    "I cant move toward %(name)s! Aborting search.",
                    self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                self.logger.info("Moving to destination at %s meters: %s",
                                 round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 30

        return WorkerResult.RUNNING
Example #20
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.config_disabled_while_camping and hasattr(self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = time.time() + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()
        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries, pokemons)

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                random.shuffle(worth_pokemons)
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                if self._is_vip_pokemon(self.destination):
                    self.logger.info("This is a VIP Pokemon! Starting hunt.")
                    if self.config_lock_on_target:
                        self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info("I need a %(name)s to complete the Pokedex! I have %(candies)s candies.", self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names) # unicode object, no lower? , key=str.lower)

                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join('{}({})'.format(key, val) for key, val in names.items()))
                    self.no_log_until = now + 120
                    self.destination = None
                    wait = uniform(120, 600)
                    self.no_hunt_until = now + wait
                    self.logger.info("Will look again around {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter >= 3:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info("I cant move toward %(name)s! Aborting search.", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 30

        return WorkerResult.RUNNING
Example #21
0
class PokemonHunter(BaseTask):
    SUPPORTED_TASK_API_VERSION = 1

    def __init__(self, bot, config):
        super(PokemonHunter, self).__init__(bot, config)

    def initialize(self):
        self.notified_second_gen = []
        self.destination = None
        self.walker = None
        self.search_cell_id = None
        self.search_points = []
        self.lost_counter = 0
        self.no_log_until = 0
        self.distance_to_target = 0
        self.distance_counter = 0
        self.recent_tries = []
        self.no_hunt_until = None
        self.hunt_started_at = None

        self.config_max_distance = self.config.get("max_distance", 2000)
        self.config_hunt_all = self.config.get("hunt_all", False)
        self.config_hunt_vip = self.config.get("hunt_vip", True)
        self.config_hunt_pokedex = self.config.get("hunt_pokedex", True)
        # Lock on Target; ignore all other Pokémon until we found our target.
        self.config_lock_on_target = self.config.get("lock_on_target", False)
        # Lock only VIP Pokemon (unseen / VIP)
        self.config_lock_vip_only = self.config.get("lock_vip_only", True)
        # If we are camping forts, disable hunting (see CampFort)
        self.config_disabled_while_camping = self.config.get("disabled_while_camping", True)
        # Hunt unseens as VIP?
        self.config_treat_unseen_as_vip = self.config.get("treat_unseen_as_vip", True)
        self.bot.hunter_locked_target = None

    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.config_disabled_while_camping and hasattr(self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = time.time() + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()
        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries, pokemons)

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                random.shuffle(worth_pokemons)
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                if self._is_vip_pokemon(self.destination):
                    self.logger.info("This is a VIP Pokemon! Starting hunt.")
                    if self.config_lock_on_target:
                        self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info("I need a %(name)s to complete the Pokedex! I have %(candies)s candies.", self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names) # unicode object, no lower? , key=str.lower)

                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join('{}({})'.format(key, val) for key, val in names.items()))
                    self.no_log_until = now + 120
                    self.destination = None
                    wait = uniform(120, 600)
                    self.no_hunt_until = now + wait
                    self.logger.info("Will look again around {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter >= 3:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info("I cant move toward %(name)s! Aborting search.", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 30

        return WorkerResult.RUNNING

    def get_pokeball_count(self):
        return sum([inventory.items().get(ball.value).count for ball in [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]])

    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [p for p in self.bot.cell["nearby_pokemons"] if self.get_distance(self.bot.start_position, p) <= radius]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, p)
            pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])
            pokemon["candies"] = inventory.candies().get(pokemon["pokemon_id"]).quantity

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons

    def _is_vip_pokemon(self, pokemon):
        # 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(pokemon["name"]) == {} or (self.config_treat_unseen_as_vip and not inventory.pokedex().seen(pokemon["pokemon_id"])):
            return True

    def _is_needed_pokedex(self, pokemon):
        candies = inventory.candies().get(pokemon["pokemon_id"]).quantity
        if candies > 150:
            # We have enough candies, pass on hunting this Pokemon
            return False

        # get family ids, gets ALL ids, also for previous evo!
        # We could see a Ivysaur on the map, and need a Bulbasaur
        # Then we have no need for a Ivysaur. If we see a Bulbasaur and need
        # a Ivysaur, then we DO need this pokemon.
        got_current_evo = False
        ids = []
        for fid in self.get_family_ids(pokemon):
            if got_current_evo:
                ids += [fid]
            else:
                if fid == pokemon["pokemon_id"]:
                    ids += [fid]
                    got_current_evo = True
        # Check if we need this, or a next EVO in the Pokedex
        if any(not inventory.pokedex().seen(fid) for fid in ids):
            return True

    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [p for p in pokemons if p["name"] in self.bot.config.vips]

            if self.config_hunt_pokedex:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and self._is_needed_pokedex(p)]

        worth_pokemons.sort(key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons

    def get_family_ids(self, pokemon):
        family_id = inventory.pokemons().data_for(pokemon["pokemon_id"]).first_evolution_id
        ids = [family_id]
        ids += inventory.pokemons().data_for(family_id).next_evolutions_all[:]

        return ids

    def get_distance(self, location, pokemon):
        return great_circle(location, (pokemon["latitude"], pokemon["longitude"])).meters

    def get_search_points(self, cell_id):
        points = []

        # For cell level 15
        for c in Cell(CellId(cell_id)).subdivide():
            for cc in c.subdivide():
                latlng = LatLng.from_point(cc.get_center())
                point = (latlng.lat().degrees, latlng.lng().degrees)
                points.append(point)

        points[0], points[1] = points[1], points[0]
        points[14], points[15] = points[15], points[14]
        point = points.pop(2)
        points.insert(7, point)
        point = points.pop(13)
        points.insert(8, point)

        closest = min(points, key=lambda p: great_circle(self.bot.position, p).meters)
        index = points.index(closest)

        return points[index:] + points[:index]

    def destination_caught(self):
        # self.logger.info("Searching for a {} since {}".format(self.destination["name"], self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute(
                "SELECT COUNT(pokemon) FROM catch_log where pokemon = '{}' and  datetime(dated, 'localtime') > Datetime('{}')".format(self.destination["name"], self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))
        # Now check if there is 1 or more caught
        amount = c.fetchone()[0]
        caught = amount > 0
        if caught:
            self.logger.info("We caught {} {}(s) since {}".format(amount, self.destination["name"], self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))

        return caught
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info(
                    "All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled"
                    .format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                self.destination = worth_pokemons[0]
                self.lost_counter = 0

                self.logger.info(
                    "New destination at %(distance).2f meters: %(name)s",
                    self.destination)
                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(
                        self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot,
                                                 self.search_points[0][0],
                                                 self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[
                        1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    self.logger.info(
                        "There is no nearby pokemon worth hunting down [%s]",
                        ", ".join(p["name"] for p in pokemons))
                    self.no_log_until = now + 120

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"]
               for p in self.bot.cell["catchable_pokemons"] +
               self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"]
                       for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.destination = None
            else:
                self.logger.info("Now searching for %(name)s",
                                 self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0],
                                         self.search_points[0][1])
                self.search_points = self.search_points[
                    1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(
                self.bot.position,
                (self.walker.dest_lat, self.walker.dest_lng)).meters
            self.logger.info("Moving to destination at %s meters: %s",
                             round(distance, 2), self.destination["name"])
            self.no_log_until = now + 30

        return WorkerResult.RUNNING
Example #23
0
class PokemonHunter(BaseTask):
    SUPPORTED_TASK_API_VERSION = 1

    def __init__(self, bot, config):
        super(PokemonHunter, self).__init__(bot, config)

    def initialize(self):
        self.destination = None
        self.walker = None
        self.search_cell_id = None
        self.search_points = []
        self.lost_counter = 0
        self.no_log_until = 0

        self.config_max_distance = self.config.get("max_distance", 2000)
        self.config_hunt_all = self.config.get("hunt_all", False)
        self.config_hunt_vip = self.config.get("hunt_vip", True)
        self.config_hunt_pokedex = self.config.get("hunt_pokedex", True)

    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                self.destination = worth_pokemons[0]
                self.lost_counter = 0

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join(p["name"] for p in pokemons))
                    self.no_log_until = now + 120

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.destination = None
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
            self.no_log_until = now + 30

        return WorkerResult.RUNNING

    def get_pokeball_count(self):
        return sum([inventory.items().get(ball.value).count for ball in [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]])

    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [p for p in self.bot.cell["nearby_pokemons"] if self.get_distance(self.bot.start_position, p) <= radius]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, p)
            pokemon["name"] = inventory.pokemons().name_for(pokemon["pokemon_id"])

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons

    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [p for p in pokemons if p["name"] in self.bot.config.vips]

            if self.config_hunt_pokedex:
                worth_pokemons += [p for p in pokemons if (p not in worth_pokemons) and any(not inventory.pokedex().seen(fid) for fid in self.get_family_ids(p))]

        worth_pokemons.sort(key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons

    def get_family_ids(self, pokemon):
        family_id = inventory.pokemons().data_for(pokemon["pokemon_id"]).first_evolution_id
        ids = [family_id]
        ids += inventory.pokemons().data_for(family_id).next_evolutions_all[:]

        return ids

    def get_distance(self, location, pokemon):
        return great_circle(location, (pokemon["latitude"], pokemon["longitude"])).meters

    def get_search_points(self, cell_id):
        points = []

        # For cell level 15
        for c in Cell(CellId(cell_id)).subdivide():
            for cc in c.subdivide():
                latlng = LatLng.from_point(cc.get_center())
                point = (latlng.lat().degrees, latlng.lng().degrees)
                points.append(point)

        points[0], points[1] = points[1], points[0]
        points[14], points[15] = points[15], points[14]
        point = points.pop(2)
        points.insert(7, point)
        point = points.pop(13)
        points.insert(8, point)

        closest = min(points, key=lambda p: great_circle(self.bot.position, p).meters)
        index = points.index(closest)

        return points[index:] + points[:index]
Example #24
0
class PokemonHunter(BaseTask):
    SUPPORTED_TASK_API_VERSION = 1

    def __init__(self, bot, config):
        super(PokemonHunter, self).__init__(bot, config)

    def initialize(self):
        self.notified_second_gen = []
        self.destination = None
        self.walker = None
        self.search_cell_id = None
        self.search_points = []
        self.lost_counter = 0
        self.no_log_until = 0
        self.distance_to_target = 0
        self.distance_counter = 0
        self.recent_tries = []
        self.no_hunt_until = None
        self.hunt_started_at = None

        self.config_max_distance = self.config.get("max_distance", 2000)
        self.config_hunt_all = self.config.get("hunt_all", False)
        self.config_hunt_vip = self.config.get("hunt_vip", True)
        self.config_hunt_pokedex = self.config.get("hunt_pokedex", True)
        # Lock on Target; ignore all other Pokémon until we found our target.
        self.config_lock_on_target = self.config.get("lock_on_target", False)
        # Lock only VIP Pokemon (unseen / VIP)
        self.config_lock_vip_only = self.config.get("lock_vip_only", True)
        # If we are camping forts, disable hunting (see CampFort)
        self.config_disabled_while_camping = self.config.get(
            "disabled_while_camping", True)
        # Hunt unseens as VIP?
        self.config_treat_unseen_as_vip = self.config.get(
            "treat_unseen_as_vip", True)
        self.bot.hunter_locked_target = None

    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.config_disabled_while_camping and hasattr(
                self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info(
                    "All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled"
                    .format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        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

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info(
                    "We found a %(name)s while hunting. Aborting the current search.",
                    self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = time.time() + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()
        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries,
                          pokemons)

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                random.shuffle(worth_pokemons)
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info(
                    "New destination at %(distance).2f meters: %(name)s",
                    self.destination)
                if self._is_vip_pokemon(self.destination):
                    self.logger.info("This is a VIP Pokemon! Starting hunt.")
                    if self.config_lock_on_target:
                        self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info(
                        "I need a %(name)s to complete the Pokedex! I have %(candies)s candies.",
                        self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(
                        self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot,
                                                 self.search_points[0][0],
                                                 self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[
                        1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names)  # unicode object, no lower? , key=str.lower)

                    self.logger.info(
                        "There is no nearby pokemon worth hunting down [%s]",
                        ", ".join('{}({})'.format(key, val)
                                  for key, val in names.items()))
                    self.no_log_until = now + 120
                    self.destination = None
                    wait = uniform(120, 600)
                    self.no_hunt_until = now + wait
                    self.logger.info("Will look again around {}.".format(
                        (datetime.now() +
                         timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info(
                    "We found a %(name)s while hunting. Aborting the current search.",
                    self.destination)
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"]
               for p in self.bot.cell["catchable_pokemons"] +
               self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"]
                       for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s",
                                 self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0],
                                         self.search_points[0][1])
                self.search_points = self.search_points[
                    1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(
                self.bot.position,
                (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter >= 3:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info(
                    "I cant move toward %(name)s! Aborting search.",
                    self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                wait = uniform(120, 600)
                self.no_hunt_until = now + wait
                self.logger.info("Hunting on cooldown until {}.".format(
                    (datetime.now() +
                     timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                self.logger.info("Moving to destination at %s meters: %s",
                                 round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 30

        return WorkerResult.RUNNING

    def get_pokeball_count(self):
        return sum([
            inventory.items().get(ball.value).count for ball in
            [Item.ITEM_POKE_BALL, Item.ITEM_GREAT_BALL, Item.ITEM_ULTRA_BALL]
        ])

    def get_nearby_pokemons(self):
        radius = self.config_max_distance

        pokemons = [
            p for p in self.bot.cell["nearby_pokemons"]
            if self.get_distance(self.bot.start_position, p) <= radius
        ]

        for pokemon in pokemons:
            pokemon["distance"] = self.get_distance(self.bot.position, p)
            pokemon["name"] = inventory.pokemons().name_for(
                pokemon["pokemon_id"])
            pokemon["candies"] = inventory.candies().get(
                pokemon["pokemon_id"]).quantity

        pokemons.sort(key=lambda p: p["distance"])

        return pokemons

    def _is_vip_pokemon(self, pokemon):
        # 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(pokemon["name"]) == {} or (
                self.config_treat_unseen_as_vip
                and not inventory.pokedex().seen(pokemon["pokemon_id"])):
            return True

    def _is_needed_pokedex(self, pokemon):
        candies = inventory.candies().get(pokemon["pokemon_id"]).quantity
        if candies > 150:
            # We have enough candies, pass on hunting this Pokemon
            return False

        # get family ids, gets ALL ids, also for previous evo!
        # We could see a Ivysaur on the map, and need a Bulbasaur
        # Then we have no need for a Ivysaur. If we see a Bulbasaur and need
        # a Ivysaur, then we DO need this pokemon.
        got_current_evo = False
        ids = []
        for fid in self.get_family_ids(pokemon):
            if got_current_evo:
                ids += [fid]
            else:
                if fid == pokemon["pokemon_id"]:
                    ids += [fid]
                    got_current_evo = True
        # Check if we need this, or a next EVO in the Pokedex
        if any(not inventory.pokedex().seen(fid) for fid in ids):
            return True

    def get_worth_pokemons(self, pokemons):
        if self.config_hunt_all:
            worth_pokemons = pokemons
        else:
            worth_pokemons = []

            if self.config_hunt_vip:
                worth_pokemons += [
                    p for p in pokemons if p["name"] in self.bot.config.vips
                ]

            if self.config_hunt_pokedex:
                worth_pokemons += [
                    p for p in pokemons
                    if (p not in worth_pokemons) and self._is_needed_pokedex(p)
                ]

        worth_pokemons.sort(
            key=lambda p: inventory.candies().get(p["pokemon_id"]).quantity)

        return worth_pokemons

    def get_family_ids(self, pokemon):
        family_id = inventory.pokemons().data_for(
            pokemon["pokemon_id"]).first_evolution_id
        ids = [family_id]
        ids += inventory.pokemons().data_for(family_id).next_evolutions_all[:]

        return ids

    def get_distance(self, location, pokemon):
        return great_circle(location,
                            (pokemon["latitude"], pokemon["longitude"])).meters

    def get_search_points(self, cell_id):
        points = []

        # For cell level 15
        for c in Cell(CellId(cell_id)).subdivide():
            for cc in c.subdivide():
                latlng = LatLng.from_point(cc.get_center())
                point = (latlng.lat().degrees, latlng.lng().degrees)
                points.append(point)

        points[0], points[1] = points[1], points[0]
        points[14], points[15] = points[15], points[14]
        point = points.pop(2)
        points.insert(7, point)
        point = points.pop(13)
        points.insert(8, point)

        closest = min(points,
                      key=lambda p: great_circle(self.bot.position, p).meters)
        index = points.index(closest)

        return points[index:] + points[:index]

    def destination_caught(self):
        # self.logger.info("Searching for a {} since {}".format(self.destination["name"], self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))

        with self.bot.database as conn:
            c = conn.cursor()
            c.execute(
                "SELECT COUNT(pokemon) FROM catch_log where pokemon = '{}' and  datetime(dated, 'localtime') > Datetime('{}')"
                .format(self.destination["name"],
                        self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))
        # Now check if there is 1 or more caught
        amount = c.fetchone()[0]
        caught = amount > 0
        if caught:
            self.logger.info("We caught {} {}(s) since {}".format(
                amount, self.destination["name"],
                self.hunt_started_at.strftime("%Y-%m-%d %H:%M:%S")))

        return caught
Example #25
0
    def work(self):
        forts = self.bot.get_forts()
        log_lure_avail_str = ''
        log_lured_str = ''
        if self.lured:
            lured_forts = [x for x in forts if 'active_fort_modifier' in x]
            if len(lured_forts) > 0:
                log_lured_str = 'lured '
                self.dest = find_biggest_cluster(self.radius, lured_forts,
                                                 '9QM=')
            else:
                log_lure_avail_str = 'No lured pokestops in vicinity. Search for normal ones instead. '
                self.dest = find_biggest_cluster(self.radius, forts)
        else:
            self.dest = find_biggest_cluster(self.radius, forts)

        if self.dest is not None:
            lat = self.dest['latitude']
            lng = self.dest['longitude']
            cnt = self.dest['num_points']

            if not self.is_at_destination:
                msg = log_lure_avail_str + (
                    "Move to cluster: {num_points} {forts} "
                    "pokestops will be in range of {radius}. Walking {distance}m."
                )
                self.emit_event('found_cluster',
                                formatted=msg,
                                data={
                                    'num_points':
                                    cnt,
                                    'forts':
                                    log_lured_str,
                                    'radius':
                                    str(self.radius),
                                    'distance':
                                    str(
                                        round(
                                            distance(self.bot.position[0],
                                                     self.bot.position[1], lat,
                                                     lng), 2))
                                })

                self.announced = False

                step_walker = StepWalker(self.bot, lat, lng)

                self.is_at_destination = False
                if step_walker.step():
                    self.is_at_destination = True
            elif not self.announced:
                self.emit_event(
                    'arrived_at_cluster',
                    formatted=
                    "Arrived at cluster. {num_points} {forts} pokestops are in a range of {radius}m radius.",
                    data={
                        'num_points': cnt,
                        'forts': log_lured_str,
                        'radius': self.radius
                    })
                self.announced = True
        else:
            lat = self.bot.position[0]
            lng = self.bot.position[1]

        return [lat, lng]
Example #26
0
    def work(self):
        forts = self.bot.get_forts()
        log_lure_avail_str = ''
        log_lured_str = ''
        if self.lured:
            lured_forts = [x for x in forts if 'active_fort_modifier' in x]
            if len(lured_forts) > 0:
                log_lured_str = 'lured '
                self.dest = find_biggest_cluster(self.radius, lured_forts, '9QM=')
            else:
                log_lure_avail_str = 'No lured pokestops in vicinity. Search for normal ones instead. '
                self.dest = find_biggest_cluster(self.radius, forts)
        else:
            self.dest = find_biggest_cluster(self.radius, forts)

        if self.dest is not None:

            lat = self.dest['latitude']
            lng = self.dest['longitude']
            cnt = self.dest['num_points']

            if not self.is_at_destination:
                msg = log_lure_avail_str + (
                    "Move to cluster: {num_points} {forts} "
                    "pokestops will be in range of {radius}. Walking {distance}m."
                )
                self.emit_event(
                    'found_cluster',
                    formatted=msg,
                    data={
                        'num_points': cnt,
                        'forts': log_lured_str,
                        'radius': str(self.radius),
                        'distance': str(round(distance(self.bot.position[0], self.bot.position[1], lat, lng), 2))
                    }
                )

                self.announced = False

                if self.bot.config.walk_max > 0:
                    step_walker = StepWalker(
                        self.bot,
                        lat,
                        lng
                    )

                    self.is_at_destination = False
                    if step_walker.step():
                        self.is_at_destination = True
                else:
                    alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
                    self.bot.api.set_position(lat, lng, alt)

            elif not self.announced:
                self.emit_event(
                    'arrived_at_cluster',
                    formatted="Arrived at cluster. {num_points} {forts} pokestops are in a range of {radius}m radius.",
                    data={
                        'num_points': cnt,
                        'forts': log_lured_str,
                        'radius': self.radius
                    }
                )
                self.announced = True
        else:
            lat = self.bot.position[0]
            lng = self.bot.position[1]

        return [lat, lng]
Example #27
0
    def work(self):
        last_lat = self.bot.api._position_lat
        last_lng = self.bot.api._position_lng
        last_alt = self.bot.api._position_alt

        point = self.points[self.ptr]
        lat = float(point['lat'])
        lng = float(point['lng'])
        alt = uniform(self.bot.config.alt_min, self.bot.config.alt_max)
        if 'alt' in point:
            alt = float(point['alt'])

        if self.bot.config.walk_max > 0:
            step_walker = StepWalker(
                self.bot,
                lat,
                lng
            )

            is_at_destination = False
            if step_walker.step():
                is_at_destination = True

        else:
            self.bot.api.set_position(lat, lng, alt)

        dist = distance(
            last_lat,
            last_lng,
            lat,
            lng
        )

        self.emit_event(
            'position_update',
            formatted="Walking from {last_position} to {current_position}, distance left: ({distance} {distance_unit}) ..",
            data={
                'last_position': (last_lat, last_lng, last_alt),
                'current_position': (lat, lng, alt),
                'distance': dist,
                'distance_unit': 'm'
            }
        )
        
        if dist <= 1 or (self.bot.config.walk_min > 0 and is_at_destination):
            if (self.ptr + 1) == len(self.points):
                self.ptr = 0
                if self.path_mode == 'linear':
                    self.points = list(reversed(self.points))
                if self.number_lap_max >= 0:
                    self.number_lap+=1
                    self.emit_event(
                        'path_lap_update',
                        formatted="number lap : {number_lap} / {number_lap_max}",
                        data={
                            'number_lap': str(self.number_lap),
                            'number_lap_max': str(self.number_lap_max)
                        }
                    )
                    if self.number_lap >= self.number_lap_max:
                        self.endLaps()
            else:
                self.ptr += 1
        
        return [lat, lng]
Example #28
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.bot.catch_disabled:
            # When catching is disabled, drop the target.
            if self.destination is not None:
                self.destination = None
                self.last_cell_id = None

            if not hasattr(self.bot, "hunter_disabled_global_warning") or \
                        (hasattr(self.bot, "hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.bot.softban:
            # At softban, drop target
            if self.destination is not None:
                self.destination = None
                self.last_cell_id = None
                self.hunting_trash = False

            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

        if self.config_disabled_while_camping and hasattr(self.bot, 'camping_forts') and self.bot.camping_forts:
            return WorkerResult.SUCCESS

        if not self.config_lock_on_target:
            self.bot.hunter_locked_target = None

        if self.no_hunt_until != None and self.no_hunt_until > time.time():
            # No hunting now, cooling down
            return WorkerResult.SUCCESS
        else:
            # Resume hunting
            self.no_hunt_until = None

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            self.hunting_trash = False
            return WorkerResult.SUCCESS

        if self.destination is not None:
            if self.destination_caught():
                self.logger.info("We found a %(name)s while hunting.", self.destination)
                self.recent_tries.append(self.destination['pokemon_id'])
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                    return WorkerResult.SUCCESS
                else:
                    self.logger.info("Electing new target....")

            if self.destination_vanished():
                self.logger.info("Darn, target got away!")
                self.recent_tries.append(self.destination['pokemon_id'])
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                    return WorkerResult.SUCCESS
                else:
                    self.logger.info("Electing new target....")

        now = time.time()
        pokemons = self.get_nearby_pokemons()
        pokemons = filter(lambda x: x["pokemon_id"] not in self.recent_tries, pokemons)

        if self.config_hunt_for_trash and self.hunting_trash is False and (self.destination is None or self._is_vip_pokemon(self.destination) is False ):
            # Okay, we should hunt for trash if the bag is almost full
            trash_mons = ["Caterpie", "Weedle", "Pidgey", "Pidgeotto", "Pidgeot", "Kakuna", "Beedrill", "Metapod", "Butterfree"]
            if self.pokemon_slots_left() <= self.config_trash_hunt_open_slots:
                if self.no_log_until < now:
                    self.logger.info("Less than %s slots left to fill, starting hunt for trash" % elf.config_trash_hunt_open_slots)
                for pokemon in pokemons:
                    if pokemon["name"] in trash_mons:
                        self.hunting_trash = True
                        self.destination = pokemon
                        self.lost_counter = 0
                        self.hunt_started_at = datetime.now()
                        self.logger.info("Hunting for trash at %(distance).2f meters: %(name)s", self.destination)
                        self.set_target()
                        # We have a target
                        return WorkerResult.SUCCESS

        if self.config_hunt_for_trash and self.hunting_trash:
            if self.pokemon_slots_left() > 20:
                self.logger.info("No longer trying to fill the bag. Electing new target....")
                self.hunting_trash = False
                self.destination = None

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons, self.config_hunt_closest_first)

            if len(worth_pokemons) > 0:
                # Pick a random target from the list
                # random.shuffle(worth_pokemons)
                # Priotize closer pokemon
                worth_pokemons.sort(key=lambda p: p["distance"])
                # Prevents the bot from looping the same Pokemon
                self.destination = worth_pokemons[0]
                self.set_target()
                self.lost_counter = 0
                self.hunt_started_at = datetime.now()

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                if self._is_vip_pokemon(self.destination):
                    self.logger.info("This is a VIP Pokemon! Starting hunt.")
                    if self.config_lock_on_target:
                        self.bot.hunter_locked_target = self.destination
                elif self._is_needed_pokedex(self.destination):
                    self.logger.info("I need a %(name)s to complete the Pokedex! I have %(candies)s candies.", self.destination)
                    if self.config_lock_on_target and not self.config_lock_vip_only:
                        self.bot.hunter_locked_target = self.destination
                    else:
                        self.bot.hunter_locked_target = None

                self.no_log_until = now + 60
                # We have a target
                return WorkerResult.SUCCESS
            else:
                if self.no_log_until < now:
                    # Show like "Pidgey (12), Zubat(2)"
                    names = Counter((p["name"] for p in pokemons))
                    sorted(names) # unicode object, no lower? , key=str.lower)

                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join('{}({})'.format(key, val) for key, val in names.items()))
                    self.no_log_until = now + 120
                    self.destination = None
                    if self.config_enable_cooldown:
                        wait = uniform(120, 360)
                        self.no_hunt_until = now + wait
                        self.logger.info("Will look again around {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        # Make sure a VIP is treated that way
        if self.config_lock_on_target and self.destination is not None:
            if self._is_vip_pokemon(self.destination) and self.bot.hunter_locked_target is None:
                self.bot.hunter_locked_target = self.destination

        # Check if there is a VIP around to hunt
        if (self.destination is not None and
                self.config_lock_on_target and
                self.config_lock_vip_only and
                self.bot.hunter_locked_target is None):
            worth_pokemons = self.get_worth_pokemons(pokemons)
            # We have a none VIP target set, check for VIP targets!
            if len(worth_pokemons) > 0:
                for pokemon in worth_pokemons:
                    if self._is_vip_pokemon(pokemon):
                        self.hunting_trash = False
                        self.destination = pokemon
                        self.lost_counter = 0
                        self.hunt_started_at = datetime.now()
                        self.set_target()
                        if self.config_lock_on_target:
                            self.bot.hunter_locked_target = self.destination
                        self.logger.info("Found a VIP Pokemon! Looking for a %(name)s at %(distance).2f.", self.destination)
                        return WorkerResult.SUCCESS
            pass

        if self.destination is None:
            if self.no_log_until < now:
                self.logger.info("Nothing to hunt.")
            return WorkerResult.SUCCESS

        if self.config_lock_on_target and not self.config_lock_vip_only:
            if self.bot.hunter_locked_target == None:
                self.logger.info("We found a %(name)s while hunting. Aborting the current search.", self.destination)
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
            self.hunting_trash = False
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
                self.hunting_trash = False
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            if round(distance, 2) == self.distance_to_target:
                # Hmm, not moved toward the Pokemon?
                self.distance_counter += 1
            else:
                self.distance_counter = 0

            if self.distance_counter >= 3:
                # Ignore last 3
                if len(self.recent_tries) > 3:
                    self.recent_tries.pop()

                self.recent_tries.append(self.destination['pokemon_id'])
                self.logger.info("I cant move toward %(name)s! Aborting search.", self.destination)
                self.hunting_trash = False
                self.bot.hunter_locked_target = None
                self.destination = None
                if self.config_enable_cooldown:
                    wait = uniform(120, 600)
                    self.no_hunt_until = time.time() + wait
                    self.logger.info("Hunting on cooldown until {}.".format((datetime.now() + timedelta(seconds=wait)).strftime("%H:%M:%S")))
                return WorkerResult.ERROR
            else:
                self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
                # record the new distance...
                self.distance_to_target = round(distance, 2)
                if self.config_lock_on_target and not self.config_lock_vip_only:
                    # Just to ensure we stay on target
                    self.bot.hunter_locked_target = self.destination
                self.no_log_until = now + 30

        return WorkerResult.RUNNING
Example #29
0
    def work(self):
        if not self.enabled:
            return WorkerResult.SUCCESS

        if self.bot.catch_disabled:
            if not hasattr(self.bot,"hunter_disabled_global_warning") or \
                        (hasattr(self.bot,"hunter_disabled_global_warning") and not self.bot.hunter_disabled_global_warning):
                self.logger.info("All catching tasks are currently disabled until {}. Pokemon Hunter will resume when catching tasks are re-enabled".format(self.bot.catch_resume_at.strftime("%H:%M:%S")))
            self.bot.hunter_disabled_global_warning = True
            return WorkerResult.SUCCESS
        else:
            self.bot.hunter_disabled_global_warning = False

        if self.get_pokeball_count() <= 0:
            self.destination = None
            self.last_cell_id = None
            return WorkerResult.SUCCESS

        now = time.time()
        pokemons = self.get_nearby_pokemons()

        if self.destination is None:
            worth_pokemons = self.get_worth_pokemons(pokemons)

            if len(worth_pokemons) > 0:
                self.destination = worth_pokemons[0]
                self.lost_counter = 0

                self.logger.info("New destination at %(distance).2f meters: %(name)s", self.destination)
                self.no_log_until = now + 60
                if self.config_lock_on_target:
                    self.bot.hunter_locked_target = self.destination

                if self.destination["s2_cell_id"] != self.search_cell_id:
                    self.search_points = self.get_search_points(self.destination["s2_cell_id"])
                    self.walker = PolylineWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                    self.search_cell_id = self.destination["s2_cell_id"]
                    self.search_points = self.search_points[1:] + self.search_points[:1]
            else:
                if self.no_log_until < now:
                    self.logger.info("There is no nearby pokemon worth hunting down [%s]", ", ".join(p["name"] for p in pokemons))
                    self.no_log_until = now + 120

                self.last_cell_id = None

                return WorkerResult.SUCCESS

        if any(self.destination["encounter_id"] == p["encounter_id"] for p in self.bot.cell["catchable_pokemons"] + self.bot.cell["wild_pokemons"]):
            self.destination = None
        elif self.walker.step():
            if not any(self.destination["encounter_id"] == p["encounter_id"] for p in pokemons):
                self.lost_counter += 1
            else:
                self.lost_counter = 0

            if self.lost_counter >= 3:
                self.logger.info("I haven't found %(name)s", self.destination)
                self.bot.hunter_locked_target = None
                self.destination = None
            else:
                self.logger.info("Now searching for %(name)s", self.destination)

                self.walker = StepWalker(self.bot, self.search_points[0][0], self.search_points[0][1])
                self.search_points = self.search_points[1:] + self.search_points[:1]
        elif self.no_log_until < now:
            distance = great_circle(self.bot.position, (self.walker.dest_lat, self.walker.dest_lng)).meters
            self.logger.info("Moving to destination at %s meters: %s", round(distance, 2), self.destination["name"])
            if self.config_lock_on_target:
                self.bot.hunter_locked_target = self.destination
            self.no_log_until = now + 30

        return WorkerResult.RUNNING