def test_bigger_then_total_speed_big_precision_offset(self): walk_max = self.bot.config.walk_max walk_min = self.bot.config.walk_min speed = 300 precision = 2.5 self.bot.config.walk_max = speed self.bot.config.walk_min = speed pw = PolylineWalker(self.bot, ex_dest[0], ex_dest[1], precision=precision) self.assertEqual(pw.dest_lat, ex_dest[0], 'dest_lat did not match') self.assertEqual(pw.dest_lng, ex_dest[1], 'dest_lng did not match') @mock.patch('random.uniform') def run_step(mock_random): mock_random.return_value = 0.0 return pw.step() finishedWalking = run_step() self.assertTrue(finishedWalking, 'step should return False') distance = Geodesic.WGS84.Inverse(ex_dest[0], ex_dest[1], self.bot.position[0], self.bot.position[1])["s12"] self.assertTrue(0.0 <= distance <= (pw.precision + pw.epsilon)) self.polyline._last_pos = self.polyline.destination self.assertTrue(abs(self.polyline.get_alt() - self.bot.position[2]) <= 1) self.bot.config.walk_max = walk_max self.bot.config.walk_min = walk_min
def test_one_small_speed(self): walk_max = self.bot.config.walk_max walk_min = self.bot.config.walk_min speed = 0.247503233266 precision = 0.0 dlat = 47.17064 dlng = 8.51674 self.bot.config.walk_max = speed self.bot.config.walk_min = speed pw = PolylineWalker(self.bot, ex_dest[0], ex_dest[1], precision=precision) self.assertEqual(pw.dest_lat, ex_dest[0], 'dest_lat did not match') self.assertEqual(pw.dest_lng, ex_dest[1], 'dest_lng did not match') @mock.patch('random.uniform') def run_step(mock_random): mock_random.return_value = 0.0 return pw.step() finishedWalking = run_step() self.assertFalse(finishedWalking, 'step should return False') distance = Geodesic.WGS84.Inverse(dlat, dlng, self.bot.position[0], self.bot.position[1])["s12"] self.assertTrue(0.0 <= distance <= (pw.precision + pw.epsilon)) self.polyline._last_pos = (dlat, dlng) self.assertTrue(abs(self.polyline.get_alt() - self.bot.position[2]) <= 1) self.bot.config.walk_max = walk_max self.bot.config.walk_min = walk_min
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 set_target(self): if not 's2_cell_id' in self.destination: # This Pokemon has coords self.search_points = [] self.walker = PolylineWalker(self.bot, self.destination["latitude"], self.destination["longitude"]) self.logger.info("Target must be close by...") # self.logger.info("destination: %s" % self.destination) # self.search_points = self.get_search_points(self.bot.cell["s2_cell_id"]) # self.search_cell_id = self.bot.cell["s2_cell_id"] # self.search_points = self.search_points[1:] + self.search_points[:1] else: 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] if "fort_id" in self.destination: # The Pokemon is hding at a POkestop, so move to that Pokestop! # Get forts forts = self.bot.get_forts(order_by_distance=True) for fort in forts: if fort['id'] == self.destination['fort_id']: # Found our fort! lat = fort['latitude'] lng = fort['longitude'] details = fort_details(self.bot, fort['id'], lat, lng) fort_name = details.get('name', 'Unknown') self.logger.info("%s is hiding at %s, going there first!" % (self.destination["name"], fort_name)) self.walker = PolylineWalker(self.bot, lat, lng) else: nearest_fort = self.get_nearest_fort_on_the_way() if nearest_fort is not None: lat = nearest_fort['latitude'] lng = nearest_fort['longitude'] details = fort_details(self.bot, nearest_fort['id'], lat, lng) fort_name = details.get('name', 'Unknown') self.logger.info("Moving to %s via %s." % (self.destination["name"], fort_name)) self.walker = PolylineWalker(self.bot, lat, lng)
def set_target(self): 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] if "fort_id" in self.destination: # The Pokemon is hding at a POkestop, so move to that Pokestop! # Get forts forts = self.bot.get_forts(order_by_distance=True) for fort in forts: if fort['id'] == self.destination['fort_id']: # Found our fort! lat = fort['latitude'] lng = fort['longitude'] details = fort_details(self.bot, fort['id'], lat, lng) fort_name = details.get('name', 'Unknown') self.logger.info("%s is hiding at %s, going there first!" % (self.destination["name"], fort_name)) self.walker = PolylineWalker(self.bot, 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
def test_teleport(self): walk_max = self.bot.config.walk_max walk_min = self.bot.config.walk_min precision = 0.0 speed = float("inf") self.bot.config.walk_max = 4 self.bot.config.walk_min = 2 pw = PolylineWalker(self.bot, ex_dest[0], ex_dest[1], precision=precision) self.assertEqual(pw.dest_lat, ex_dest[0], 'dest_lat did not match') self.assertEqual(pw.dest_lng, ex_dest[1], 'dest_lng did not match') finishedWalking = pw.step(speed=speed) self.assertTrue(finishedWalking, 'step should return True') distance = Geodesic.WGS84.Inverse(ex_dest[0], ex_dest[1], self.bot.position[0], self.bot.position[1])["s12"] self.assertTrue(0.0 <= distance <= (pw.precision + pw.epsilon)) self.polyline._last_pos = self.polyline.destination self.assertTrue(abs(self.polyline.get_alt() - self.bot.position[2]) <= 1) self.bot.config.walk_max = walk_max self.bot.config.walk_min = walk_min
def test_stay_put(self): altitude = 429.5 self.bot.position = [47.1706378, 8.5167405, altitude] walk_max = self.bot.config.walk_max walk_min = self.bot.config.walk_min precision = 0.0 speed = 0.0 self.bot.config.walk_max = 4 self.bot.config.walk_min = 2 pw = PolylineWalker(self.bot, ex_dest[0], ex_dest[1], precision=precision) self.assertEqual(pw.dest_lat, ex_dest[0], 'dest_lat did not match') self.assertEqual(pw.dest_lng, ex_dest[1], 'dest_lng did not match') finishedWalking = pw.step(speed=speed) self.assertFalse(finishedWalking, 'step should return False') distance = Geodesic.WGS84.Inverse(ex_orig[0], ex_orig[1], self.bot.position[0], self.bot.position[1])["s12"] self.assertTrue(0.0 <= distance <= (pw.precision + pw.epsilon)) self.assertTrue(altitude - 1 <= self.bot.position[2] <= altitude + 1) self.bot.config.walk_max = walk_max self.bot.config.walk_min = walk_min
def work(self): if not self.enabled: return WorkerResult.SUCCESS now = time.time() if now < self.move_until: return WorkerResult.SUCCESS if 0 < self.stay_until < now: self.cluster = None self.stay_until = 0 self.move_until = now + self.config_moving_time if self.config_moving_time > 0: return WorkerResult.SUCCESS # Let's make sure we have balls before we sit at a lure! # See also catch_pokemon.py if self.get_pokeball_count() <= 0: self.emit_event( 'refuse_to_sit', formatted='No pokeballs left, refuse to sit at lure!', ) # Move away from lures for a time self.cluster = None self.stay_until = 0 self.move_until = now + max(self.config_moving_time, NO_BALLS_MOVING_TIME) return WorkerResult.SUCCESS forts = self.get_forts() if self.cluster is None: if self.clusters is None: self.clusters = self.get_clusters(forts.values()) available_clusters = self.get_available_clusters(forts) if len(available_clusters) > 0: self.cluster = available_clusters[0] self.walker = PolylineWalker(self.bot, self.cluster["center"][0], self.cluster["center"][1]) self.no_log_until = now + LOG_TIME_INTERVAL self.emit_event( "new_destination", formatted= 'New destination at {distance:.2f} meters: {size} forts, {lured} lured' .format(**self.cluster)) else: return WorkerResult.SUCCESS self.update_cluster_distance(self.cluster) self.update_cluster_lured(self.cluster, forts) if self.stay_until >= now: if self.no_log_until < now: self.no_log_until = now + LOG_TIME_INTERVAL self.emit_event( "staying_at_destination", formatted= 'Staying at destination: {size} forts, {lured} lured'. format(**self.cluster)) if self.cluster["lured"] == 0: self.stay_until -= NO_LURED_TIME_MALUS self.walker.step(speed=0) elif self.walker.step(): self.stay_until = now + self.config_camping_time self.emit_event( "arrived_at_destination", formatted="Arrived at destination: {size} forts, {lured} lured" .format(**self.cluster)) elif self.no_log_until < now: if self.cluster["lured"] == 0: self.cluster = None self.emit_event("reset_destination", formatted="Lures gone! Resetting destination!") else: self.no_log_until = now + LOG_TIME_INTERVAL self.emit_event( "moving_to_destination", formatted= "Moving to destination at {distance:.2f} meters: {size} forts, {lured} lured" .format(**self.cluster)) return WorkerResult.RUNNING
def work(self): if not self.enabled: return WorkerResult.SUCCESS if self.bot.catch_disabled: if not hasattr(self.bot,"camper_disabled_global_warning") or \ (hasattr(self.bot,"camper_disabled_global_warning") and not self.bot.camper_disabled_global_warning): self.logger.info("All catching tasks are currently disabled until {}. Camping of lured forts disabled till then.".format(self.bot.catch_resume_at.strftime("%H:%M:%S"))) self.bot.camper_disabled_global_warning = True return WorkerResult.SUCCESS else: self.bot.camper_disabled_global_warning = False now = time.time() if now < self.move_until: return WorkerResult.SUCCESS if 0 < self.stay_until < now: self.cluster = None self.stay_until = 0 self.move_until = now + self.config_moving_time if self.config_moving_time > 0: return WorkerResult.SUCCESS # Let's make sure we have balls before we sit at a lure! # See also catch_pokemon.py if self.get_pokeball_count() <= 0: self.emit_event( 'refuse_to_sit', formatted='No pokeballs left, refuse to sit at lure!', ) # Move away from lures for a time self.cluster = None self.stay_until = 0 self.move_until = now + max(self.config_moving_time, NO_BALLS_MOVING_TIME) return WorkerResult.SUCCESS forts = self.get_forts() if self.cluster is None: if self.clusters is None: self.clusters = self.get_clusters(forts.values()) # self.logger.info("Forts: {}".format(len(forts))) # self.logger.info("Checking {} clusters for availiblity....".format(len(self.clusters))) available_clusters = self.get_available_clusters(forts) if len(available_clusters) > 0: self.cluster = available_clusters[0] self.walker = PolylineWalker(self.bot, self.cluster["center"][0], self.cluster["center"][1]) self.no_log_until = now + LOG_TIME_INTERVAL self.no_recheck_cluster_until = now + NO_BALLS_MOVING_TIME self.emit_event("new_destination", formatted='New destination at {distance:.2f} meters: {size} forts, {lured} lured'.format(**self.cluster)) else: # self.logger.info("No clusters found.") self.cluster = None self.clusters = None return WorkerResult.SUCCESS # We can check if the cluster is still the best elif self.no_recheck_cluster_until < now: self.clusters = self.get_clusters(forts.values()) available_clusters = self.get_available_clusters(forts) if len(available_clusters) > 0: if self.cluster is not available_clusters[0]: self.cluster = available_clusters[0] self.stay_until = 0 self.emit_event("new_destination", formatted='Better destination found at {distance:.2f} meters: {size} forts, {lured} lured'.format(**self.cluster)) self.no_recheck_cluster_until = now + NO_BALLS_MOVING_TIME self.update_cluster_distance(self.cluster) self.update_cluster_lured(self.cluster, forts) if self.stay_until >= now: if self.no_log_until < now: self.no_log_until = now + LOG_TIME_INTERVAL self.bot.camping_forts = True self.emit_event("staying_at_destination", formatted='Staying at destination: {size} forts, {lured} lured'.format(**self.cluster)) if self.cluster["lured"] == 0: self.bot.camping_forts = False # Allow hunter to move self.stay_until -= NO_LURED_TIME_MALUS self.walker.step(speed=0) elif self.walker.step(): self.stay_until = now + self.config_camping_time self.bot.camping_forts = True self.emit_event("arrived_at_destination", formatted="Arrived at destination: {size} forts, {lured} lured.".format(**self.cluster)) elif self.no_log_until < now: if self.cluster["lured"] == 0: self.cluster = None self.bot.camping_forts = False self.emit_event("reset_destination", formatted="Lures gone! Resetting destination!") else: self.no_log_until = now + LOG_TIME_INTERVAL self.emit_event("moving_to_destination", formatted="Moving to destination at {distance:.2f} meters: {size} forts, {lured} lured".format(**self.cluster)) return WorkerResult.RUNNING
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
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