Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update MoveToMapPokemon to use events instead of logger. #2913

Merged
merged 1 commit into from
Aug 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ var/
.pydevproject
.settings/

# Cloud9 Users
.c9/

# Installer logs
pip-log.txt
pip-delete-this-directory.txt
Expand Down Expand Up @@ -86,6 +89,8 @@ celerybeat-schedule
# virtualenv
venv/
ENV/
local/
share/

# Spyder project settings
.spyderproject
Expand Down
29 changes: 29 additions & 0 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,35 @@ def _register_events(self):
)
self.event_manager.register_event('unset_pokemon_nickname')

# Move To map pokemon
self.event_manager.register_event(
'move_to_map_pokemon_fail',
parameters=('message',)
)
self.event_manager.register_event(
'move_to_map_pokemon_updated_map',
parameters=('lat', 'lon')
)
self.event_manager.register_event(
'move_to_map_pokemon_teleport_to',
parameters=('poke_name', 'poke_dist', 'poke_lat', 'poke_lon',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It think the shorthand typically used for longitude is lng.

'disappears_in')
)
self.event_manager.register_event(
'move_to_map_pokemon_encounter',
parameters=('poke_name', 'poke_dist', 'poke_lat', 'poke_lon',
'disappears_in')
)
self.event_manager.register_event(
'move_to_map_pokemon_move_towards',
parameters=('poke_name', 'poke_dist', 'poke_lat', 'poke_lon',
'disappears_in')
)
self.event_manager.register_event(
'move_to_map_pokemon_teleport_back',
parameters=('last_lat', 'last_lon')
)

def tick(self):
self.health_record.heartbeat()
self.cell = self.get_meta_cell()
Expand Down
231 changes: 198 additions & 33 deletions pokemongo_bot/cell_workers/move_to_map_pokemon.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,80 @@
# -*- coding: utf-8 -*-
"""
Moves a trainer to a Pokemon.

Events:
move_to_map_pokemon_fail
When the worker fails.
Returns:
message: Failure message.

move_to_map_pokemon_updated_map
When worker updates the PokemonGo-Map.
Returns:
lat: Latitude
lon: Longitude

move_to_map_pokemon_teleport_to
When trainer is teleported to a Pokemon.
Returns:
poke_name: Pokemon's name
poke_dist: Distance from the trainer
poke_lat: Latitude of the Pokemon
poke_lon: Longitude of the Pokemon
disappears_in: Number of seconds before the Pokemon disappears

move_to_map_pokemon_encounter
When a trainer encounters a Pokemon by teleporting or walking.
Returns:
poke_name: Pokemon's name
poke_dist: Distance from the trainer
poke_lat: Latitude of the Pokemon
poke_lon: Longitude of the Pokemon
disappears_in: Number of seconds before the Pokemon disappears

move_to_map_pokemon_move_towards
When a trainer moves toward a Pokemon.
Returns:
poke_name: Pokemon's name
poke_dist: Distance from the trainer
poke_lat: Latitude of the Pokemon
poke_lon: Longitude of the Pokemon
disappears_in: Number of seconds before the Pokemon disappears

move_to_map_pokemon_teleport_back
When a trainer teleports back to thier previous location.
Returns:
last_lat: Trainer's last known latitude
last_lon: Trainer's last known longitude

"""

import os
import time
import json
import base64
import requests
from pokemongo_bot import logger
from pokemongo_bot.cell_workers.utils import distance, format_dist, format_time
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker


# Update the map if more than N meters away from the center. (AND'd with
# UPDATE_MAP_MIN_TIME_MINUTES)
UPDATE_MAP_MIN_DISTANCE_METERS = 500

# Update the map if it hasn't been updated in n seconds. (AND'd with
# UPDATE_MAP_MIN_DISTANCE_METERS)
UPDATE_MAP_MIN_TIME_SEC = 120

# Number of seconds to sleep between teleporting to a snipped Pokemon.
SNIPE_SLEEP_SEC = 2


