def _parse_responses(self, responses): for response_type in responses.keys(): response = responses[response_type] if response_type == 'GET_INBOX': self._parse_inbox_response(response) del responses[response_type] elif response_type == 'GET_HOLO_INVENTORY': api_inventory = response # Set an (empty) inventory if necessary if self.inventory is None: self.inventory = {} # Update inventory (balls, items) self._parse_inventory_delta(api_inventory) self._update_inventory_totals() # Update last timestamp for inventory requests self._last_timestamp_ms = api_inventory.inventory_delta.new_timestamp_ms # Clean up del responses[response_type] # Get settings hash from response for future calls elif response_type == 'DOWNLOAD_SETTINGS': if response.hash: self._download_settings_hash = response.hash # TODO: Check forced client version and exit program if different # Clean up del responses[response_type] elif response_type == 'GET_PLAYER': self._player_state = { 'tutorial_state': response.player_data.tutorial_state, 'buddy': response.player_data.buddy_pokemon.id, 'warn': response.warn, 'banned': response.banned } # Clean up del responses[response_type] if self._player_state['banned']: self.log_warning("GET_PLAYER has the 'banned' flag set.") raise BannedAccountException # Check for captcha elif response_type == 'CHECK_CHALLENGE': self.captcha_url = response.challenge_url # Clean up del responses[response_type] if self.has_captcha() and self.cfg['exception_on_captcha']: raise CaptchaException elif response_type == 'GET_MAP_OBJECTS': if is_rareless_scan(response): if self.rareless_scans is None: self.rareless_scans = 1 else: self.rareless_scans += 1 else: self.rareless_scans = 0 elif response_type == 'GET_HATCHED_EGGS': if self.callback_egg_hatched and response.success and len( response.hatched_pokemon) > 0: for i in range(0, len(response.pokemon_id)): hatched_egg = { 'experience_awarded': response.experience_awarded[i], 'candy_awarded': response.candy_awarded[i], 'stardust_awarded': response.stardust_awarded[i], 'egg_km_walked': response.egg_km_walked[i], 'hatched_pokemon': response.hatched_pokemon[i] } self.callback_egg_hatched(self, hatched_egg)
def search_worker(args, scheduler, enc_list): #scheduler = Scheduler(args) details = account_queue.get() initial_location = scheduler.next_item(details) #log.info(str(initial_location)) details['latitude'] = initial_location[0] details['longitude'] = initial_location[1] try: api = create_api(args, details, initial_location) #api.log_info('Setting up at {}, {}.'.format(initial_location[0], # initial_location[1])) last_action = datetime.utcnow() #log.info('Setting last action') rareless_scan_count = 0 #log.info('Setting rareless scans count') if not api.is_logged_in(): log.error('Account {} not logged in.'.format(api.username)) return if api.is_banned(): log.error('Account {} banned.'.format(api.username)) return if api.has_captcha(): log.error('Account {} CAPTCHA\'d.'.format(api.username)) return api.log_info('Level: {} ({} / {} XP), Pokestops spun: {}, Pokemon ' 'caught: {}, KM Walked: {}'.format( api.get_stats('level', 1), api.get_stats('experience', 0), api.get_stats('next_level_xp', 0), api.get_stats('poke_stop_visits', 0), api.get_stats('pokemons_captured', 0), api.get_stats('km_walked', 0.))) except Exception as e: log.error(repr(e)) return while True: #log.info('Pulling location') loc = scheduler.next_item(details) #log.info('Pulled location') #log.info(str(loc)) gp = geopy.Point(loc[0], loc[1]) now_date = datetime.utcnow() meters = geopy.distance.vincenty(loc, (api.latitude, api.longitude))\ .meters secs_to_arrival = meters / float(args.kph) * 3.6 secs_waited = (now_date - last_action).total_seconds() secs_to_arrival = max(secs_to_arrival - secs_waited, 0) api.log_info('Moving to {} (will take {} seconds to travel)'.format( gp.format_decimal(), round(secs_to_arrival, 2))) #log.info('{} seconds to arrive'.format(secs_to_arrival)) sleep(secs_to_arrival) api.set_position(loc[0], loc[1], 0) details['latitude'] = loc[0] details['longitude'] = loc[1] gmo = api.req_get_map_objects()['GET_MAP_OBJECTS'] try: weather_info = gmo.client_weather[0] # NONE (0) # CLEAR (1) # RAINY (2) # PARTLY_CLOUDY (3) # OVERCAST (4) # WINDY (5) # SNOW (6) # FOG (7) condition = weather_info.gameplay_weather.gameplay_condition except Exception: condition = 0 cells = gmo.map_cells rareless = is_rareless_scan(gmo) if rareless: rareless_scan_count += 1 if not rareless: rareless_scan_count = 0 if rareless_scan_count > 10: log.warning( 'Account {} may be shadowbanned. {} scans without rare ' 'Pokemon.'.format(api.username, rareless_scan_count)) if rareless_scan_count >= 25: # Die. log.error( 'Account {} is shadowbanned. {} scans without rare Pokemon. Exiting.' .format(api.username, rareless_scan_count)) return last_action = datetime.utcnow() counts = {'pokemon': 0, 'nearby': 0, 'raids': 0, 'forts': 0} for cell in cells: counts['nearby'] += len(cell.nearby_pokemons) for f in cell.forts: counts['forts'] += 1 if f.raid_info.raid_level != 0: counts['raids'] += 1 raid = f.raid_info if raid.raid_battle_ms > now_ms(): dbq.put((Raid, { 'raid_seed': raid.raid_seed, 'gym_id': f.id, 'spawn': datetime.fromtimestamp(raid.raid_spawn_ms / 1000), 'start': datetime.fromtimestamp(raid.raid_battle_ms / 1000), 'end': datetime.fromtimestamp(raid.raid_end_ms / 1000), 'level': raid.raid_level, 'pokemon_id': None, 'cp': None, 'move_1': None, 'move_2': None, 'latitude': f.latitude, 'longitude': f.longitude })) else: dbq.put((Raid, { 'raid_seed': raid.raid_seed, 'gym_id': f.id, 'spawn': datetime.fromtimestamp(raid.raid_spawn_ms / 1000), 'start': datetime.fromtimestamp(raid.raid_battle_ms / 1000), 'end': datetime.fromtimestamp(raid.raid_end_ms / 1000), 'level': raid.raid_level, 'pokemon_id': raid.raid_pokemon.pokemon_id, 'cp': raid.raid_pokemon.cp, 'move_1': raid.raid_pokemon.move_1, 'move_2': raid.raid_pokemon.move_2, 'latitude': f.latitude, 'longitude': f.longitude })) for p in cell.wild_pokemons: counts['pokemon'] += 1 spawn = SpawnPoint.find_spawn(p.spawn_point_id, p.latitude, p.longitude) disappear = calculate_disappear(p, spawn) if p.pokemon_data.pokemon_id in DITTO_IDS and args.ditto_detection: api.log_info('Trying to check a Ditto at {}, {}.'.format( p.latitude, p.longitude)) enc = api.req_encounter(encounter_id=p.encounter_id, spawn_point_id=p.spawn_point_id, latitude=p.latitude, longitude=p.longitude)['ENCOUNTER'] if enc.status == 1: i = 0 while i < 5: api.log_info('Catch attempt #{}.'.format(i + 1)) catch = api.req_catch_pokemon( encounter_id=p.encounter_id, spawn_point_id=p.spawn_point_id, normalized_reticle_size=1.95, spin_modifier=1., ball=1)['CATCH_POKEMON'] if catch.status == 1: api.log_info( 'Pokemon caught. (ID: {}, CP: {}, IV: {})'. format( api.last_caught_pokemon['pokemon_id'], api.last_caught_pokemon['cp'], get_iv(api.last_caught_pokemon))) if api.last_caught_pokemon[ 'pokemon_id'] == 132: api.log_info( 'Ditto found at {}, {}!'.format( p.latitude, p.longitude)) try: dbq.put((Pokemon, { 'encounter_id': b64_e(p.encounter_id), 'spawnpoint_id': p.spawn_point_id, 'pokemon_id': 132, 'latitude': p.latitude, 'longitude': p.longitude, 'disappear_time': disappear, 'gender': api.last_caught_pokemon['gender'], 'form': api.last_caught_pokemon['form'], 'disguise': p.pokemon_data.pokemon_id, 'weather': condition })) except Exception as e: log.error(repr(e)) break else: api.log_info('Not a Ditto.') try: dbq.put((Pokemon, { 'encounter_id': b64_e(p.encounter_id), 'spawnpoint_id': p.spawn_point_id, 'pokemon_id': p.pokemon_data.pokemon_id, 'latitude': p.latitude, 'longitude': p.longitude, 'disappear_time': disappear, 'gender': p.pokemon_data.pokemon_display. gender, 'form': p.pokemon_data.pokemon_display. form, 'weather': condition })) except Exception as e: log.error(repr(e)) break elif catch.status == 3: try: dbq.put((Pokemon, { 'encounter_id': b64_e(p.encounter_id), 'spawnpoint_id': p.spawn_point_id, 'pokemon_id': p.pokemon_data.pokemon_id, 'latitude': p.latitude, 'longitude': p.longitude, 'disappear_time': disappear, 'gender': p.pokemon_data.pokemon_display.gender, 'form': p.pokemon_data.pokemon_display.form, 'weather': condition })) except Exception as e: log.error(repr(e)) break elif catch.status not in [1, 3]: sleep(0.1) i += 1 if i > 5: break if p.pokemon_data.pokemon_id in enc_list: scout = pgscout_encounter(p, args) try: dbq.put((Pokemon, { 'encounter_id': b64_e(p.encounter_id), 'spawnpoint_id': p.spawn_point_id, 'pokemon_id': p.pokemon_data.pokemon_id, 'latitude': p.latitude, 'longitude': p.longitude, 'disappear_time': disappear, 'gender': p.pokemon_data.pokemon_display.gender, 'form': p.pokemon_data.pokemon_display.form, 'iv_attack': scout.get('iv_attack', None), 'iv_defense': scout.get('iv_defense', None), 'iv_stamina': scout.get('iv_stamina', None), 'move_1': scout.get('move_1', None), 'move_2': scout.get('move_2', None), 'cp': scout.get('cp', None), 'cp_multiplier': scout.get('cp_multiplier', None), 'level': scout.get('level', None), 'height': scout.get('height', None), 'weight': scout.get('weight', None), 'weather': condition })) except Exception as e: log.error(repr(e)) else: try: dbq.put((Pokemon, { 'encounter_id': b64_e(p.encounter_id), 'spawnpoint_id': p.spawn_point_id, 'pokemon_id': p.pokemon_data.pokemon_id, 'latitude': p.latitude, 'longitude': p.longitude, 'disappear_time': disappear, 'gender': p.pokemon_data.pokemon_display.gender, 'form': p.pokemon_data.pokemon_display.form, 'weather': condition })) except Exception as e: log.error(repr(e)) for f in cell.forts: dist = geopy.distance.vincenty( (api.latitude, api.longitude), (f.latitude, f.longitude)).kilometers if dist <= 0.04 and f.type == 1 and f.enabled and args.spin_pokestops: api.log_info('Spinning a Pokestop at {}, {}.'.format( f.latitude, f.longitude)) api.seq_spin_pokestop(f.id, f.latitude, f.longitude, api.latitude, api.longitude) # DON'T LET NIANTIC THROTTLE. *SWEATING* sleep(random.random()) api.log_info( 'Parse at {} returned {} Pokemon ({} nearby), {} forts and {} raids.' .format(gp.format_decimal(), counts['pokemon'], counts['nearby'], counts['forts'], counts['raids'])) # Other shit. # details['inventory_ts'] = api._item_templates_time # details['ds_hash'] = api._download_settings_hash scheduler.item_done(loc)