Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/faeture/xp-improvements' into po…
Browse files Browse the repository at this point in the history
…kemon_optimizer
  • Loading branch information
julienlavergne committed Aug 8, 2016
2 parents e8fd901 + ef2bb53 commit ff1f5e4
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 73 deletions.
19 changes: 14 additions & 5 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import random
import re
import sys
import struct
import time
import Queue
import threading
Expand All @@ -31,7 +32,9 @@
from worker_result import WorkerResult
from tree_config_builder import ConfigException, MismatchTaskApiVersion, TreeConfigBuilder
from sys import platform as _platform
import struct



class PokemonGoBot(object):
@property
def position(self):
Expand Down Expand Up @@ -441,11 +444,16 @@ def tick(self):

# Check if session token has expired
self.check_session(self.position[0:2])
start_tick = time.time()

for worker in self.workers:
if worker.work() == WorkerResult.RUNNING:
return

end_tick = time.time()
if end_tick - start_tick < 5:
time.sleep(5 - (end_tick - start_tick))

def get_meta_cell(self):
location = self.position[0:2]
cells = self.find_close_cells(*location)
Expand Down Expand Up @@ -590,7 +598,7 @@ def check_session(self, position):

# prevent crash if return not numeric value
if not self.is_numeric(self.api._auth_provider._ticket_expire):
self.logger.info("Ticket expired value is not numeric", 'yellow')
self.logger.info("Ticket expired value is not numeric")
return

remaining_time = \
Expand Down Expand Up @@ -650,7 +658,7 @@ def login(self):
def get_encryption_lib(self):
if _platform == "linux" or _platform == "linux2" or _platform == "darwin":
file_name = 'encrypt.so'
elif _platform == "Windows" or _platform == "win32":
elif _platform == "Windows" or _platform == "win32" or _platform == "cygwin":
# Check if we are on 32 or 64 bit
if sys.maxsize > 2**32:
file_name = 'encrypt_64.dll'
Expand All @@ -664,8 +672,9 @@ def get_encryption_lib(self):

full_path = path + '/'+ file_name
if not os.path.isfile(full_path):
self.logger.error(file_name + ' is not found! Please place it in the bots root directory or set libencrypt_location in config.')
self.logger.info('Platform: '+ _platform + ' Encrypt.so directory: '+ path)
self.logger.error(file_name + ' is not found! Please place it in the bots root directory.')
self.logger.info('Platform: '+ _platform)
self.logger.info('Bot root directory: '+ path)
sys.exit(1)
else:
self.logger.info('Found '+ file_name +'! Platform: ' + _platform + ' Encrypt.so directory: ' + path)
Expand Down
66 changes: 39 additions & 27 deletions pokemongo_bot/base_task.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
import logging
import time


class BaseTask(object):
TASK_API_VERSION = 1

def __init__(self, bot, config):
self.bot = bot
self.config = config
self._validate_work_exists()
self.logger = logging.getLogger(type(self).__name__)
self.initialize()

def _validate_work_exists(self):
method = getattr(self, 'work', None)
if not method or not callable(method):
raise NotImplementedError('Missing "work" method')

def emit_event(self, event, sender=None, level='info', formatted='', data={}):
if not sender:
sender=self
self.bot.event_manager.emit(
event,
sender=sender,
level=level,
formatted=formatted,
data=data
)

def initialize(self):
pass
TASK_API_VERSION = 1

def __init__(self, bot, config):
self.bot = bot
self.config = config
self._validate_work_exists()
self.logger = logging.getLogger(type(self).__name__)
self.last_ran = time.time()
self.run_interval = config.get('run_interval', 10)
self.initialize()

def _update_last_ran(self):
self.last_ran = time.time()

def _time_to_run(self):
interval = time.time() - self.last_ran
if interval > self.run_interval:
return True
return False

def _validate_work_exists(self):
method = getattr(self, 'work', None)
if not method or not callable(method):
raise NotImplementedError('Missing "work" method')

