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

Polyline rework #3854

Merged
merged 12 commits into from
Aug 19, 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
1 change: 1 addition & 0 deletions configs/config.json.map.example
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"update_map": true,
"mode": "priority",
"map_path": "raw_data",
"walker": "StepWalker",
"catch": {
"==========Legendaries==========": 0,
"Aerodactyl": 1000,
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_cluster.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.cell_workers.utils import find_biggest_cluster
from pokemongo_bot.base_task import BaseTask
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.utils import distance, i2f, format_dist
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pgoapi.utilities import f2i


Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/follow_spiral.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import math

from pokemongo_bot.cell_workers.utils import distance, format_dist
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.base_task import BaseTask

class FollowSpiral(BaseTask):
Expand Down
2 changes: 1 addition & 1 deletion pokemongo_bot/cell_workers/move_to_fort.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pokemongo_bot import inventory
from pokemongo_bot.constants import Constants
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from utils import distance, format_dist, fort_details
Expand Down
11 changes: 6 additions & 5 deletions pokemongo_bot/cell_workers/move_to_map_pokemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
import requests
from pokemongo_bot.base_dir import _base_dir
from pokemongo_bot.cell_workers.utils import distance, format_dist, format_time
from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.walker_factory import walker_factory
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker
Expand Down Expand Up @@ -85,10 +85,10 @@ def initialize(self):
self.caught = []
self.min_ball = self.config.get('min_ball', 1)
self.map_path = self.config.get('map_path', 'raw_data')
self.walker = self.config.get('walker', 'StepWalker')
self.snipe_high_prio_only = self.config.get('snipe_high_prio_only', False)
self.snipe_high_prio_threshold = self.config.get('snipe_high_prio_threshold', 400)


data_file = os.path.join(_base_dir, 'map-caught-{}.json'.format(self.bot.config.username))
if os.path.isfile(data_file):
self.caught = json.load(
Expand Down Expand Up @@ -359,7 +359,7 @@ def _move_to(self, pokemon):
pokemon: Pokemon to move to.

Returns:
StepWalker
Walker
"""
now = int(time.time())
self.emit_event(
Expand All @@ -368,8 +368,9 @@ def _move_to(self, pokemon):
'{disappears_in})'),
data=self._pokemon_event_data(pokemon)
)
return StepWalker(
return walker_factory(self.walker,
self.bot,
pokemon['latitude'],
pokemon['longitude']
pokemon['longitude'],
**{'parent': MoveToMapPokemon}
)
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import unittest
from mock import MagicMock, patch

from pokemongo_bot.step_walker import StepWalker
from pokemongo_bot.walkers.step_walker import StepWalker
from pokemongo_bot.cell_workers.utils import float_equal

NORMALIZED_LAT_LNG_DISTANCE_STEP = 6.3593e-6

class TestStepWalker(unittest.TestCase):
def setUp(self):
self.patcherSleep = patch('pokemongo_bot.step_walker.sleep')
self.patcherRandomLat = patch('pokemongo_bot.step_walker.random_lat_long_delta', return_value=0)
self.patcherSleep = patch('pokemongo_bot.walkers.step_walker.sleep')
self.patcherRandomLat = patch('pokemongo_bot.walkers.step_walker.random_lat_long_delta', return_value=0)
self.patcherSleep.start()
self.patcherRandomLat.start()

Expand Down
2 changes: 0 additions & 2 deletions pokemongo_bot/walkers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
from polyline_generator import Polyline
from polyline_walker import PolylineWalker
49 changes: 46 additions & 3 deletions pokemongo_bot/walkers/polyline_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,48 @@
import polyline
import requests

class PolylineObjectHandler:
'''
Does this need to be a class?
More like a namespace...
'''
_cache = {}
_kill_these = set()

class Polyline(object):
@staticmethod
def cached_polyline(bot, origin, destination, speed, parent_cls):
'''
Google API has limits, so we can't generate new Polyline at every tick...
'''
for key in list(PolylineObjectHandler._kill_these):
PolylineObjectHandler._cache.pop(key)
PolylineObjectHandler._kill_these.remove(key)

key = parent_cls
if key not in PolylineObjectHandler._cache:
polyline = Polyline(origin, destination, speed)
polyline.key = key
polyline.destination = destination

PolylineObjectHandler._cache[key] = polyline
elif key in PolylineObjectHandler._cache and PolylineObjectHandler._cache[key].destination != destination:
# The case bot changes mind to catch Mew instead of following Doduo...
# Merge with upper code? Without comment, it would be quite puzzling...
polyline = Polyline(origin, destination, speed)
polyline.key = key
polyline.destination = destination

PolylineObjectHandler._cache[key] = polyline
else:
polyline = PolylineObjectHandler._cache[key]
return polyline

@staticmethod
def delete_cache(polyline):
PolylineObjectHandler._cache.pop(polyline.key)


class Polyline(object):
def __init__(self, origin, destination, speed):
self.DISTANCE_API_URL='https://maps.googleapis.com/maps/api/directions/json?mode=walking'
self.origin = origin
Expand All @@ -18,12 +57,16 @@ def __init__(self, origin, destination, speed):
'{},{}'.format(*self.destination))
self.request_responce = requests.get(self.URL).json()
try:
# Polyline walker starts teleporting after reaching api query limit.
# throw error here atm, catch it at factory and return StepWalker
# TODO Check what is happening...
self.polyline_points = [x['polyline']['points'] for x in
self.request_responce['routes'][0]['legs'][0]['steps']]
self.request_responce['routes'][0]['legs'][0]['steps']]
except IndexError:
self.polyline_points = self.request_responce['routes']
self.speed = float(speed)
raise # catch at factory atm...
self.points = [self.origin] + self.get_points(self.polyline_points) + [self.destination]
self.speed = float(speed)
self.lat, self.long = self.points[0][0], self.points[0][1]
self.polyline = self.combine_polylines(self.points)
self._timestamp = time.time()
Expand Down
49 changes: 29 additions & 20 deletions pokemongo_bot/walkers/polyline_walker.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
# -*- coding: utf-8 -*-

from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.step_walker import StepWalker
from polyline_generator import Polyline

from pokemongo_bot.walkers.step_walker import StepWalker
from polyline_generator import PolylineObjectHandler
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.constants import Constants

class PolylineWalker(StepWalker):
'''
Heavy multi-botting can cause issue, since the directions API has limits.
'''

def __init__(self, bot, speed, dest_lat, dest_lng):
def __init__(self, bot, speed, dest_lat, dest_lng, parent):
super(PolylineWalker, self).__init__(bot, speed, dest_lat, dest_lng)
self.polyline_walker = Polyline((self.api._position_lat, self.api._position_lng),
(self.destLat, self.destLng), self.speed)
self.bot.event_manager.emit(
'polyline_request',
sender=self,
level='info',
formatted="{url}",
data={'url': self.polyline_walker.URL}
self.polyline_walker = PolylineObjectHandler.cached_polyline(bot, (self.api._position_lat, self.api._position_lng),
(self.destLat, self.destLng), self.speed, parent)
self.dist = distance(
self.bot.position[0],
self.bot.position[1],
dest_lat,
dest_lng
)

def step(self):
cLat, cLng = self.api._position_lat, self.api._position_lng
while (cLat, cLng) != self.polyline_walker.get_pos()[0]:
self.polyline_walker.unpause()
sleep(1)
self.polyline_walker.pause()
cLat, cLng = self.polyline_walker.get_pos()[0]
self.api.set_position(round(cLat, 5), round(cLng, 5), 0)
self.bot.heartbeat()
return True

if self.dist < 10: # 10m, add config? set it at constants?
PolylineObjectHandler.delete_cache(self.polyline_walker)
return True

self.polyline_walker.unpause()
sleep(1)
self.polyline_walker.pause()
cLat, cLng = self.polyline_walker.get_pos()[0]
_, _, alt = self.api.get_position()
self.api.set_position(cLat, cLng, alt)
self.bot.heartbeat()
return False

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from math import sqrt

from random import random
from cell_workers.utils import distance
from human_behaviour import random_lat_long_delta, sleep
from pokemongo_bot.cell_workers.utils import distance
from pokemongo_bot.human_behaviour import random_lat_long_delta, sleep


class StepWalker(object):
Expand Down
15 changes: 15 additions & 0 deletions pokemongo_bot/walkers/walker_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from pokemongo_bot.walkers.polyline_walker import PolylineWalker
from pokemongo_bot.walkers.step_walker import StepWalker

def walker_factory(name, bot, speed, dest_lat, dest_lng, *args, **kwargs):
'''
Charlie and the Walker Factory
'''
if 'StepWalker' == name:
ret = StepWalker(bot, speed, dest_lat, dest_lng)
elif 'PolylineWalker' == name:
try:
ret = PolylineWalker(bot, speed, dest_lat, dest_lng, *args, **kwargs)
except:
ret = StepWalker(bot, speed, dest_lat, dest_lng)
return ret