Guest User

Untitled

a guest
Jul 17th, 2016
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.22 KB | None | 0 0
  1. import requests
  2. import re
  3. import struct
  4. import json
  5. import argparse
  6. import pokemon_pb2
  7. import time
  8.  
  9. from google.protobuf.internal import encoder
  10.  
  11. from datetime import datetime
  12. from geopy.geocoders import GoogleV3
  13. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  14. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  15. from s2sphere import *
  16.  
  17. def encode(cellid):
  18.     output = []
  19.     encoder._VarintEncoder()(output.append, cellid)
  20.     return ''.join(output)
  21.  
  22. def getNeighbors():
  23.     origin = CellId.from_lat_lng(LatLng.from_degrees(FLOAT_LAT, FLOAT_LONG)).parent(15)
  24.     walk = [origin.id()]
  25.     # 10 before and 10 after
  26.     next = origin.next()
  27.     prev = origin.prev()
  28.     for i in range(10):
  29.         walk.append(prev.id())
  30.         walk.append(next.id())
  31.         next = next.next()
  32.         prev = prev.prev()
  33.     return walk
  34.  
  35.  
  36.  
  37. API_URL = 'https://pgorelease.nianticlabs.com/plfe/rpc'
  38. LOGIN_URL = 'https://sso.pokemon.com/sso/login?service=https%3A%2F%2Fsso.pokemon.com%2Fsso%2Foauth2.0%2FcallbackAuthorize'
  39. LOGIN_OAUTH = 'https://sso.pokemon.com/sso/oauth2.0/accessToken'
  40.  
  41. SESSION = requests.session()
  42. SESSION.headers.update({'User-Agent': 'Niantic App'})
  43. SESSION.verify = False
  44.  
  45. DEBUG = False
  46. COORDS_LATITUDE = 0
  47. COORDS_LONGITUDE = 0
  48. COORDS_ALTITUDE = 0
  49. FLOAT_LAT = 0
  50. FLOAT_LONG = 0
  51.  
  52. def f2i(float):
  53.   return struct.unpack('<Q', struct.pack('<d', float))[0]
  54.  
  55. def f2h(float):
  56.   return hex(struct.unpack('<Q', struct.pack('<d', float))[0])
  57.  
  58. def h2f(hex):
  59.   return struct.unpack('<d', struct.pack('<Q', int(hex,16)))[0]
  60.  
  61. def set_location(location_name):
  62.     geolocator = GoogleV3()
  63.     loc = geolocator.geocode(location_name)
  64.  
  65.     print('[!] Your given location: {}'.format(loc.address.encode('utf-8')))
  66.     print('[!] lat/long/alt: {} {} {}'.format(loc.latitude, loc.longitude, loc.altitude))
  67.     set_location_coords(loc.latitude, loc.longitude, loc.altitude)
  68.  
  69. def set_location_coords(lat, long, alt):
  70.     global COORDS_LATITUDE, COORDS_LONGITUDE, COORDS_ALTITUDE
  71.     global FLOAT_LAT, FLOAT_LONG
  72.     FLOAT_LAT = lat
  73.     FLOAT_LONG = long
  74.     COORDS_LATITUDE = f2i(lat) # 0x4042bd7c00000000 # f2i(lat)
  75.     COORDS_LONGITUDE = f2i(long) # 0xc05e8aae40000000 #f2i(long)
  76.     COORDS_ALTITUDE = f2i(alt)
  77.  
  78. def get_location_coords():
  79.     return (COORDS_LATITUDE, COORDS_LONGITUDE, COORDS_ALTITUDE)
  80.  
  81. def api_req(api_endpoint, access_token, *mehs, **kw):
  82.     while True:
  83.         try:
  84.             p_req = pokemon_pb2.RequestEnvelop()
  85.             p_req.rpc_id = 1469378659230941192
  86.  
  87.             p_req.unknown1 = 2
  88.  
  89.             p_req.latitude, p_req.longitude, p_req.altitude = get_location_coords()
  90.  
  91.             p_req.unknown12 = 989
  92.  
  93.             if 'useauth' not in kw or not kw['useauth']:
  94.                 p_req.auth.provider = 'ptc'
  95.                 p_req.auth.token.contents = access_token
  96.                 p_req.auth.token.unknown13 = 14
  97.             else:
  98.                 p_req.unknown11.unknown71 = kw['useauth'].unknown71
  99.                 p_req.unknown11.unknown72 = kw['useauth'].unknown72
  100.                 p_req.unknown11.unknown73 = kw['useauth'].unknown73
  101.  
  102.             for meh in mehs:
  103.                 p_req.MergeFrom(meh)
  104.  
  105.             protobuf = p_req.SerializeToString()
  106.  
  107.             r = SESSION.post(api_endpoint, data=protobuf, verify=False)
  108.  
  109.             p_ret = pokemon_pb2.ResponseEnvelop()
  110.             p_ret.ParseFromString(r.content)
  111.  
  112.             if DEBUG:
  113.                 print("REQUEST:")
  114.                 print(p_req)
  115.                 print("Response:")
  116.                 print(p_ret)
  117.                 print("\n\n")
  118.  
  119.             print("[ ] Sleeping for 2 seconds to get around rate-limit.")
  120.             time.sleep(2)
  121.             return p_ret
  122.         except Exception, e:
  123.             if DEBUG:
  124.                 print(e)
  125.             print('[-] API request error, retrying')
  126.             time.sleep(1)
  127.             continue
  128.  
  129. def get_profile(access_token, api, useauth, *reqq):
  130.     req = pokemon_pb2.RequestEnvelop()
  131.  
  132.     req1 = req.requests.add()
  133.     req1.type = 2
  134.     if len(reqq) >= 1:
  135.         req1.MergeFrom(reqq[0])
  136.  
  137.     req2 = req.requests.add()
  138.     req2.type = 126
  139.     if len(reqq) >= 2:
  140.         req2.MergeFrom(reqq[1])
  141.  
  142.     req3 = req.requests.add()
  143.     req3.type = 4
  144.     if len(reqq) >= 3:
  145.         req3.MergeFrom(reqq[2])
  146.  
  147.     req4 = req.requests.add()
  148.     req4.type = 129
  149.     if len(reqq) >= 4:
  150.         req4.MergeFrom(reqq[3])
  151.  
  152.     req5 = req.requests.add()
  153.     req5.type = 5
  154.     if len(reqq) >= 5:
  155.         req5.MergeFrom(reqq[4])
  156.  
  157.     return api_req(api, access_token, req, useauth = useauth)
  158.  
  159. def get_api_endpoint(access_token, api = API_URL):
  160.     p_ret = get_profile(access_token, api, None)
  161.     try:
  162.         return ('https://%s/rpc' % p_ret.api_url)
  163.     except:
  164.         return None
  165.  
  166.  
  167. def login_ptc(username, password):
  168.     print('[!] login for: {}'.format(username))
  169.     head = {'User-Agent': 'niantic'}
  170.     r = SESSION.get(LOGIN_URL, headers=head)
  171.     jdata = json.loads(r.content)
  172.     data = {
  173.         'lt': jdata['lt'],
  174.         'execution': jdata['execution'],
  175.         '_eventId': 'submit',
  176.         'username': username,
  177.         'password': password,
  178.     }
  179.     r1 = SESSION.post(LOGIN_URL, data=data, headers=head)
  180.  
  181.     ticket = None
  182.     try:
  183.         ticket = re.sub('.*ticket=', '', r1.history[0].headers['Location'])
  184.     except e:
  185.         if DEBUG:
  186.             print(r1.json()['errors'][0])
  187.         return None
  188.  
  189.     data1 = {
  190.         'client_id': 'mobile-app_pokemon-go',
  191.         'redirect_uri': 'https://www.nianticlabs.com/pokemongo/error',
  192.         'client_secret': 'w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR',
  193.         'grant_type': 'refresh_token',
  194.         'code': ticket,
  195.     }
  196.     r2 = SESSION.post(LOGIN_OAUTH, data=data1)
  197.     access_token = re.sub('&expires.*', '', r2.content)
  198.     access_token = re.sub('.*access_token=', '', access_token)
  199.     return access_token
  200.  
  201. def heartbeat(api_endpoint, access_token, response):
  202.     m4 = pokemon_pb2.RequestEnvelop.Requests()
  203.     m = pokemon_pb2.RequestEnvelop.MessageSingleInt()
  204.     m.f1 = int(time.time() * 1000)
  205.     m4.message = m.SerializeToString()
  206.     m5 = pokemon_pb2.RequestEnvelop.Requests()
  207.     m = pokemon_pb2.RequestEnvelop.MessageSingleString()
  208.     m.bytes = "05daf51635c82611d1aac95c0b051d3ec088a930"
  209.     m5.message = m.SerializeToString()
  210.  
  211.     walk = sorted(getNeighbors())
  212.  
  213.     m1 = pokemon_pb2.RequestEnvelop.Requests()
  214.     m1.type = 106
  215.     m = pokemon_pb2.RequestEnvelop.MessageQuad()
  216.     m.f1 = ''.join(map(encode, walk))
  217.     m.f2 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
  218.     m.lat = COORDS_LATITUDE
  219.     m.long = COORDS_LONGITUDE
  220.     m1.message = m.SerializeToString()
  221.     response = get_profile(
  222.         access_token,
  223.         api_endpoint,
  224.         response.unknown7,
  225.         m1,
  226.         pokemon_pb2.RequestEnvelop.Requests(),
  227.         m4,
  228.         pokemon_pb2.RequestEnvelop.Requests(),
  229.         m5)
  230.     payload = response.payload[0]
  231.     heartbeat = pokemon_pb2.ResponseEnvelop.HeartbeatPayload()
  232.     heartbeat.ParseFromString(payload)
  233.     return heartbeat
  234.  
  235.  
  236. def main():
  237.     pokemons = json.load(open('pokemon.json'))
  238.     parser = argparse.ArgumentParser()
  239.     parser.add_argument("-u", "--username", help="PTC Username", required=True)
  240.     parser.add_argument("-p", "--password", help="PTC Password", required=True)
  241.     parser.add_argument("-l", "--location", help="Location", required=True)
  242.     parser.add_argument("-d", "--debug", help="Debug Mode", action='store_true')
  243.     parser.set_defaults(DEBUG=False)
  244.     args = parser.parse_args()
  245.  
  246.     if args.debug:
  247.         global DEBUG
  248.         DEBUG = True
  249.         print('[!] DEBUG mode on')
  250.  
  251.     set_location(args.location)
  252.  
  253.     access_token = login_ptc(args.username, args.password)
  254.     if access_token is None:
  255.         print('[-] Wrong username/password')
  256.         return
  257.     print('[+] RPC Session Token: {} ...'.format(access_token[:25]))
  258.  
  259.     api_endpoint = get_api_endpoint(access_token)
  260.     if api_endpoint is None:
  261.         print('[-] RPC server offline')
  262.         return
  263.     print('[+] Received API endpoint: {}'.format(api_endpoint))
  264.  
  265.     response = get_profile(access_token, api_endpoint, None)
  266.     if response is not None:
  267.         print('[+] Login successful')
  268.  
  269.         payload = response.payload[0]
  270.         profile = pokemon_pb2.ResponseEnvelop.ProfilePayload()
  271.         profile.ParseFromString(payload)
  272.         print('[+] Username: {}'.format(profile.profile.username))
  273.  
  274.         creation_time = datetime.fromtimestamp(int(profile.profile.creation_time)/1000)
  275.         print('[+] You are playing Pokemon Go since: {}'.format(
  276.             creation_time.strftime('%Y-%m-%d %H:%M:%S'),
  277.         ))
  278.  
  279.         for curr in profile.profile.currency:
  280.             print('[+] {}: {}'.format(curr.type, curr.amount))
  281.     else:
  282.         print('[-] Ooops...')
  283.  
  284.     origin = LatLng.from_degrees(FLOAT_LAT, FLOAT_LONG)
  285.     while True:
  286.         original_lat = FLOAT_LAT
  287.         original_long = FLOAT_LONG
  288.         parent = CellId.from_lat_lng(LatLng.from_degrees(FLOAT_LAT, FLOAT_LONG)).parent(15)
  289.  
  290.         h = heartbeat(api_endpoint, access_token, response)
  291.         hs = [h]
  292.         seen = set([])
  293.         for child in parent.children():
  294.             latlng = LatLng.from_point(Cell(child).get_center())
  295.             set_location_coords(latlng.lat().degrees, latlng.lng().degrees, 0)
  296.             hs.append(heartbeat(api_endpoint, access_token, response))
  297.         set_location_coords(original_lat, original_long, 0)
  298.  
  299.         visible = []
  300.  
  301.         for hh in hs:
  302.             for cell in hh.cells:
  303.                 for wild in cell.WildPokemon:
  304.                     hash = wild.SpawnPointId + ':' + str(wild.pokemon.PokemonId)
  305.                     visible.append(wild)
  306.                     seen.add(hash)
  307.  
  308.         print('')
  309.         for cell in h.cells:
  310.             if cell.NearbyPokemon:
  311.                 other = LatLng.from_point(Cell(CellId(cell.S2CellId)).get_center())
  312.                 diff = other - origin
  313.                 # print(diff)
  314.                 difflat = diff.lat().degrees
  315.                 difflng = diff.lng().degrees
  316.                 direction = (('N' if difflat >= 0 else 'S') if abs(difflat) > 1e-4 else '')  + (('E' if difflng >= 0 else 'W') if abs(difflng) > 1e-4 else '')
  317.                 print("Within one step of %s (%sm %s from you):" % (other, int(origin.get_distance(other).radians * 6366468.241830914), direction))
  318.                 with open("test.txt", "a") as myfile:
  319.                     myfile.write("Within one step of %s (%sm %s from you):" % (other, int(origin.get_distance(other).radians * 6366468.241830914), direction) + "\n")
  320.                 for poke in cell.NearbyPokemon:
  321.                     print('    (%s) %s' % (poke.PokedexNumber, pokemons[poke.PokedexNumber - 1]['Name']))
  322.                     with open("test.txt", "a") as myfile:
  323.                        myfile.write('    (%s) %s' % (poke.PokedexNumber, pokemons[poke.PokedexNumber - 1]['Name']) + "\n")
  324.  
  325.  
  326.         print('')
  327.         for poke in visible:
  328.             other = LatLng.from_degrees(poke.Latitude, poke.Longitude)
  329.             diff = other - origin
  330.  
  331.             difflat = diff.lat().degrees
  332.             difflng = diff.lng().degrees
  333.             direction = "{0}{1}".format(
  334.                 (('N' if difflat >= 0 else 'S') if abs(difflat) > 1e-4 else ''),
  335.                 (('E' if difflng >= 0 else 'W') if abs(difflng) > 1e-4 else '')
  336.             )
  337.  
  338.             visible_at_str = "(%s) %s is visible at (%s, %s) for %s seconds (%sm %s from you)" % (
  339.                 poke.pokemon.PokemonId,
  340.                 pokemons[poke.pokemon.PokemonId - 1]['Name'],
  341.                 poke.Latitude,
  342.                 poke.Longitude,
  343.                 poke.TimeTillHiddenMs / 1000,
  344.                 int(origin.get_distance(other).radians * 6366468.241830914),
  345.                 direction
  346.             )
  347.  
  348.             print(visible_at_str)
  349.  
  350.             with open("test.txt", "a") as myfile:
  351.                 myfile.write(visible_at_str + "\n")
  352.  
  353.         print('')
  354.         walk = getNeighbors()
  355.         next = LatLng.from_point(Cell(CellId(walk[2])).get_center())
  356.  
  357.         set_location_coords(next.lat().degrees, next.lng().degrees, 0)
  358.  
  359. if __name__ == '__main__':
  360.     main()
Advertisement
Add Comment
Please, Sign In to add comment