def emit_event(self, event, sender=None, level='info', formatted='', data={}):
if not sender:
sender=self
self.bot.event_manager.emit(
event,
sender=sender,
level=level,
formatted=formatted,
data=data
)

def initialize(self):
pass
40 changes: 27 additions & 13 deletions pokemongo_bot/cell_workers/catch_lured_pokemon.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from pokemongo_bot.cell_workers.utils import fort_details
from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.constants import Constants
from pokemongo_bot.cell_workers.utils import fort_details, distance
from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker


class CatchLuredPokemon(BaseTask):
Expand All @@ -12,39 +13,52 @@ class CatchLuredPokemon(BaseTask):
def work(self):
lured_pokemon = self.get_lured_pokemon()
if lured_pokemon:
self.catch_pokemon(lured_pokemon)
for pokemon in lured_pokemon:
self.catch_pokemon(pokemon)

def get_lured_pokemon(self):
forts_in_range = []
pokemon_to_catch = []
forts = self.bot.get_forts(order_by_distance=True)

if len(forts) == 0:
return False

fort = forts[0]
details = fort_details(self.bot, fort_id=fort['id'],
latitude=fort['latitude'],
longitude=fort['longitude'])
fort_name = details.get('name', 'Unknown')
for fort in forts:
distance_to_fort = distance(
self.bot.position[0],
self.bot.position[1],
fort['latitude'],
fort['longitude']
)

encounter_id = fort.get('lure_info', {}).get('encounter_id', None)
if distance_to_fort < Constants.MAX_DISTANCE_FORT_IS_REACHABLE and encounter_id:
forts_in_range.append(fort)


encounter_id = fort.get('lure_info', {}).get('encounter_id', None)
for fort in forts_in_range:
details = fort_details(self.bot, fort_id=fort['id'],
latitude=fort['latitude'],
longitude=fort['longitude'])
fort_name = details.get('name', 'Unknown')
encounter_id = fort['lure_info']['encounter_id']

if encounter_id:
result = {
'encounter_id': encounter_id,
'fort_id': fort['id'],
'fort_name': u"{}".format(fort_name),
'latitude': fort['latitude'],
'longitude': fort['longitude']
}
pokemon_to_catch.append(result)

self.emit_event(
'lured_pokemon_found',
formatted='Lured pokemon at fort {fort_name} ({fort_id})',
data=result
)
return result

return False
return pokemon_to_catch

def catch_pokemon(self, pokemon):
worker = PokemonCatchWorker(pokemon, self.bot)
Expand Down
23 changes: 19 additions & 4 deletions pokemongo_bot/cell_workers/catch_visible_pokemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ def work(self):
lambda x: distance(self.bot.position[0], self.bot.position[1], x['latitude'], x['longitude'])
)
user_web_catchable = 'web/catchable-{}.json'.format(self.bot.config.username)


for pokemon in self.bot.cell['catchable_pokemons']:
with open(user_web_catchable, 'w') as outfile:
json.dump(pokemon, outfile)
self.emit_event(
'catchable_pokemon',
level='debug',
level='info',
data={
'pokemon_id': pokemon['pokemon_id'],
'spawn_point_id': pokemon['spawn_point_id'],
Expand All @@ -32,16 +34,29 @@ def work(self):
'expiration_timestamp_ms': pokemon['expiration_timestamp_ms'],
}
)

return self.catch_pokemon(self.bot.cell['catchable_pokemons'].pop(0))
self.catch_pokemon(pokemon)

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

for pokemon in self.bot.cell['wild_pokemons']:
self.emit_event(
'catchable_pokemon',
level='info',
data={
'pokemon_id': pokemon['pokemon_data']['pokemon_id'],
'spawn_point_id': pokemon['spawn_point_id'],
'encounter_id': pokemon['encounter_id'],
'latitude': pokemon['latitude'],
'longitude': pokemon['longitude'],
'expiration_timestamp_ms': pokemon['time_till_hidden_ms'],
}
)
self.catch_pokemon(pokemon)