class MoveToMapPokemon(BaseTask):
"""Task for moving a trainer to a Pokemon."""
SUPPORTED_TASK_API_VERSION = 1

def initialize(self):
Expand All @@ -32,13 +93,15 @@ def get_pokemon_from_map(self):
try:
req = requests.get('{}/raw_data?gyms=false&scanned=false'.format(self.config['address']))
except requests.exceptions.ConnectionError:
logger.log('Could not reach PokemonGo-Map Server', 'red')
self._emit_failure('Could not get Pokemon data from PokemonGo-Map: '
'{}. Is it running?'.format(
self.config['address']))
return []

try:
raw_data = req.json()
except ValueError:
logger.log('Map data was not valid', 'red')
self._emit_failure('Map data was not valid')
return []

pokemon_list = []
Expand All @@ -48,7 +111,7 @@ def get_pokemon_from_map(self):
try:
pokemon['encounter_id'] = long(base64.b64decode(pokemon['encounter_id']))
except TypeError:
log.logger('base64 error: {}'.format(pokemon['encounter_id']), 'red')
self._emit_failure('base64 error: {}'.format(pokemon['encounter_id']))
continue
pokemon['spawn_point_id'] = pokemon['spawnpoint_id']
pokemon['disappear_time'] = int(pokemon['disappear_time'] / 1000)
Expand Down Expand Up @@ -100,14 +163,17 @@ def update_map_location(self):
try:
req = requests.get('{}/loc'.format(self.config['address']))
except requests.exceptions.ConnectionError:
logger.log('Could not reach PokemonGo-Map Server', 'red')
self._emit_failure('Could not update trainer location '
'PokemonGo-Map: {}. Is it running?'.format(
self.config['address']))
return

try:
loc_json = req.json()
except ValueError:
return log.logger('Map location data was not valid', 'red')

err = 'Map location data was not valid'
self._emit_failure(err)
return log.logger(err, 'red')

