Skip to content

Commit

Permalink
Completing tutorial with a final Pok茅stop spin (#1857)
Browse files Browse the repository at this point in the history
* Initiate orphan branch

* Orphan branch initiated

* Initial commit

* Provide a basic documentation

* Fix documentation, try to pep8

* Fix syntax, indents and flake8

* Make flake8 happy

* Over-indented, under-indented - decide :-P

* Let's see what I broke

* Broke a lot.

* Please learn python, Arengo

* I love you Flake8

* ^loves me, too. Changed to better sleeps

* Import the needed functions, move level check to account.py, improve documentation

* r

* Add check if accidently disabled pokestop parsing

* Fix requested changes

* Minor text fix

* Remove duplicate, fix typo

* Fix my python skills (loading...)

* Removed unnecessary variable, reduced code size

* No need to spam a debug message

* Another function emigration, fix spamming debug messages, improving documentation

* Minor text fixes

* r

* Minor text fix

* Address requested changes

* Fix possible syntax error

* Using the correct object to check

* Stupid Arengo tries to access ghost variables

* Minor text fixes.

* Update tutorial.md
  • Loading branch information
SiteEffect authored and sebastienvercammen committed Mar 15, 2017
1 parent cf32f73 commit b5e1bcb
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 2 deletions.
33 changes: 33 additions & 0 deletions docs/extras/tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# RocketMap tutorial completion for accounts (up to Level 2)
This is a guide on how to complete the Pok茅mon Go tutorial steps and becoming
level 2 on your accounts as fast as possible, so you can use `-tut` once
on all accounts and disable it again afterwards.

## Instruction
* We assume you are running a basic RocketMap installation. Using the hashing
service with the latest API version will avoid accounts being flagged.
* Create a ``config/config.tutorial.ini`` file by copying and renaming
``config/config.ini.example`` and make the following changes:
* Config changes are:
* Set location next to at least one known Pokestop, a cluster is preferred.
* Set step distance to ``st: 1``.
* Set scan delay ``sd`` to a value which provides enough calls during the
following set search time (a good value is around ``sd: 15`` or lower).
* Set the account search interval to approx. ``asi: 120``.
* Set the account rest interval as high as possible so all accounts get
cycled and none return, a safe value is ``ari: 36000``.
* Set login delay to at least ``login_delay: 1`` to avoid throttling.
* Put the accounts that need to complete the tutorial and need to level up
into your ``accounts.csv`` file.
* Set up an instance with the following flags:
* ``--complete-tutorial`` or just ``-tut``
* ``--config config/config.tutorial.ini`` or just
``-cf config/config.tutorial.ini`` to use a designated config file.
* ``--accountcsv PATH/accounts.csv`` or just ``-ac PATH/accounts.csv``
* ``-w WORKER`` to set your simultaneously working accounts to a reasonable
number, considering hash key limit and throttling. You can have at least 10
accounts running at the same time without any problems.
* If you are not using fresh accounts and you are not using the hashing service,
prepare for captchas. Set up your RocketMap accordingly.
* Enable ``-v`` in process if you want to see the debug logs.
* Let it run and your accounts will complete the tutorial and rise to level 2.
105 changes: 105 additions & 0 deletions pogom/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from pgoapi.exceptions import AuthException

from .utils import in_radius

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -200,3 +202,106 @@ def complete_tutorial(api, account, tutorial_state):
account['username'])
time.sleep(random.uniform(2, 4))
return True


# Complete tutorial with a level up by a Pokestop spin.
# API argument needs to be a logged in API instance.
# Called during fort parsing in models.py
def tutorial_pokestop_spin(api, map_dict, forts, step_location, account):
player_level = get_player_level(map_dict)
if player_level > 1:
log.debug(
'No need to spin a Pokestop. ' +
'Account %s is already level %d.',
account['username'], player_level)
else: # Account needs to spin a Pokestop for level 2.
log.debug(
'Spinning Pokestop for account %s.',
account['username'])
for fort in forts:
if fort.get('type') == 1:
if spin_pokestop(api, fort, step_location):
log.debug(
'Account %s successfully spun a Pokestop ' +
'after completed tutorial.',
account['username'])
return True

return False


def get_player_level(map_dict):
inventory_items = map_dict['responses'].get(
'GET_INVENTORY', {}).get(
'inventory_delta', {}).get(
'inventory_items', [])
player_stats = [item['inventory_item_data']['player_stats']
for item in inventory_items
if 'player_stats' in item.get(
'inventory_item_data', {})]
if len(player_stats) > 0:
player_level = player_stats[0].get('level', 1)
return player_level

return 0


def spin_pokestop(api, fort, step_location):
spinning_radius = 0.04
if in_radius((fort['latitude'], fort['longitude']), step_location,
spinning_radius):
log.debug('Attempt to spin Pokestop (ID %s)', fort['id'])