def catch_pokemon(self, pokemon):
worker = PokemonCatchWorker(pokemon, self.bot)
Expand Down
6 changes: 5 additions & 1 deletion pokemongo_bot/cell_workers/collect_level_up_reward.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pokemongo_bot.base_task import BaseTask

from pokemongo_bot.worker_result import WorkerResult

class CollectLevelUpReward(BaseTask):
SUPPORTED_TASK_API_VERSION = 1
Expand All @@ -12,6 +12,10 @@ def initialize(self):
self.previous_level = 0

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

self.current_level = self._get_current_level()

# let's check level reward on bot initialization
Expand Down
8 changes: 7 additions & 1 deletion pokemongo_bot/cell_workers/evolve_pokemon.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.item_list import Item
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.worker_result import WorkerResult


class EvolvePokemon(BaseTask):
Expand All @@ -23,7 +24,9 @@ def _validate_config(self):

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

self._update_last_ran()

response_dict = self.api.get_inventory()
inventory_items = response_dict.get('responses', {}).get('GET_INVENTORY', {}).get('inventory_delta', {}).get(
Expand All @@ -42,6 +45,9 @@ def work(self):
self._execute_pokemon_evolve(pokemon, candy_list, cache)

def _should_run(self):
if not self._time_to_run():
return False

if not self.evolve_all or self.evolve_all[0] == 'none':
return False

Expand Down
5 changes: 5 additions & 0 deletions pokemongo_bot/cell_workers/incubate_eggs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.worker_result import WorkerResult


class IncubateEggs(BaseTask):
Expand All @@ -21,6 +22,10 @@ def _process_config(self):
self.longer_eggs_first = self.config.get("longer_eggs_first", True)

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

try:
self._check_inventory()
except:
Expand Down
9 changes: 5 additions & 4 deletions pokemongo_bot/cell_workers/move_to_fort.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ class MoveToFort(BaseTask):

def initialize(self):
self.lure_distance = 0
self.lure_attraction = True #self.config.get("lure_attraction", True)
self.lure_max_distance = 2000 #self.config.get("lure_max_distance", 2000)
self.lure_attraction = self.config.get("lure_attraction", True)
self.lure_max_distance = self.config.get("lure_max_distance", 2000)
self.ignore_item_count = self.config.get("ignore_item_count", False)

def should_run(self):
has_space_for_loot = self.bot.has_space_for_loot()
if not has_space_for_loot:
self.emit_event(
'inventory_full',
formatted="Not moving to any forts as there aren't enough space. You might want to change your config to recycle more items if this message appears consistently."
formatted="Inventory is full. You might want to change your config to recycle more items if this message appears consistently."
)
return has_space_for_loot or self.bot.softban
return has_space_for_loot or self.ignore_item_count or self.bot.softban

def is_attracted(self):
return (self.lure_distance > 0)
Expand Down
6 changes: 6 additions & 0 deletions pokemongo_bot/cell_workers/nickname_pokemon.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pokemongo_bot.human_behaviour import sleep
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.worker_result import WorkerResult


class NicknamePokemon(BaseTask):
SUPPORTED_TASK_API_VERSION = 1
Expand All @@ -10,6 +12,10 @@ def initialize(self):
self.template = ""

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

try:
inventory = reduce(dict.__getitem__, ["responses", "GET_INVENTORY", "inventory_delta", "inventory_items"], self.bot.get_inventory())
except KeyError:
Expand Down
6 changes: 6 additions & 0 deletions pokemongo_bot/cell_workers/recycle_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import os
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.tree_config_builder import ConfigException
from pokemongo_bot.worker_result import WorkerResult


class RecycleItems(BaseTask):
SUPPORTED_TASK_API_VERSION = 1
Expand All @@ -18,6 +20,10 @@ def _validate_item_filter(self):
raise ConfigException("item {} does not exist, spelling mistake? (check for valid item names in data/items.json)".format(config_item_name))

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

self.bot.latest_inventory = None
item_count_dict = self.bot.item_inventory_count('all')

Expand Down
Loading

0 comments on commit ff1f5e4

Please sign in to comment.