def map_request(api, position, no_jitter=False): # Create scan_location to send to the api based off of position, because # tuples aren't mutable. if no_jitter: # Just use the original coordinates. scan_location = position else: # Jitter it, just a little bit. scan_location = jitter_location(position) log.debug('Jittered to: %f/%f/%f', scan_location[0], scan_location[1], scan_location[2]) try: cell_ids = util.get_cell_ids(scan_location[0], scan_location[1]) timestamps = [0, ] * len(cell_ids) req = api.create_request() response = req.get_map_objects(latitude=f2i(scan_location[0]), longitude=f2i(scan_location[1]), since_timestamp_ms=timestamps, cell_id=cell_ids) response = req.check_challenge() response = req.get_hatched_eggs() response = req.get_inventory() response = req.check_awarded_badges() response = req.download_settings() response = req.get_buddy_walked() response = req.call() return response except Exception as e: log.warning('Exception while downloading map: %s', repr(e)) return False
def nearby_map_objects(self): self._posf = self.api.get_position() cell_ids = util.get_cell_ids(lat=self._posf[0], long=self._posf[1], radius=500) timestamps = [0, ] * len(cell_ids) response = self.api.get_map_objects(latitude=self._posf[0], longitude=self._posf[1], since_timestamp_ms=timestamps, cell_id=cell_ids) self.response_parser(res=response) return response
def get_map_objects(self): time.sleep(1) cell_id = utilities.get_cell_ids(self.lat, self.lng) timestamp = [0, ] * len(cell_id) map_dict = self.api.get_map_objects( latitude = self.lat, longitude = self.lng, since_timestamp_ms = timestamp, cell_id = cell_id ) map_objects = map_dict.get( 'responses', {} ).get('GET_MAP_OBJECTS', {}) status = map_objects.get('status', None) map_cells = [] if status and status == 1: map_cells = map_objects['map_cells'] map_cells.sort( key=lambda x: gpxpy.geo.haversine_distance( self.lat, self.lng, x['forts'][0]['latitude'], x['forts'][0]['longitude'] ) if x.get('forts', []) else 1e6 ) return map_cells
def scan(self): log.info('Current public IP address: %s', load(urlopen('http://httpbin.org/ip'))['origin']) ScanMetrics.NUM_STEPS = len(self.scan_config.COVER) log.info("Starting scan of {} locations".format(ScanMetrics.NUM_STEPS)) for i, next_pos in enumerate(self.next_position()): log.debug('Scanning step {:d} of {:d}.'.format(i, ScanMetrics.NUM_STEPS)) log.debug('Scan location is {:f}, {:f}'.format(next_pos[0], next_pos[1])) # TODO: Add error throttle cell_ids = get_cell_ids(next_pos[0], next_pos[1], radius=70) timestamps = [0, ] * len(cell_ids) self.api.get_map_objects( latitude=f2i(next_pos[0]), longitude=f2i(next_pos[1]), cell_id=cell_ids, since_timestamp_ms=timestamps, position=next_pos, callback=Scanner.callback) while not self.api.is_work_queue_empty(): # Location change if self.scan_config.RESTART: log.info("Restarting scan") self.api.empty_work_queue() else: time.sleep(2)
def scan(self): ScanMetrics.NUM_STEPS = len(self.scan_config.COVER) log.info("Starting scan of {} locations".format(ScanMetrics.NUM_STEPS)) for i, next_pos in enumerate(self.next_position()): log.debug('Scanning step {:d} of {:d}.'.format(i, ScanMetrics.NUM_STEPS)) log.debug('Scan location is {:f}, {:f}'.format(next_pos[0], next_pos[1])) # TODO: Add error throttle cell_ids = get_cell_ids(next_pos[0], next_pos[1], radius=70) timestamps = [0, ] * len(cell_ids) self.api.get_map_objects( latitude=f2i(next_pos[0]), longitude=f2i(next_pos[1]), cell_id=cell_ids, since_timestamp_ms=timestamps, position=next_pos, callback=Scanner.callback) while not self.api.is_work_queue_empty(): # Location change if self.scan_config.RESTART: log.info("Restarting scan") self.api.empty_work_queue() else: time.sleep(2) self.api.wait_until_done() # Work queue empty != work done
def req_get_map_objects(self): """Scans current account location.""" # Make sure that we don't hammer with GMO requests diff = self._last_gmo + self.cfg['scan_delay'] - time.time() if diff > 0: time.sleep(diff) # Jitter if wanted if self.cfg['jitter_gmo']: lat, lng = jitter_location(self.latitude, self.longitude) else: lat, lng = self.latitude, self.longitude cell_ids = get_cell_ids(lat, lng) timestamps = [ 0, ] * len(cell_ids) responses = self.perform_request( lambda req: req.get_map_objects(latitude=f2i(lat), longitude=f2i(lng), since_timestamp_ms=timestamps, cell_id=cell_ids), get_inbox=True) self._last_gmo = self._last_request return responses
def req_get_map_objects(self): """Scans current account location.""" # Make sure that we don't hammer with GMO requests diff = self._last_gmo + self.cfg['scan_delay'] - time.time() if diff > 0: time.sleep(diff) # We jitter here because we need the jittered location NOW lat, lng = jitter_location(self.latitude, self.longitude) self._api.set_position(lat, lng, self.altitude) cell_ids = get_cell_ids(lat, lng) timestamps = [ 0, ] * len(cell_ids) responses = self.perform_request( lambda req: req.get_map_objects(latitude=f2i(lat), longitude=f2i(lng), since_timestamp_ms=timestamps, cell_id=cell_ids), get_inbox=True, jitter=False # we already jittered ) self._last_gmo = self._last_request return responses
def telemon(): cell_ids = util.get_cell_ids(target_lat, target_lng) timestamps = [ 0, ] * len(cell_ids) req = api.create_request() req.get_map_objects(latitude=target_lat, longitude=target_lng, since_timestamp_ms=timestamps, cell_id=cell_ids) response = req.call() cells = response['responses']['GET_MAP_OBJECTS'][ 'map_cells'] print('Response dictionary:\n\r{}'.format( pprint.PrettyPrinter(indent=4).pformat(response))) for cell in cells: pkm_raw.extend(cell.get('catchable_pokemons', [])) for i in pkm_raw: if i not in pkm: pkm.append(i) n = len(pkm) global trial if n == 0 and trial < 4: trial += 1 trial_count = "TRIAL: " + str(trial) print trial_count time.sleep(1) return telemon() return
def find_close_cells(self, lat, lng): cellid = get_cell_ids(lat, lng) timestamp = [0, ] * len(cellid) self.api.get_map_objects( latitude=f2i(lat), longitude=f2i(lng), since_timestamp_ms=timestamp, cell_id=cellid ) response_dict = get_api_response(self.api) map_objects = response_dict.get('responses', {}).get('GET_MAP_OBJECTS', {}) status = map_objects.get('status', None) map_cells = [] if status and status == 1: map_cells = map_objects['map_cells'] position = (lat, lng, 0) map_cells.sort( key=lambda x: distance( lat, lng, x['forts'][0]['latitude'], x['forts'][0]['longitude']) if x.get('forts', []) else 1e6 ) return map_cells
def send_map_request (self, user, position): try: cell_ids = util.get_cell_ids(position[0], position[1]) user._last_call = time.time() timestamps = [0,] * len(cell_ids) return user.get_map_objects( latitude=util.f2i(position[0]), longitude=util.f2i(position[1]), since_timestamp_ms=timestamps, cell_id=cell_ids ) except ServerSideAccessForbiddenException as e: logging.info("User {} or IP might be banned, attempting recovery...".format(user._data["username"])) with self._lock: now = time.time() if now - self._last_vpn_retry >= self._delay_between_vpn_retries: self._last_vpn_retry = now if self._num_vpn_retries < self._max_vpn_retries_before_switch: logging.info("Restarting vpn ({} times so far)".format(self._num_vpn_retries)) subprocess.call([self._restart_vpn_file]) self._num_vpn_retries += 1 else: logging.info("Restarted vpn too many times. Switching to a different vpn now") subprocess.call([self._switch_vpn_file]) self._num_vpn_retries = 0 # we can hold the lock for a bit during re-auth since there's # no point in retrying in other threads in the meantime self.auth_users() except Exception as e: logging.info("Uncaught exception when downloading map: {}".format(e)) return False
def doScan(wid, sLat, sLng, api): #print ('scanning ({}, {})'.format(sLat, sLng)) api.set_position(sLat,sLng,0) cell_ids = util.get_cell_ids(lat=sLat, long=sLng, radius=80) timestamps = [0,] * len(cell_ids) while True: try: response_dict = api.get_map_objects(latitude = sLat, longitude = sLng, since_timestamp_ms = timestamps, cell_id = cell_ids) except ServerSideRequestThrottlingException: config['scanDelay'] += 0.5 print ('Request throttled, increasing sleep by 0.5 to {}').format(config['scanDelay']) time.sleep(config['scanDelay']) continue except: time.sleep(config['scanDelay']) api.set_position(sLat,sLng,0) time.sleep(config['scanDelay']) continue break try: cells = response_dict['responses']['GET_MAP_OBJECTS']['map_cells'] except TypeError: print ('thread {} error getting map data for {}, {}'.format(wid,sLat, sLng)) raise except KeyError: print ('thread {} error getting map data for {}, {}'.format(wid,sLat, sLng)) raise return for cell in cells: curTime = cell['current_timestamp_ms'] if 'wild_pokemons' in cell: for wild in cell['wild_pokemons']: if wild['time_till_hidden_ms']>0: timeSpawn = (curTime+(wild['time_till_hidden_ms']))-900000 gmSpawn = time.gmtime(int(timeSpawn/1000)) secSpawn = (gmSpawn.tm_min*60)+(gmSpawn.tm_sec) phash = '{},{}'.format(timeSpawn,wild['spawn_point_id']) shash = '{},{}'.format(secSpawn,wild['spawn_point_id']) pokeLog = {'time':timeSpawn, 'sid':wild['spawn_point_id'], 'lat':wild['latitude'], 'lng':wild['longitude'], 'pid':wild['pokemon_data']['pokemon_id'], 'cell':CellId.from_lat_lng(LatLng.from_degrees(wild['latitude'], wild['longitude'])).to_token()} spawnLog = {'time':secSpawn, 'sid':wild['spawn_point_id'], 'lat':wild['latitude'], 'lng':wild['longitude'], 'cell':CellId.from_lat_lng(LatLng.from_degrees(wild['latitude'], wild['longitude'])).to_token()} pokes[phash] = pokeLog spawns[shash] = spawnLog if 'forts' in cell: for fort in cell['forts']: if fort['enabled'] == True: if 'type' in fort: #got a pokestop stopLog = {'id':fort['id'],'lat':fort['latitude'],'lng':fort['longitude'],'lure':-1} if 'lure_info' in fort: stopLog['lure'] = fort['lure_info']['lure_expires_timestamp_ms'] stops[fort['id']] = stopLog if 'gym_points' in fort: gymLog = {'id':fort['id'],'lat':fort['latitude'],'lng':fort['longitude'],'team':0} if 'owned_by_team' in fort: gymLog['team'] = fort['owned_by_team'] gyms[fort['id']] = gymLog time.sleep(config['scanDelay'])
def get_pokemon(self, api, lat, lng): api.set_position(lat, lng, 40) cells = pgoutil.get_cell_ids(lat, lng, 70) response = api.get_map_objects(since_timestamp_ms=[0] * len(cells), cell_id=cells) self.check(response) r = response["responses"]["GET_MAP_OBJECTS"] pokemon = list(itertools.chain.from_iterable(cell.get("catchable_pokemons", []) for cell in r["map_cells"])) now = r["map_cells"][0]["current_timestamp_ms"] return pokemon, now
def find_pokemon(self, job): tries = 0 max_tries = 3 wild_pokemon = [] while tries < max_tries: tries += 1 try: (lat, lng) = self.jittered_location(job) self.log_info("Looking for {} at {}, {} - try {}".format(job.pokemon_name, lat, lng, tries)) cell_ids = get_cell_ids(lat, lng) timestamps = [0, ] * len(cell_ids) response = self.perform_request( lambda req: req.get_map_objects(latitude=f2i(lat), longitude=f2i(lng), since_timestamp_ms=timestamps, cell_id=cell_ids)) wild_pokemon = self.parse_wild_pokemon(response) if len(wild_pokemon) > 0: break except Exception as e: self.log_error('Exception on GMO try {}: {}'.format(tries, repr(e))) if len(wild_pokemon) == 0: self.log_info("Still no wild Pokemon found. Giving up.") return False # find all pokemon with desired id candidates = filter( lambda pkm: pkm['pokemon_data']['pokemon_id'] == job.pokemon_id, wild_pokemon) target = None if len(candidates) == 1: # exactly one pokemon of this id found target = candidates[0] elif len(candidates) > 1: # multiple pokemon found, pick one with lowest distance to search position loc = (job.lat, job.lng) min_dist = False for pkm in candidates: d = geopy.distance.distance(loc, (pkm["latitude"], pkm["longitude"])).meters if not min_dist or d < min_dist: min_dist = d target = pkm # no pokemon found if target is None: self.log_info("No wild {} found at {}, {}.".format(job.pokemon_name, lat, lng)) return False # now set encounter id and spawn point id self.log_info("Got encounter_id for {} at {}, {}.".format(job.pokemon_name, target['latitude'], target['longitude'])) job.encounter_id = target['encounter_id'] job.spawn_point_id = target["spawn_point_id"] return True
def get_map_objects(api, account, location): cell_ids = get_cell_ids(location[0], location[1]) timestamps = [0, ]*len(cell_ids) req = api.create_request() req.get_map_objects( latitude=f2i(location[0]), longitude=f2i(location[1]), since_timestamp_ms=timestamps, cell_id=cell_ids) return send_generic_request(req, account)
def map_request(api, position): try: cell_ids = util.get_cell_ids(position[0], position[1]) timestamps = [0] * len(cell_ids) return api.get_map_objects( latitude=f2i(position[0]), longitude=f2i(position[1]), since_timestamp_ms=timestamps, cell_id=cell_ids ) except Exception as e: log.warning("Exception while downloading map: %s", e) return False
def main(): # log settings # log format logging.basicConfig( level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s') # log level for http request class logging.getLogger("requests").setLevel(logging.WARNING) # log level for main pgoapi class logging.getLogger("pgoapi").setLevel(logging.INFO) # log level for internal pgoapi class logging.getLogger("rpc_api").setLevel(logging.INFO) config = init_config() if not config: return if config.debug: logging.getLogger("requests").setLevel(logging.DEBUG) logging.getLogger("pgoapi").setLevel(logging.DEBUG) logging.getLogger("rpc_api").setLevel(logging.DEBUG) # instantiate pgoapi api = pgoapi.PGoApi() # parse position position = util.get_pos_by_name(config.location) if not position: log.error('Your given location could not be found by name') return elif config.test: return # set player position on the earth api.set_position(*position) # new authentication initialitation api.set_authentication(provider=config.auth_service, username=config.username, password=config.password) # provide the path for your encrypt dll api.activate_signature("encrypt.dll") # print get maps object cell_ids = util.get_cell_ids(position[0], position[1]) timestamps = [ 0, ] * len(cell_ids) response_dict = api.get_map_objects(latitude=position[0], longitude=position[1], since_timestamp_ms=timestamps, cell_id=cell_ids) print('Response dictionary (get_player): \n\r{}'.format( pprint.PrettyPrinter(indent=4).pformat(response_dict)))
def getMapSearch(self, center, radius): # idea: assign outlier value to each so you know how many points each one # is made of in the end in the "parents" entry lat1 = center[0] lon1 = center[1] # because we already have a wait in the update method #self.plt.pause(3) # just because it's slightly more useful than time.sleep try: cell_ids = util.get_cell_ids(self.latitude, self.longitude) timestamps = [ 0, ] * len(cell_ids) # for what purpose? theMap = self.player.get_map_objects(latitude=util.f2i(self.latitude), longitude=util.f2i( self.longitude), since_timestamp_ms=timestamps, cell_id=cell_ids) except: logging.warn("Unexpexted response from get_map_objects") self.relog() return False try: cells = theMap["responses"]["GET_MAP_OBJECTS"]["map_cells"] except: logging.warn("Unexpexted response from get_map_objects") return False for i in cells: if "forts" in i: for j in i["forts"]: lat2 = j["latitude"] lon2 = j["longitude"] if geography.isInRange(lat1, lon1, lat2, lon2, radius): if "gym_points" in j: if j["id"] not in self.foundGyms: self.foundGyms[j["id"]] = 1 self.gyms.append(j) self.plot(lat2, lon2, "gd") else: if j["id"] not in self.foundForts: self.foundForts[j["id"]] = 1 self.forts.append(j) self.plot(lat2, lon2, "rd") if "spawn_points" in i: for j in i["spawn_points"]: lat2 = j["latitude"] lon2 = j["longitude"] ID = str(lat2) + str(lon2) ID = base64.b64encode(bytes(ID, "UTF-8")) if geography.isInRange(lat1, lon1, lat2, lon2, radius): if ID not in self.foundSpawns: self.spawns.append(j) self.foundSpawns[ID] = 1 self.plot(lat2, lon2, "bd")
def send_map_request(api, position): try: api_copy = api.copy() api_copy.set_position(*position) api_copy.get_map_objects(latitude=f2i(position[0]), longitude=f2i(position[1]), since_timestamp_ms=TIMESTAMP, cell_id=util.get_cell_ids(position[0], position[1])) return api_copy.call() except Exception as e: log.warning("Uncaught exception when downloading map " + str(e)) return False
def nearby_map_objects(self): self._posf = self.api.get_position() cell_ids = util.get_cell_ids(lat=self._posf[0], long=self._posf[1], radius=700) timestamps = [ 0, ] * len(cell_ids) response = self.api.get_map_objects(latitude=self._posf[0], longitude=self._posf[1], since_timestamp_ms=timestamps, cell_id=cell_ids) return response
def map_request(api, position): try: cell_ids = util.get_cell_ids(position[0], position[1]) timestamps = [ 0, ] * len(cell_ids) return api.get_map_objects(latitude=f2i(position[0]), longitude=f2i(position[1]), since_timestamp_ms=timestamps, cell_id=cell_ids) except Exception as e: log.warning('Exception while downloading map: %s', e) return False
def main(): # log settings # log format logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s') # log level for http request class logging.getLogger("requests").setLevel(logging.WARNING) # log level for main pgoapi class logging.getLogger("pgoapi").setLevel(logging.INFO) # log level for internal pgoapi class logging.getLogger("rpc_api").setLevel(logging.INFO) config = init_config() if not config: return if config.debug: logging.getLogger("requests").setLevel(logging.DEBUG) logging.getLogger("pgoapi").setLevel(logging.DEBUG) logging.getLogger("rpc_api").setLevel(logging.DEBUG) # instantiate pgoapi api = pgoapi.PGoApi() if config.proxy: api.set_proxy({'http': config.proxy, 'https': config.proxy}) # parse position position = util.get_pos_by_name(config.location) if not position: log.error('Your given location could not be found by name') return elif config.test: return # set player position on the earth api.set_position(*position) # new authentication initialitation if config.proxy: api.set_authentication(provider = config.auth_service, username = config.username, password = config.password, proxy_config = {'http': config.proxy, 'https': config.proxy}) else: api.set_authentication(provider = config.auth_service, username = config.username, password = config.password) # provide the path for your encrypt dll api.activate_signature("/usr/lib/libencrypt.so") # print get maps object cell_ids = util.get_cell_ids(position[0], position[1]) timestamps = [0,] * len(cell_ids) response_dict = api.get_map_objects(latitude =position[0], longitude = position[1], since_timestamp_ms = timestamps, cell_id = cell_ids) print('Response dictionary (get_player): \n\r{}'.format(pprint.PrettyPrinter(indent=4).pformat(response_dict)))
def _get_cell_id_from_latlong(self, radius=1000): # type: (Optional[int]) -> List[str] position_lat, position_lng, _ = self.api_wrapper.get_position() cells = get_cell_ids(position_lat, position_lng, radius) if self.config['debug']: self._log('Cells:', color='yellow') self._log('Origin: {},{}'.format(position_lat, position_lng), color='yellow') for cell in cells: cell_id = CellId(cell) lat_lng = cell_id.to_lat_lng() self._log('Cell : {},{}'.format(lat_lng.lat().degrees, lat_lng.lng().degrees), color='yellow') return cells
def find_poi(api, lat, lng): poi = {'pokemons': {}, 'forts': []} step_size = 0.0015 step_limit = 1 coords = generate_spiral(lat, lng, step_size, step_limit) FOUND_POKEMON = [] for coord in coords: lat = coord['lat'] lng = coord['lng'] api.set_position(lat, lng, 0) #get_cellid was buggy -> replaced through get_cell_ids from pokecli #timestamp gets computed a different way: cell_ids = util.get_cell_ids(lat, lng) timestamps = [ 0, ] * len(cell_ids) response_dict = api.get_map_objects(latitude=util.f2i(lat), longitude=util.f2i(lng), since_timestamp_ms=timestamps, cell_id=cell_ids) if (response_dict['responses']): if 'status' in response_dict['responses']['GET_MAP_OBJECTS']: if response_dict['responses']['GET_MAP_OBJECTS'][ 'status'] == 1: for map_cell in response_dict['responses'][ 'GET_MAP_OBJECTS']['map_cells']: if 'wild_pokemons' in map_cell: for pokemon in map_cell['wild_pokemons']: FOUND_POKEMON.append( pokemon['pokemon_data']['pokemon_id']) # pokekey = get_key_from_pokemon(pokemon) # pokemon['hides_at'] = time.time() + pokemon['time_till_hidden_ms']/1000 # poi['pokemons'][pokekey] = pokemon time.sleep(0.51) for x in FOUND_POKEMON: print("#{} NEARBY, {}!".format(x, POKE_NAMES[x - 1])) if (x in COMMON_POKE): enable_led(17, True) if (x in UNCOMMON_POKE or x in RARE_POKE or x in VERY_RARE_POKE or x in EPIC_POKE or x in LEGENDARY_POKE): print("RARE POKEMON FOUND!") enable_led(27, True) enable_led(22, True)
def main(self): """Heart of the worker - goes over each point and reports sightings""" session = db.Session() self.seen_per_cycle = 0 self.step = 0 for i, point in enumerate(self.points): if not self.running: return logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) self.api.set_position(point[0], point[1], 100) response_dict = self.api.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids ) if response_dict is False: raise CannotProcessStep now = time.time() map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] if map_objects.get('status') == 1: for map_cell in map_objects['map_cells']: for pokemon in map_cell.get('wild_pokemons', []): # Care only about 15 min spawns # 30 and 45 min ones will be just put after # time_till_hidden is below 15 min if pokemon['time_till_hidden_ms'] < 0: continue pokemons.append(self.normalize_pokemon(pokemon, now)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 logger.info('Point processed, %d Pokemons seen!', len(pokemons)) session.commit() # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 time.sleep( random.uniform(config.SCAN_DELAY, config.SCAN_DELAY + 2) ) session.close() if self.seen_per_cycle == 0: self.error_code = 'NO POKEMON'
def scan_location(self): try: self.api.set_position(self.latitude, self.longitude, random.randint(12, 108)) cell_ids = get_cell_ids(self.latitude, self.longitude) timestamps = [ 0, ] * len(cell_ids) req = self.api.create_request() req.get_map_objects(latitude=f2i(self.latitude), longitude=f2i(self.longitude), since_timestamp_ms=timestamps, cell_id=cell_ids) response = self.perform_request(req) self.wild_pokemon = self.count_pokemon(response) except Exception as e: pass
def find_close_cells(self, lat, lng): cellid = get_cell_ids(lat, lng) timestamp = [ 0, ] * len(cellid) response_dict = self.get_map_objects(lat, lng, timestamp, cellid) map_objects = response_dict.get('responses', {}).get('GET_MAP_OBJECTS', {}) status = map_objects.get('status', None) map_cells = [] if status and status == 1: map_cells = map_objects['map_cells'] position = (lat, lng, 0) map_cells.sort( key=lambda x: distance(lat, lng, x['forts'][0]['latitude'], x[ 'forts'][0]['longitude']) if x.get('forts', []) else 1e6) return map_cells
def main(self): """Heart of the worker - goes over each point and reports sightings""" session = db.Session() self.seen_per_cycle = 0 self.step = 0 for i, point in enumerate(self.points): if not self.running: return logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) self.api.set_position(point[0], point[1], 100) response_dict = self.api.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids) if response_dict is False: raise CannotProcessStep now = time.time() map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] if map_objects.get('status') == 1: for map_cell in map_objects['map_cells']: for pokemon in map_cell.get('wild_pokemons', []): # Care only about 15 min spawns # 30 and 45 min ones will be just put after # time_till_hidden is below 15 min if pokemon['time_till_hidden_ms'] < 0: continue pokemons.append(self.normalize_pokemon(pokemon, now)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 logger.info('Point processed, %d Pokemons seen!', len(pokemons)) session.commit() # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 time.sleep(random.uniform(5, 7)) session.close() if self.seen_per_cycle == 0: self.error_code = 'NO POKEMON'
def find_pokemon(self, snipe_info, first_retry): self.emit_event( 'snipe_find_pokemon', formatted='Try to find {poke_name} {lat}, {lon} in 10 seconds', data={ 'poke_name': snipe_info.pokemon_name, 'lat': snipe_info.latitude, 'lon': snipe_info.longitude }) time.sleep(GET_MAP_OBJECT_SLEEP_SEC) cellid = get_cell_ids(snipe_info.latitude, snipe_info.longitude) timestamp = [ 0, ] * len(cellid) response_dict = self.bot.get_map_objects(snipe_info.latitude, snipe_info.longitude, timestamp, cellid) map_objects = response_dict.get('responses', {}).get('GET_MAP_OBJECTS', {}) cells = map_objects['map_cells'] for cell in cells: pokemons = [] if "wild_pokemons" in cell and len(cell["wild_pokemons"]): pokemons += cell["wild_pokemons"] if "catchable_pokemons" in cell and len( cell["catchable_pokemons"]): pokemons += cell["catchable_pokemons"] for pokemon in pokemons: pokemon = self.get_pokemon(pokemon) if pokemon['name'] == snipe_info.pokemon_name: return pokemon self.emit_event('snipe_not_found', formatted='{poke_name} ({lat} {lon}) is not found', data={ 'poke_name': snipe_info.pokemon_name, 'lat': snipe_info.latitude, 'lon': snipe_info.longitude }) if first_retry == True: return self.find_pokemon(snipe_info, False) return None
def map_request(api, position, jitter=False): # create scan_location to send to the api based off of position, because tuples aren't mutable if jitter: # jitter it, just a little bit. scan_location = jitterLocation(position) log.debug('Jittered to: %f/%f/%f', scan_location[0], scan_location[1], scan_location[2]) else: # Just use the original coordinates scan_location = position try: cell_ids = util.get_cell_ids(scan_location[0], scan_location[1]) timestamps = [0, ] * len(cell_ids) return api.get_map_objects(latitude=f2i(scan_location[0]), longitude=f2i(scan_location[1]), since_timestamp_ms=timestamps, cell_id=cell_ids) except Exception as e: log.warning('Exception while downloading map: %s', e) return False
def get_map_objects(api, account, position, no_jitter=False): # Create scan_location to send to the api based off of position # because tuples aren't mutable. if no_jitter: # Just use the original coordinates. scan_location = position else: # Jitter it, just a little bit. scan_location = jitter_location(position) log.debug('Jittered to: %f/%f/%f', scan_location[0], scan_location[1], scan_location[2]) cell_ids = get_cell_ids(scan_location[0], scan_location[1]) timestamps = [0, ]*len(cell_ids) req = api.create_request() req.get_map_objects( latitude=f2i(scan_location[0]), longitude=f2i(scan_location[1]), since_timestamp_ms=timestamps, cell_id=cell_ids) return send_generic_request(req, account)
def catchNearby(self, point): if self.Grinding: d = geography.getDistance(self.lastpt[0], self.lastpt[1], point[0], point[1]) if d >= .14: self.lastpt = [self.latitude, self.longitude] self.plt.pause(1.5) else: return False else: return False try: cell_ids = util.get_cell_ids(self.latitude, self.longitude) timestamps = [ 0, ] * len(cell_ids) # for what purpose? theMap = self.player.get_map_objects(latitude=util.f2i(self.latitude), longitude=util.f2i( self.longitude), since_timestamp_ms=timestamps, cell_id=cell_ids) except: logging.warn("Unexpexted response from get_map_objects") self.relog() return False try: cells = theMap["responses"]["GET_MAP_OBJECTS"]["map_cells"] except: logging.warn("Unexpexted response from get_map_objects") return False for i in cells: if "catchable_pokemons" in i: print("found some pokemon :") for j in i["catchable_pokemons"]: print(self.data.PokemonNames[j["pokemon_id"]]) response = catch(self, j["spawn_point_id"], j["encounter_id"]) if response == False: break
def gym_scanner_thread(options): id = options.get('id', '') lat = options.get('lat', 0) lng = options.get('lng', 0) sleep(random.randint(0, config.SCAN_BUFFER)) api = pgoapi.PGoApi() api.activate_hash_server(config.HASH_KEY) api.set_position(lat, lng, 0) api.set_authentication(provider='ptc', username=options['username'], password=options['password'], timeout=15) print('{} logged in.'.format(options['username'])) req = api.create_request() req.get_map_objects(lat=f2i(lat), lng=f2i(lng), since_timestamp_ms=[ 0, ] * len(get_cell_ids(lat, lng)), cell_id=get_cell_ids(lat, lng)) req.check_challenge() req.get_hatched_eggs() req.get_inventory() req.check_awarded_badges() req.get_buddy_walked() req.get_inbox(is_history=True) res = req.call() gmo = res['responses']['GET_MAP_OBJECTS'] print('Scanning gym {}...'.format(id)) # TODO: this is a really bad way to do this for cell in gmo.get('map_cells'): for fort in cell.get('forts'): if fort.get('id') == id: if fort.get('raid_info' ) is not None or fort.get('raid_info') != {}: raid = fort.get('raid_info') print('Found a L{} raid at {}.'.format( raid.get('raid_info'), id)) if raid.get('raid_pokemon') is not None or raid.get( 'raid_pokemon') != {}: pokemon = raid.get('raid_pokemon') webhook.send_to_webhook(fort) Raid.insert(level=raid.get('raid_level'), pokemon_id=pokemon.get('pokemon_id'), latitude=fort.get('latitude'), longitude=fort.get('longitude'), fort_id=fort.get('id'), seed=raid.get('raid_seed'), spawn_time=raid.get('raid_spawn_ms'), battle_time=raid.get('raid_battle_ms'), end_time=raid.get('raid_end_ms'), cp=pokemon.get('cp'), move_1=pokemon.get('move_1'), move_2=pokemon.get('move_2'), controlled_by=fort.get('owned_by_team')) else: Raid.insert(level=raid.get('raid_level'), pokemon_id=None, latitude=fort.get('latitude'), longitude=fort.get('longitude'), fort_id=fort.get('id'), seed=raid.get('raid_seed'), spawn_time=raid.get('raid_spawn_ms'), battle_time=raid.get('raid_battle_ms'), end_time=raid.get('raid_end_ms'), cp=None, move_1=None, move_2=None, controlled_by=fort.get('owned_by_team')) sleep(config.SCAN_BUFFER * 60)
def main(): # log settings # log format logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s') # log level for http request class logging.getLogger("requests").setLevel(logging.WARNING) # log level for main pgoapi class logging.getLogger("pgoapi").setLevel(logging.INFO) # log level for internal pgoapi class logging.getLogger("rpc_api").setLevel(logging.INFO) config = init_config() if not config: return if config.debug: logging.getLogger("requests").setLevel(logging.DEBUG) logging.getLogger("pgoapi").setLevel(logging.DEBUG) logging.getLogger("rpc_api").setLevel(logging.DEBUG) data_path = os.path.join(os.path.dirname(__file__), "data") gyms_path = os.path.join(data_path, "gyms") if not os.path.exists(data_path): os.makedirs(data_path) if not os.path.exists(gyms_path): os.makedirs(gyms_path) # instantiate pgoapi api = pgoapi.PGoApi() # parse position position = util.get_pos_by_name(config.location) if not position: log.error('Your given location could not be found by name') return elif config.test: return # set player position on the earth api.set_position(*position) #if not api.login(config.auth_service, config.username, config.password, app_simulation = True): # return # new authentication initialitation api.set_authentication(provider = config.auth_service, username = config.username, password = config.password) # provide the path for your encrypt dll encryptPath = get_encryption_lib_path() api.activate_signature(encryptPath) # get player profile call (single command example) # ---------------------- #response_dict = api.get_player() #print('Response dictionary (get_player): \n\r{}'.format(pprint.PrettyPrinter(indent=4).pformat(response_dict))) # sleep 200ms due to server-side throttling #time.sleep(0.2) # get player profile + inventory call (thread-safe/chaining example) # ---------------------- #req = api.create_request() #req.get_player() #req.get_inventory() #response_dict = req.call() #print('Response dictionary (get_player + get_inventory): \n\r{}'.format(pprint.PrettyPrinter(indent=4).pformat(response_dict))) # sleep 200ms due to server-side throttling #time.sleep(0.2) #print('cellids:\n\r{}'.format(util.get_cell_ids(position[0],position[1]))) #get gym info lat= position[0] lng= position[1] cell_ids = util.get_cell_ids(lat, lng) timestamps = [0,] * len(cell_ids) response_dict = api.get_map_objects(latitude = util.f2i(lat), longitude = util.f2i(lng), since_timestamp_ms = timestamps, cell_id = cell_ids) response_json = os.path.join(data_path, "response_dict.json") with open(response_json, 'w') as outfile: outfile.truncate() json.dump(response_dict, outfile) map_objects = response_dict.get('responses', {}).get('GET_MAP_OBJECTS', {}) status = map_objects.get('status', None) cells = map_objects['map_cells'] time.sleep(2); #insert detail info about gym to fort for cell in cells: if 'forts' in cell: for fort in cell['forts']: print ('id {} type {} points {}'.format(fort.get('id'),fort.get('type'),fort.get('gym_points'))) #if fort.get('type') != 1: if 'gym_points' in fort: req = api.create_request() req.get_gym_details(gym_id=fort.get('id'), player_latitude=lng, player_longitude=lat, gym_latitude=fort.get('latitude'), gym_longitude=fort.get('longitude')) response_gym_details = req.call() fort['gym_details'] = response_gym_details.get('responses', {}).get('GET_GYM_DETAILS', None) if ('name' in fort['gym_details']): gym_data_cells = os.path.join(gyms_path, "gym_{}.json".format(fort['id'])) with open(gym_data_cells, 'w') as outfile: json.dump(fort['gym_details'], outfile) else: print('***NO GYM DETAILS - HANDLE WHY?'); print('{}'.format(pprint.PrettyPrinter(indent=1).pformat(fort['gym_details']))); print('{}'.format(pprint.PrettyPrinter(indent=1).pformat(fort))); print('***NO GYM DETAILS - HANDLE WHY?'); time.sleep(2); user_data_cells = os.path.join(data_path, "cells.json") with open(user_data_cells, 'w') as outfile: outfile.truncate() json.dump(cells, outfile)
def performMapOperations(self, i, point, session): self.error_code = None try: if not self.running: return if self.minorFailCount > 6: raise FunkyAccount if self.cycle == 1 and self.step == 0: time.sleep(1) else: secondsBetween = random.uniform(config.MIN_SCAN_DELAY, config.MIN_SCAN_DELAY + 2) time.sleep(secondsBetween) if (len(self.points) > 1): point1 = self.points[i] if (self.step == 0): point2 = self.points[len(self.points) - 1] else: point2 = self.points[i - 1] speed = utils.get_speed_kmh(point1, point2, secondsBetween) while (speed > config.MAX_SPEED_KMH): moreSleep = random.uniform(.5, 2.5) time.sleep(moreSleep) secondsBetween += moreSleep speed = utils.get_speed_kmh(point1, point2, secondsBetween) logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) #logger.info('Visiting point %d (%s %s) step 2', i, point[0], point[1]) #self.api.set_position(point[0], point[1], 10) #logger.info('Visited point %d (%s %s) step 3', i, point[0], point[1]) req = self.api.create_request() response_dict = req.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids) response_dict = req.check_challenge() response_dict = req.get_hatched_eggs() response_dict = req.get_inventory() response_dict = req.check_awarded_badges() response_dict = req.download_settings() response_dict = req.get_buddy_walked() response_dict = req.call() self.checkResponseStatus(response_dict) map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] gyms = [] pokestops = [] if map_objects.get('status') == 1: #logger.info("Status was 1") #logger.info("number of map objects returned: %d",len(map_objects)) # logger.info(map_objects) for map_cell in map_objects['map_cells']: #logger.info(map_cell) for pokemon in map_cell.get('wild_pokemons', []): #logger.info(pokemon) # Care only about 15 min spawns # 30 and 45 min ones (negative) will be just put after # time_till_hidden is below 15 min # As of 2016.08.14 we don't know what values over # 60 minutes are, so ignore them too invalid_time = False #( #pokemon['time_till_hidden_ms'] < 0 or # pokemon['time_till_hidden_ms'] > 900000 # ) pokemon['time_logged'] = time.time() #logger.info("found pokemon. time remaining: %d, %d", pokemon['time_till_hidden_ms'], pokemon['time_logged']) if invalid_time: logger.error("pokemon had invalid time") continue if config.ENCOUNTER == 1: self.encounter(pokemon, point, 0) else: pokemon['ATK_IV'] = -2 pokemon['DEF_IV'] = -2 pokemon['STA_IV'] = -2 pokemon['move_1'] = -2 pokemon['move_2'] = -2 #logger.info("appending pokemon") pokemons.append( self.normalize_pokemon( pokemon, map_cell['current_timestamp_ms'])) for fort in map_cell.get('forts', []): # logger.info(fort) if not fort.get('enabled'): continue if fort.get('type') == 1: # probably pokestops pokestops.append( self.normalize_pokestop( fort, map_cell['current_timestamp_ms'])) else: gyms.append(self.normalize_gym(fort)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 session.commit() for raw_gym in gyms: db.add_gym_sighting(session, raw_gym) for raw_pokestop in pokestops: db.add_pokestop_sighting(session, raw_pokestop) try: session.commit() except IntegrityError: # skip adding fort this time session.rollback() # Commit is not necessary here, it's done by add_gym_sighting logger.info( 'Point processed, %d Pokemons, %d gyms, and %d pokestops seen!', len(pokemons), len(gyms), len(pokestops)) # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 except MalformedResponse: logger.warning('Malformed response received!') self.error_code = 'MALFORMED' #self.restart() #return self.minorFailCount = self.minorFailCount + 1 self.performMapOperations(i, point, session) except CaptchaAccount: progressMsg = '{progress:.0f}%'.format( progress=(self.step / float(self.count_points) * 100)) logger.warning(self.username + " appears to be captcha at " + progressMsg) self.error_code = 'CAPTCHA-' + progressMsg username, password, service = utils.swapCaptchaWorker( self.worker_no, self.subNumber, self.numActiveAtOnce) if (username == None and password == None and service == None): # shoot, we are out of accounts. raise CaptchaAccount else: self.error_code = self.error_code + "-R" logger.info("Found new account, restarting") self.minorFailCount = self.minorFailCount + 1 # remove this if I make it resume in the middle of the path #self.restart(30, 90) for x in range(0, 6): success = self.login(self.subNumber, self.numActiveAtOnce) if success: break else: logger.warning("Failed logging into " + self.username) time.sleep(3) if not success: raise FunkyAccount logger.info("Logged into: " + self.username) self.performMapOperations(i, point, session)
def main(): # log settings # log format logging.basicConfig( level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s') # log level for http request class logging.getLogger("requests").setLevel(logging.WARNING) # log level for main pgoapi class logging.getLogger("pgoapi").setLevel(logging.INFO) # log level for internal pgoapi class logging.getLogger("rpc_api").setLevel(logging.INFO) config = init_config() if not config: return if config.debug: logging.getLogger("requests").setLevel(logging.DEBUG) logging.getLogger("pgoapi").setLevel(logging.DEBUG) logging.getLogger("rpc_api").setLevel(logging.DEBUG) device_info = { 'device_id': uuid.uuid4().hex, 'device_brand': 'Apple', 'device_model': 'iPhone', 'device_comms_model': 'iPhone8,2', 'hardware_manufacturer': 'Apple', 'hardware_model': 'N66AP', 'firmware_brand': 'iPhone OS', 'firmware_type': '9.3.3' } # instantiate pgoapi api = pgoapi.PGoApi(device_info=device_info) if config.proxy: api.set_proxy({'http': config.proxy, 'https': config.proxy}) # parse position TODO position = util.get_pos_by_name(config.location) if not position: log.error('Your given location could not be found by name') return elif config.test: return #set player position on the earth api.set_position(*position) # new authentication initialitation if config.proxy: api.set_authentication(provider=config.auth_service, username=config.username, password=config.password, proxy_config={ 'http': config.proxy, 'https': config.proxy }) else: api.set_authentication(provider=config.auth_service, username=config.username, password=config.password) # provide the path for your encrypt dll api.activate_signature( os.path.join(os.path.dirname(os.path.realpath(__file__)), "libencrypt.so")) api.app_simulation_login() time.sleep(10) cell_ids = util.get_cell_ids(position[0], position[1]) timestamps = [ 0, ] * len(cell_ids) request = api.create_request() request.get_map_objects(latitude=position[0], longitude=position[1], since_timestamp_ms=timestamps, cell_id=cell_ids) request.check_challenge() #request.get_hatched_eggs() #request.get_inventory() #request.check_awarded_badges() #request.download_settings(hash="8631c515a4c084ef30ef4d6eee8f5f5b250db697")#old54b359c97e46900f87211ef6e6dd0b7f2a3ea1f5 #request.get_buddy_walked() response_dict = request.call() #print('Response dictionary (map_objects): \n\r{}'.format(pprint.PrettyPrinter(indent=4).pformat(response_dict))) if 'status' not in response_dict['responses']['GET_MAP_OBJECTS']: raise ValueError("Invalid response: {}".format( json.dumps(response_dict, indent=2))) if response_dict['responses']['GET_MAP_OBJECTS']['status'] == 1: for cell in response_dict['responses']['GET_MAP_OBJECTS']['map_cells']: if 'nearby_pokemons' in cell: print "nearby_pokemons in cell: " + cell['s2_cell_id'] print cell['nearby_pokemons'] if 'wild_pokemons' in cell: pprint.PrettyPrinter(indent=2).pformat(cell['wild_pokemons']) print response_dict['responses']['CHECK_CHALLENGE'] """
def main(self): """Heart of the worker - goes over each point and reports sightings""" session = db.Session() self.seen_per_cycle = 0 self.step = 0 for i, point in enumerate(self.points): if not self.running: return logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) self.api.set_position(point[0], point[1], 100) response_dict = self.api.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids) if not isinstance(response_dict, dict): logger.warning('Response: %s', response_dict) raise MalformedResponse if response_dict['status_code'] == 3: logger.warning('Account banned') raise BannedAccount responses = response_dict.get('responses') if not responses: logger.warning('Response: %s', response_dict) raise MalformedResponse map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] forts = [] if map_objects.get('status') == 1: for map_cell in map_objects['map_cells']: for pokemon in map_cell.get('wild_pokemons', []): # Care only about 15 min spawns # 30 and 45 min ones (negative) will be just put after # time_till_hidden is below 15 min # As of 2016.08.14 we don't know what values over # 60 minutes are, so ignore them too invalid_time = ( pokemon['time_till_hidden_ms'] < 0 or pokemon['time_till_hidden_ms'] > 900000) if invalid_time: continue pokemons.append( self.normalize_pokemon( pokemon, map_cell['current_timestamp_ms'])) for fort in map_cell.get('forts', []): if not fort.get('enabled'): continue if fort.get('type') == 1: # probably pokestops continue forts.append(self.normalize_fort(fort)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 session.commit() for raw_fort in forts: db.add_fort_sighting(session, raw_fort) # Commit is not necessary here, it's done by add_fort_sighting logger.info( 'Point processed, %d Pokemons and %d forts seen!', len(pokemons), len(forts), ) # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 time.sleep(random.uniform(config.SCAN_DELAY, config.SCAN_DELAY + 2)) session.close() if self.seen_per_cycle == 0: self.error_code = 'NO POKEMON'
def main(self): """Heart of the worker - goes over each point and reports sightings""" session = db.Session() self.seen_per_cycle = 0 self.step = 0 for i, point in enumerate(self.points): if not self.running: return logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) self.api.set_position(point[0], point[1], 100) response_dict = self.api.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids ) if response_dict is False: raise CannotProcessStep map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] forts = [] if map_objects.get('status') == 1: for map_cell in map_objects['map_cells']: for pokemon in map_cell.get('wild_pokemons', []): # Care only about 15 min spawns # 30 and 45 min ones will be just put after # time_till_hidden is below 15 min if pokemon['time_till_hidden_ms'] < 0: continue pokemons.append( self.normalize_pokemon( pokemon, map_cell['current_timestamp_ms'] ) ) # Prepare and send the pokemon data to the webhook listeners d_t = datetime.utcfromtimestamp( (pokemon['last_modified_timestamp_ms'] + pokemon['time_till_hidden_ms']) / 1000.0) webhook_data = { 'encounter_id': b64encode(str(pokemon['encounter_id'])), 'spawnpoint_id': pokemon['spawn_point_id'], 'pokemon_id': pokemon['pokemon_data']['pokemon_id'], 'latitude': pokemon['latitude'], 'longitude': pokemon['longitude'], 'disappear_time': calendar.timegm(d_t.timetuple()), 'last_modified_time': pokemon['last_modified_timestamp_ms'], 'time_until_hidden_ms': pokemon['time_till_hidden_ms'] } self.send_to_webhook('pokemon', webhook_data) for fort in map_cell.get('forts', []): if not fort.get('enabled'): continue if fort.get('type') == 1: # probably pokestops continue forts.append(self.normalize_fort(fort)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 session.commit() for raw_fort in forts: db.add_fort_sighting(session, raw_fort) # Commit is not necessary here, it's done by add_fort_sighting logger.info( 'Point processed, %d Pokemons and %d forts seen!', len(pokemons), len(forts), ) # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 time.sleep( random.uniform(config.SCAN_DELAY, config.SCAN_DELAY + 2) ) session.close() if self.seen_per_cycle == 0: self.error_code = 'NO POKEMON'
def get_cell_ids_for_points(points): cell_ids = [] for point in points: cell_ids.append(pgoapi_utils.get_cell_ids(point[0], point[1])) return cell_ids
def main(self): """Heart of the worker - goes over each point and reports sightings""" session = db.Session() self.seen_per_cycle = 0 self.step = 0 for i, point in enumerate(self.points): if not self.running: return logger.info('Visiting point %d (%s %s)', i, point[0], point[1]) self.api.set_position(point[0], point[1], 0) cell_ids = pgoapi_utils.get_cell_ids(point[0], point[1]) self.api.set_position(point[0], point[1], 100) response_dict = self.api.get_map_objects( latitude=pgoapi_utils.f2i(point[0]), longitude=pgoapi_utils.f2i(point[1]), cell_id=cell_ids ) if not isinstance(response_dict, dict): logger.warning('Response: %s', response_dict) raise MalformedResponse responses = response_dict.get('responses') if not responses: logger.warning('Response: %s', response_dict) raise MalformedResponse map_objects = response_dict['responses'].get('GET_MAP_OBJECTS', {}) pokemons = [] forts = [] if map_objects.get('status') == 1: for map_cell in map_objects['map_cells']: for pokemon in map_cell.get('wild_pokemons', []): # Care only about 15 min spawns # 30 and 45 min ones (negative) will be just put after # time_till_hidden is below 15 min # As of 2016.08.14 we don't know what values over # 60 minutes are, so ignore them too invalid_time = ( pokemon['time_till_hidden_ms'] < 0 or pokemon['time_till_hidden_ms'] > 900000 ) if invalid_time: continue pokemons.append( self.normalize_pokemon( pokemon, map_cell['current_timestamp_ms'] ) ) for fort in map_cell.get('forts', []): if not fort.get('enabled'): continue if fort.get('type') == 1: # probably pokestops continue forts.append(self.normalize_fort(fort)) for raw_pokemon in pokemons: db.add_sighting(session, raw_pokemon) self.seen_per_cycle += 1 self.total_seen += 1 session.commit() for raw_fort in forts: db.add_fort_sighting(session, raw_fort) # Commit is not necessary here, it's done by add_fort_sighting logger.info( 'Point processed, %d Pokemons and %d forts seen!', len(pokemons), len(forts), ) # Clear error code and let know that there are Pokemon if self.error_code and self.seen_per_cycle: self.error_code = None self.step += 1 time.sleep( random.uniform(config.SCAN_DELAY, config.SCAN_DELAY + 2) ) session.close() if self.seen_per_cycle == 0: self.error_code = 'NO POKEMON'
def update_web_location(self, cells=[], lat=None, lng=None, alt=None): # we can call the function with no arguments and still get the position # and map_cells if lat is None: lat = self.api._position_lat if lng is None: lng = self.api._position_lng if alt is None: alt = 0 if cells == []: cellid = get_cell_ids(lat, lng) timestamp = [0, ] * len(cellid) response_dict = self.get_map_objects(lat, lng, timestamp, cellid) map_objects = response_dict.get( 'responses', {} ).get('GET_MAP_OBJECTS', {}) status = map_objects.get('status', None) cells = map_objects['map_cells'] # insert detail info about gym to fort for cell in cells: if 'forts' in cell: for fort in cell['forts']: if fort.get('type') != 1: self.api.get_gym_details( gym_id=fort.get('id'), player_latitude=lng, player_longitude=lat, gym_latitude=fort.get('latitude'), gym_longitude=fort.get('longitude') ) response_gym_details = self.api.call() fort['gym_details'] = response_gym_details.get( 'responses', {} ).get('GET_GYM_DETAILS', None) user_data_cells = "data/cells-%s.json" % self.config.username with open(user_data_cells, 'w') as outfile: json.dump(cells, outfile) user_web_location = os.path.join( 'web', 'location-%s.json' % self.config.username ) # alt is unused atm but makes using *location easier try: with open(user_web_location, 'w') as outfile: json.dump({ 'lat': lat, 'lng': lng, 'alt': alt, 'cells': cells }, outfile) except IOError as e: logger.log('[x] Error while opening location file: %s' % e, 'red') user_data_lastlocation = os.path.join( 'data', 'last-location-%s.json' % self.config.username ) try: with open(user_data_lastlocation, 'w') as outfile: json.dump({'lat': lat, 'lng': lng, 'start_position': self.start_position}, outfile) except IOError as e: logger.log('[x] Error while opening location file: %s' % e, 'red')
def doScan(wid, sLat, sLng, api): #print ('scanning ({}, {})'.format(sLat, sLng)) api.set_position(sLat, sLng, 0) cell_ids = util.get_cell_ids(lat=sLat, long=sLng, radius=80) timestamps = [ 0, ] * len(cell_ids) while True: try: response_dict = api.get_map_objects(latitude=sLat, longitude=sLng, since_timestamp_ms=timestamps, cell_id=cell_ids) except ServerSideRequestThrottlingException: config['scanDelay'] += 0.5 print('Request throttled, increasing sleep by 0.5 to {}').format( config['scanDelay']) time.sleep(config['scanDelay']) continue except: time.sleep(config['scanDelay']) api.set_position(sLat, sLng, 0) time.sleep(config['scanDelay']) continue break try: cells = response_dict['responses']['GET_MAP_OBJECTS']['map_cells'] except TypeError: print('thread {} error getting map data for {}, {}'.format( wid, sLat, sLng)) raise except KeyError: print('thread {} error getting map data for {}, {}'.format( wid, sLat, sLng)) raise return for cell in cells: curTime = cell['current_timestamp_ms'] if 'wild_pokemons' in cell: for wild in cell['wild_pokemons']: if wild['time_till_hidden_ms'] > 0: timeSpawn = (curTime + (wild['time_till_hidden_ms'])) - 900000 gmSpawn = time.gmtime(int(timeSpawn / 1000)) secSpawn = (gmSpawn.tm_min * 60) + (gmSpawn.tm_sec) phash = '{},{}'.format(timeSpawn, wild['spawn_point_id']) shash = '{},{}'.format(secSpawn, wild['spawn_point_id']) pokeLog = { 'time': timeSpawn, 'sid': wild['spawn_point_id'], 'lat': wild['latitude'], 'lng': wild['longitude'], 'pid': wild['pokemon_data']['pokemon_id'], 'cell': CellId.from_lat_lng( LatLng.from_degrees(wild['latitude'], wild['longitude'])).to_token() } spawnLog = { 'time': secSpawn, 'sid': wild['spawn_point_id'], 'lat': wild['latitude'], 'lng': wild['longitude'], 'cell': CellId.from_lat_lng( LatLng.from_degrees(wild['latitude'], wild['longitude'])).to_token() } pokes[phash] = pokeLog spawns[shash] = spawnLog if 'forts' in cell: for fort in cell['forts']: if fort['enabled'] == True: if 'type' in fort: #got a pokestop stopLog = { 'id': fort['id'], 'lat': fort['latitude'], 'lng': fort['longitude'], 'lure': -1 } if 'lure_info' in fort: stopLog['lure'] = fort['lure_info'][ 'lure_expires_timestamp_ms'] stops[fort['id']] = stopLog if 'gym_points' in fort: gymLog = { 'id': fort['id'], 'lat': fort['latitude'], 'lng': fort['longitude'], 'team': 0 } if 'owned_by_team' in fort: gymLog['team'] = fort['owned_by_team'] gyms[fort['id']] = gymLog time.sleep(config['scanDelay'])
async def visit_point(self, point, bootstrap=False): if bootstrap: self.error_code = '∞' else: self.error_code = '!' latitude, longitude = point self.logger.info('Visiting {0[0]:.4f},{0[1]:.4f}'.format(point)) start = time() rounded = round_coords(point, precision=4) if config.CACHE_CELLS and rounded in self.cell_ids: cell_ids = list(self.cell_ids[rounded]) else: cell_ids = get_cell_ids(*rounded, radius=500) if config.CACHE_CELLS: try: self.cell_ids[rounded] = array('L', cell_ids) except OverflowError: self.cell_ids[rounded] = tuple(cell_ids) since_timestamp_ms = [0] * len(cell_ids) request = self.api.create_request() request.get_map_objects(cell_id=cell_ids, since_timestamp_ms=since_timestamp_ms, latitude=latitude, longitude=longitude) diff = self.last_gmo + config.SCAN_DELAY - time() if diff > 0: await sleep(diff + .25) responses = await self.call(request) self.last_gmo = time() map_objects = responses.get('GET_MAP_OBJECTS', {}) sent = False pokemon_seen = 0 forts_seen = 0 points_seen = 0 if map_objects.get('status') == 3: raise ex.BannedAccountException('GMO code 3') elif map_objects.get('status') != 1: self.logger.warning('MapObjects code: {}'.format( map_objects.get('status'))) self.empty_visits += 1 if self.empty_visits > 3: reason = '{} empty visits'.format(self.empty_visits) await self.swap_account(reason) raise ex.UnexpectedResponseException time_of_day = map_objects.get('time_of_day', 0) if config.ITEM_LIMITS and self.bag_full(): await self.clean_bag() for map_cell in map_objects['map_cells']: request_time_ms = map_cell['current_timestamp_ms'] for pokemon in map_cell.get('wild_pokemons', []): pokemon_seen += 1 # Accurate times only provided in the last 90 seconds invalid_tth = (pokemon['time_till_hidden_ms'] < 0 or pokemon['time_till_hidden_ms'] > 90000) normalized = self.normalize_pokemon(pokemon, request_time_ms) if invalid_tth: despawn_time = self.spawns.get_despawn_time( normalized['spawn_id'], normalized['seen']) if despawn_time: normalized['expire_timestamp'] = despawn_time normalized['time_till_hidden_ms'] = ( despawn_time * 1000) - request_time_ms normalized['valid'] = 'fixed' else: normalized['valid'] = False else: normalized['valid'] = True if config.NOTIFY and self.notifier.eligible(normalized): if config.ENCOUNTER: normalized.update(await self.encounter(pokemon)) sent = self.notify(normalized, time_of_day) if (normalized not in SIGHTING_CACHE and normalized not in MYSTERY_CACHE): self.account_seen += 1 if (config.ENCOUNTER == 'all' and 'individual_attack' not in normalized): try: normalized.update(await self.encounter(pokemon)) except Exception: self.logger.exception( 'Exception during encounter.') self.db_processor.add(normalized) for fort in map_cell.get('forts', []): if not fort.get('enabled'): continue forts_seen += 1 if fort.get('type') == 1: # pokestops if 'lure_info' in fort: norm = self.normalize_lured(fort, request_time_ms) pokemon_seen += 1 if norm not in SIGHTING_CACHE: self.account_seen += 1 self.db_processor.add(norm) pokestop = self.normalize_pokestop(fort) self.db_processor.add(pokestop) if self.pokestops and not self.bag_full( ) and time() > self.next_spin: cooldown = fort.get('cooldown_complete_timestamp_ms') if not cooldown or time() > cooldown / 1000: await self.spin_pokestop(pokestop) else: self.db_processor.add(self.normalize_gym(fort)) if config.MORE_POINTS or bootstrap: for point in map_cell.get('spawn_points', []): points_seen += 1 try: p = (point['latitude'], point['longitude']) if p in self.spawns.known_points or not Bounds.contain( p): continue self.spawns.add_mystery(p) except (KeyError, TypeError): self.logger.warning( 'Spawn point exception ignored. {}'.format(point)) pass if config.INCUBATE_EGGS and len(self.unused_incubators) > 0 and len( self.eggs) > 0: await self.incubate_eggs() if pokemon_seen > 0: self.error_code = ':' self.total_seen += pokemon_seen self.g['seen'] += pokemon_seen self.empty_visits = 0 if CIRCUIT_FAILURES: CIRCUIT_FAILURES[self.proxy] = 0 else: self.empty_visits += 1 if forts_seen == 0: self.error_code = '0 SEEN' else: self.error_code = ',' if self.empty_visits > 3: reason = '{} empty visits'.format(self.empty_visits) await self.swap_account(reason) if CIRCUIT_FAILURES: CIRCUIT_FAILURES[self.proxy] += 1 if CIRCUIT_FAILURES[self.proxy] > 20: reason = '{} empty visits'.format( CIRCUIT_FAILURES[self.proxy]) self.swap_circuit(reason) self.visits += 1 if config.MAP_WORKERS: self.worker_dict.update([ (self.worker_no, ((latitude, longitude), start, self.speed, self.total_seen, self.visits, pokemon_seen, sent)) ]) self.logger.info( 'Point processed, %d Pokemon and %d forts seen!', pokemon_seen, forts_seen, ) self.update_accounts_dict(auth=False) return pokemon_seen + forts_seen + points_seen