time.sleep(random.uniform(0.8, 1.8)) # Do not let Niantic throttle
spin_response = spin_pokestop_request(api, fort, step_location)
time.sleep(random.uniform(2, 4)) # Do not let Niantic throttle

# Check for reCaptcha
captcha_url = spin_response['responses'][
'CHECK_CHALLENGE']['challenge_url']
if len(captcha_url) > 1:
log.debug('Account encountered a reCaptcha.')
return False

spin_result = spin_response['responses']['FORT_SEARCH']['result']
if spin_result is 1:
log.debug('Successful Pokestop spin.')
return True
elif spin_result is 2:
log.debug('Pokestop was not in range to spin.')
elif spin_result is 3:
log.debug('Failed to spin Pokestop. Has recently been spun.')
elif spin_result is 4:
log.debug('Failed to spin Pokestop. Inventory is full.')
elif spin_result is 5:
log.debug('Maximum number of Pokestops spun for this day.')
else:
log.debug(
'Failed to spin a Pokestop. Unknown result %d.',
spin_result)

return False


def spin_pokestop_request(api, fort, step_location):
try:
req = api.create_request()
spin_pokestop_response = req.fort_search(
fort_id=fort['id'],
fort_latitude=fort['latitude'],
fort_longitude=fort['longitude'],
player_latitude=step_location[0],
player_longitude=step_location[1])
spin_pokestop_response = req.check_challenge()
spin_pokestop_response = req.get_hatched_eggs()
spin_pokestop_response = req.get_inventory()
spin_pokestop_response = req.check_awarded_badges()
spin_pokestop_response = req.download_settings()
spin_pokestop_response = req.get_buddy_walked()
spin_pokestop_response = req.call()

return spin_pokestop_response

except Exception as e:
log.warning('Exception while spinning Pokestop: %s', repr(e))
return False
19 changes: 18 additions & 1 deletion pogom/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
get_move_name, get_move_damage, get_move_energy, get_move_type
from .transform import transform_from_wgs_to_gcj, get_new_coords
from .customLog import printPokemon
from .account import tutorial_pokestop_spin
log = logging.getLogger(__name__)

args = get_args()
Expand Down Expand Up @@ -1683,7 +1684,7 @@ def hex_bounds(center, steps=None, radius=None):

# todo: this probably shouldn't _really_ be in "models" anymore, but w/e.
def parse_map(args, map_dict, step_location, db_update_queue, wh_update_queue,
api, now_date):
api, now_date, account):
pokemon = {}
pokestops = {}
gyms = {}
Expand All @@ -1698,6 +1699,7 @@ def parse_map(args, map_dict, step_location, db_update_queue, wh_update_queue,
new_spawn_points = []
sp_id_list = []
now_secs = date_secs(now_date)
captcha_url = ''

# Consolidate the individual lists in each cell into two lists of Pokemon
# and a list of forts.
Expand Down Expand Up @@ -1862,6 +1864,11 @@ def parse_map(args, map_dict, step_location, db_update_queue, wh_update_queue,
encounter_result = req.get_buddy_walked()
encounter_result = req.call()

captcha_url = encounter_result['responses']['CHECK_CHALLENGE'][
'challenge_url'] # Check for captcha
if len(captcha_url) > 1: # Throw warning but finish parsing
log.debug('Account encountered a reCaptcha.')

pokemon[p['encounter_id']] = {
'encounter_id': b64encode(str(p['encounter_id'])),
'spawnpoint_id': p['spawn_point_id'],
Expand Down Expand Up @@ -1924,6 +1931,16 @@ def parse_map(args, map_dict, step_location, db_update_queue, wh_update_queue,
(f['last_modified'] -
datetime(1970, 1, 1)).total_seconds())) for f in query]

# Complete tutorial with a Pokestop spin
if args.complete_tutorial and not (len(captcha_url) > 1):
if config['parse_pokestops']:
tutorial_pokestop_spin(
api, map_dict, forts, step_location, account)
else:
log.error(
'Pokestop can not be spun since parsing Pokestops is ' +
'not active. Check if \'-nk\' flag is accidently set.')

for f in forts:
if config['parse_pokestops'] and f.get('type') == 1: # Pokestops.
if 'active_fort_modifier' in f:
Expand Down
2 changes: 1 addition & 1 deletion pogom/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ def search_worker_thread(args, account_queue, account_failures,
break

parsed = parse_map(args, response_dict, step_location,
dbq, whq, api, scan_date)
dbq, whq, api, scan_date, account)
scheduler.task_done(status, parsed)
if parsed['count'] > 0:
status['success'] += 1
Expand Down

0 comments on commit b5e1bcb

Please sign in to comment.