dist = distance(
self.bot.position[0],
Expand All @@ -118,32 +184,38 @@ def update_map_location(self):

# update map when 500m away from center and last update longer than 2 minutes away
now = int(time.time())
if dist > 500 and now - self.last_map_update > 2 * 60:
requests.post('{}/next_loc?lat={}&lon={}'.format(self.config['address'], self.bot.position[0], self.bot.position[1]))
logger.log('Updated PokemonGo-Map position')
if (dist > UPDATE_MAP_MIN_DISTANCE_METERS and
now - self.last_map_update > UPDATE_MAP_MIN_TIME_SEC):
requests.post(
'{}/next_loc?lat={}&lon={}'.format(self.config['address'],
self.bot.position[0],
self.bot.position[1]))
self.emit_event(
'move_to_map_pokemon_updated_map',
formatted='Updated PokemonGo-Map to {lat}, {lon}',
data={
'lat': self.bot.position[0],
'lon': self.bot.position[1]
}
)
self.last_map_update = now

def snipe(self, pokemon):
last_position = self.bot.position[0:2]

"""Snipe a Pokemon by teleporting.

Args:
pokemon: Pokemon to snipe.
"""
self.bot.heartbeat()

logger.log('Teleporting to {} ({})'.format(pokemon['name'], format_dist(pokemon['dist'], self.unit)), 'green')
self.bot.api.set_position(pokemon['latitude'], pokemon['longitude'], 0)

logger.log('Encounter pokemon', 'green')
self._teleport_to(pokemon)
catch_worker = PokemonCatchWorker(pokemon, self.bot)
api_encounter_response = catch_worker.create_encounter_api_call()

time.sleep(2)
logger.log('Teleporting back to previous location..', 'green')
self.bot.api.set_position(last_position[0], last_position[1], 0)
time.sleep(2)
time.sleep(SNIPE_SLEEP_SEC)
self._teleport_back()
time.sleep(SNIPE_SLEEP_SEC)
self.bot.heartbeat()

catch_worker.work(api_encounter_response)
self.add_caught(pokemon)

return WorkerResult.SUCCESS

def dump_caught_pokemon(self):
Expand Down Expand Up @@ -182,18 +254,111 @@ def work(self):
if self.config['snipe']:
return self.snipe(pokemon)

step_walker = self._move_to(pokemon)
if not step_walker.step():
return WorkerResult.RUNNING
self._encountered(pokemon)
self.add_caught(pokemon)
return WorkerResult.SUCCESS

def _emit_failure(self, msg):
"""Emits failure to event log.

Args:
msg: Message to emit
"""
self.emit_event(
'move_to_map_pokemon_fail',
formatted='Failure! {message}',
data={'message': msg}
)

def _emit_log(self, msg):
"""Emits log to event log.

Args:
msg: Message to emit
"""
self.emit_event(
'move_to_map_pokemon',
formatted='{message}',
data={'message': msg}
)

def _pokemon_event_data(self, pokemon):
"""Generates parameters used for the Bot's event manager.

Args:
pokemon: Pokemon object

Returns:
Dictionary with Pokemon's info.
"""
now = int(time.time())
return {
'poke_name': pokemon['name'],
'poke_dist': (format_dist(pokemon['dist'], self.unit)),
'poke_lat': pokemon['latitude'],
'poke_lon': pokemon['longitude'],
'disappears_in': (format_time(pokemon['disappear_time'] - now))
}

def _teleport_to(self, pokemon):
"""Teleports trainer to a Pokemon.

Args:
pokemon: Pokemon to teleport to.
"""
self.emit_event(
'move_to_map_pokemon_teleport_to',
formatted='Teleporting to {poke_name}. ({poke_dist})',
data=self._pokemon_event_data(pokemon)
)
self.bot.api.set_position(pokemon['latitude'], pokemon['longitude'], 0)
self._encountered(pokemon)

def _encountered(self, pokemon):
"""Emit event when trainer encounters a Pokemon.

Args:
pokemon: Pokemon encountered.
"""
self.emit_event(
'move_to_map_pokemon_encounter',
formatted='Encountered Pokemon: {poke_name}',
data=self._pokemon_event_data(pokemon)
)

def _teleport_back(self):
"""Teleports trainer back to their last position."""
last_position = self.bot.position[0:2]
self.emit_event(
'move_to_map_pokemon_teleport_back',
formatted=('Teleporting back to previous location ({last_lat}, '
'{last_long})'),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be last_lon

data={'last_lat': last_position[0], 'last_lon': last_position[1]}
)
self.bot.api.set_position(last_position[0], last_position[1], 0)

def _move_to(self, pokemon):
"""Moves trainer towards a Pokemon.

Args:
pokemon: Pokemon to move to.

Returns:
StepWalker
"""
now = int(time.time())
logger.log('Moving towards {}, {} left ({})'.format(pokemon['name'], format_dist(pokemon['dist'], self.unit), format_time(pokemon['disappear_time'] - now)))
step_walker = StepWalker(
self.emit_event(
'move_to_map_pokemon_move_towards',
formatted=('Moving towards {poke_name}, {poke_dist}, left ('
'{disappears_in})'),
data=self._pokemon_event_data(pokemon)
)
return StepWalker(
self.bot,
self.bot.config.walk,
pokemon['latitude'],
pokemon['longitude']
)

if not step_walker.step():
return WorkerResult.RUNNING

logger.log('Arrived at {}'.format(pokemon['name']))
self.add_caught(pokemon)
return WorkerResult.SUCCESS
2 changes: 1 addition & 1 deletion pokemongo_bot/health_record/bot_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, config):
# UniversalAnalytics can be reviewed here:
# https://github.com/analytics-pros/universal-analytics-python
if self.config.health_record:
self.logger.info('Health check is enabled. For more logrmation:')
self.logger.info('Health check is enabled. For more information:')
self.logger.info('https://github.com/PokemonGoF/PokemonGo-Bot/tree/dev#analytics')
self.client = Client(
dsn='https://8abac56480f34b998813d831de262514:196ae1d8dced41099f8253ea2c8fe8e6@app.getsentry.com/90254',
Expand Down