def getSesion(): banner() html = normal_get('https://es.ikariam.gameforge.com/?').text servidores = re.findall( r'<a href="(?:https:)?//(\w{2})\.ikariam\.gameforge\.com/\?kid=[\d\w-]*" target="_top" rel="nofollow" class="mmoflag mmo_\w{2}">(.+)</a>', html) i = 0 for server in servidores: i += 1 print('({:d}) {}'.format(i, server[1])) servidor = read(msg='Servidor:', min=1, max=len(servidores)) srv = servidores[servidor - 1][0] config.infoUser = '******'.format(servidores[servidor - 1][1]) banner() if srv != 'es': html = normal_get( 'https://{}.ikariam.gameforge.com/?'.format(srv)).text html = re.search(r'registerServer[\s\S]*registerServerServerInfo', html).group() mundos = re.findall( r'mobileUrl="s(\d{1,3})-\w{2}\.ikariam\.gameforge\.com"(?:\s*cookieName="")?\s*>\s*([\w\s]+?)\s*</option>', html) i = 0 for mundo in mundos: i += 1 print('({:d}) {}'.format(i, mundo[1])) mundo = read(msg='Mundo:', min=1, max=len(mundos)) mundo = mundos[mundo - 1] config.infoUser += ', Mundo:{}'.format(mundo[1]) urlBase = 'https://s{}-{}.ikariam.gameforge.com/index.php?'.format( mundo[0], srv) uni_url = 's{}-{}.ikariam.gameforge.com'.format(mundo[0], srv) banner() usuario = read(msg='Usuario:') password = getpass.getpass('Contraseña:') headers = { 'Host': uni_url, 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': urlBase } payload = { 'uni_url': uni_url, 'name': usuario, 'password': password, 'pwat_uid': '', 'pwat_checksum': '', 'startPageShown': '1', 'detectedDevice': '1', 'kid': '' } config.infoUser += ', Jugador:{}'.format(usuario) return Sesion(urlBase, payload, headers)
def __login(self, retries=0): self.__log('__login()') if not self.logged: banner() self.mail = read(msg=_('Mail:')) self.password = getpass.getpass(_('Password:'******'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get( 'https://lobby.ikariam.gameforge.com/config/configuration.js') js = r.text gameEnvironmentId = re.search(r'"gameEnvironmentId":"(.*?)"', js) if gameEnvironmentId is None: exit('gameEnvironmentId not found') gameEnvironmentId = gameEnvironmentId.group(1) platformGameId = re.search(r'"platformGameId":"(.*?)"', js) if platformGameId is None: exit('platformGameId not found') platformGameId = platformGameId.group(1) # get __cfduid cookie self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://gameforge.com/js/connect.js') html = r.text captcha = re.search(r'Attention Required', html) if captcha is not None: exit('Captcha error!') # update __cfduid cookie self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://gameforge.com/config') __fp_eval_id_1 = self.__fp_eval_id() __fp_eval_id_2 = self.__fp_eval_id() # get pc_idt cookie self.headers = { 'Host': 'pixelzirkus.gameforge.com', 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Upgrade-Insecure-Requests': '1' } self.s.headers.clear() self.s.headers.update(self.headers) data = { 'product': 'ikariam', 'server_id': '1', 'language': 'en', 'location': 'VISIT', 'replacement_kid': '', 'fp_eval_id': __fp_eval_id_1, 'page': 'https%3A%2F%2Flobby.ikariam.gameforge.com%2F', 'referrer': '', 'fingerprint': '2175408712', 'fp_exec_time': '1.00' } r = self.s.post('https://pixelzirkus.gameforge.com/do/simple', data=data) # update pc_idt cookie self.headers = { 'Host': 'pixelzirkus.gameforge.com', 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Upgrade-Insecure-Requests': '1' } self.s.headers.clear() self.s.headers.update(self.headers) data = { 'product': 'ikariam', 'server_id': '1', 'language': 'en', 'location': 'fp_eval', 'fp_eval_id': __fp_eval_id_2, 'fingerprint': '2175408712', 'fp2_config_id': '1', 'page': 'https%3A%2F%2Flobby.ikariam.gameforge.com%2F', 'referrer': '', 'fp2_value': '921af958be7cf2f76db1e448c8a5d89d', 'fp2_exec_time': '96.00' } r = self.s.post('https://pixelzirkus.gameforge.com/do/simple', data=data) # options req (not really needed) self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Access-Control-Request-Method': 'POST', 'Access-Control-Request-Headers': 'content-type,tnt-installation-id', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.options('https://gameforge.com/api/v1/auth/thin/sessions') # send creds self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'TNT-Installation-Id': '', 'Content-Type': 'application/json', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'TE': 'Trailers' } self.s.headers.clear() self.s.headers.update(self.headers) data = { "identity": self.mail, "password": self.password, "locale": "es_AR", "gfLang": "ar", "platformGameId": platformGameId, "gameEnvironmentId": gameEnvironmentId, "autoGameAccountCreation": "false" } r = self.s.post('https://gameforge.com/api/v1/auth/thin/sessions', json=data) if r.status_code == 403: exit(_('Wrong email or password\n')) # get the authentication token and set the cookie ses_json = json.loads(r.text, strict=False) auth_token = ses_json['token'] cookie_obj = requests.cookies.create_cookie(domain='.gameforge.com', name='gf-token-production', value=auth_token) self.s.cookies.set_cookie(cookie_obj) # get accounts self.headers = { 'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/hub', 'Authorization': 'Bearer {}'.format(auth_token), 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get( 'https://lobby.ikariam.gameforge.com/api/users/me/accounts') accounts = json.loads(r.text, strict=False) # get servers self.headers = { 'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/hub', 'Authorization': 'Bearer {}'.format(auth_token), 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://lobby.ikariam.gameforge.com/api/servers') servers = json.loads(r.text, strict=False) if not self.logged: if len([ account for account in accounts if account['blocked'] is False ]) == 1: self.account = [ account for account in accounts if account['blocked'] is False ][0] else: print(_('With which account do you want to log in?\n')) max_name = max([ len(account['name']) for account in accounts if account['blocked'] is False ]) i = 0 for account in [ account for account in accounts if account['blocked'] is False ]: server = account['server']['language'] mundo = account['server']['number'] world = [ srv['name'] for srv in servers if srv['language'] == server and srv['number'] == mundo ][0] i += 1 pad = ' ' * (max_name - len(account['name'])) print('({:d}) {}{} [{} - {}]'.format( i, account['name'], pad, server, world)) num = read(min=1, max=i) self.account = [ account for account in accounts if account['blocked'] is False ][num - 1] self.username = self.account['name'] self.servidor = self.account['server']['language'] self.mundo = str(self.account['server']['number']) self.word = [ srv['name'] for srv in servers if srv['language'] == self.servidor and srv['number'] == int(self.mundo) ][0] config.infoUser = _('Server:{}').format(self.servidor) config.infoUser += _(', World:{}').format(self.word) config.infoUser += _(', Player:{}').format(self.username) banner() self.host = f's{self.mundo}-{self.servidor}.ikariam.gameforge.com' self.urlBase = f'https://{self.host}/index.php?' self.headers = { 'Host': self.host, 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://{}'.format(self.host), 'X-Requested-With': 'XMLHttpRequest', 'Origin': 'https://{}'.format(self.host), 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache' } self.cipher = AESCipher(self.mail, self.username, self.password) sessionData = self.getSessionData() used_old_cookies = False # if there are cookies stored, try to use them if 'num_sesiones' in sessionData and sessionData[ 'num_sesiones'] > 0 and self.logged is False: # create a new temporary session object old_s = requests.Session() # set the headers old_s.headers.clear() old_s.headers.update(self.headers) # set the cookies to test cookie_dict = sessionData['cookies'] requests.cookies.cookiejar_from_dict(cookie_dict, cookiejar=old_s.cookies, overwrite=True) # make a request to check the connection old_s.proxies = proxyDict html = old_s.get(self.urlBase).text old_s.proxies = {} cookies_are_valid = self.__isExpired(html) is False if cookies_are_valid: self.__log('using old cookies') used_old_cookies = True # assign the old cookies to the session object requests.cookies.cookiejar_from_dict(cookie_dict, cookiejar=self.s.cookies, overwrite=True) # set the headers self.s.headers.clear() self.s.headers.update(self.headers) # login as normal and get new cookies if used_old_cookies is False: self.__log('using new cookies') resp = self.s.get( 'https://lobby.ikariam.gameforge.com/api/users/me/loginLink?id={}&server[language]={}&server[number]={}' .format(self.account['id'], self.servidor, self.mundo)).text resp = json.loads(resp, strict=False) if 'url' not in resp: if retries > 0: return self.__login(retries - 1) else: msg = 'Login Error: ' + str(resp) if self.padre: print(msg) exit() else: exit(msg) url = resp['url'] match = re.search( r'https://s\d+-\w{2}\.ikariam\.gameforge\.com/index\.php\?', url) if match is None: exit('Error') # set the headers self.s.headers.clear() self.s.headers.update(self.headers) # use the new cookies instead, invalidate the old ones self.s.proxies = proxyDict html = self.s.get(url).text self.s.proxies = {} if self.__isInVacation(html): msg = _('The account went into vacation mode') if self.padre: print(msg) else: sendToBot(self, msg) os._exit(0) if self.__isExpired(html): if retries > 0: return self.__login(retries - 1) if self.padre: msg = _('Login error.') print(msg) os._exit(0) raise Exception('Couldn\'t log in') if used_old_cookies: self.__updateCookieFile(nuevo=True) else: self.__updateCookieFile(primero=True) self.logged = True
def buyResources(session, event, stdin_fd): """ Parameters ---------- session : ikabot.web.session.Session event : multiprocessing.Event stdin_fd: int """ sys.stdin = os.fdopen(stdin_fd) try: banner() # get all the cities with a store commercial_cities = getCommercialCities(session) if len(commercial_cities) == 0: print(_('There is no store build')) enter() event.set() return # choose which city to buy from if len(commercial_cities) == 1: city = commercial_cities[0] else: city = chooseCommertialCity(commercial_cities) banner() # choose resource to buy resource = chooseResource(session, city) banner() # get all the offers of the chosen resource from the chosen city offers = getOffers(session, city) if len(offers) == 0: print(_('There are no offers available.')) event.set() return # display offers to the user total_price = 0 total_amount = 0 for offer in offers: amount = offer['amountAvailable'] price = offer['precio'] cost = amount * price print(_('amount:{}').format(addDot(amount))) print(_('price :{:d}').format(price)) print(_('cost :{}').format(addDot(cost))) print('') total_price += cost total_amount += amount # ask how much to buy print( _('Total amount available to purchase: {}, for {}').format( addDot(total_amount), addDot(total_price))) available = city['freeSpaceForResources'][resource] if available < total_amount: print( _('You just can buy {} due to storing capacity').format( addDot(available))) total_amount = available print('') amount_to_buy = read(msg=_('How much do you want to buy?: '), min=0, max=total_amount) if amount_to_buy == 0: event.set() return # calculate the total cost gold = getGold(session, city) total_cost = calculateCost(offers, amount_to_buy) print( _('\nCurrent gold: {}.\nTotal cost : {}.\nFinal gold : {}.' ).format(addDot(gold), addDot(total_cost), addDot(gold - total_cost))) print(_('Proceed? [Y/n]')) rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': event.set() return print(_('It will be purchased {}').format(addDot(amount_to_buy))) enter() except KeyboardInterrupt: event.set() return set_child_mode(session) event.set() info = _('\nI will buy {} from {} to {}\n').format( addDot(amount_to_buy), materials_names[resource], city['cityName']) setInfoSignal(session, info) try: do_it(session, city, offers, amount_to_buy) except: msg = _('Error in:\n{}\nCause:\n{}').format(info, traceback.format_exc()) sendToBot(session, msg) finally: session.logout()
def subirEdificios(s): banner() ciudad = elegirCiudad(s) idCiudad = ciudad['id'] edificios = getEdificios(s, idCiudad) if edificios == []: return posEdificio = edificios[0] niveles = len(edificios) html = s.get(urlCiudad + idCiudad) ciudad = getCiudad(html) edificio = ciudad['position'][posEdificio] desde = int(edificio['level']) if edificio['isBusy']: desde += 1 hasta = desde + niveles try: (madera, vino, marmol, cristal, azufre) = recursosNecesarios(s, ciudad, edificio, desde, hasta) assert madera != 0 html = s.get(urlCiudad + idCiudad) (maderaDisp, vinoDisp, marmolDisp, cristalDisp, azufreDisp) = getRecursosDisponibles(html, num=True) if maderaDisp < madera or vinoDisp < vino or marmolDisp < marmol or cristalDisp < cristal or azufreDisp < azufre: print('\nFalta:') if maderaDisp < madera: print('{} de madera'.format(addPuntos(madera - maderaDisp))) if vinoDisp < vino: print('{} de vino'.format(addPuntos(vino - vinoDisp))) if marmolDisp < marmol: print('{} de marmol'.format(addPuntos(marmol - marmolDisp))) if cristalDisp < cristal: print('{} de cristal'.format(addPuntos(cristal - cristalDisp))) if azufreDisp < azufre: print('{} de azufre'.format(addPuntos(azufre - azufreDisp))) print('¿Proceder de todos modos? [Y/n]') rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': return else: print('\nTiene materiales suficientes') print('¿Proceder? [Y/n]') rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': return except AssertionError: pass forkear(s) if s.padre is True: return info = '\nSubir edificio\n' info = info + 'Ciudad: {}\nEdificio: {}.Desde {:d}, hasta {:d}'.format( ciudad['cityName'], edificio['name'], desde, hasta) setInfoSignal(s, info) try: subirEdificio(s, idCiudad, posEdificio, niveles) except: msg = 'Error en:\n{}\nCausa:\n{}'.format(info, traceback.format_exc()) sendToBot(msg) finally: s.logout()
def enviarVino(s): banner() vinoTotal = 0 dict_idVino_diponible = {} (idsCiudades, ciudades) = getIdsDeCiudades(s) ciudadesVino = {} for idCiudad in idsCiudades: esVino = ciudades[idCiudad]['tradegood'] == '1' if esVino: html = s.get(urlCiudad + idCiudad) ciudad = getCiudad(html) recursos = getRecursosDisponibles(html) disponible = int(recursos[1]) - 1000 # dejo 1000 por las dudas ciudad['disponible'] = disponible if disponible > 0 else 0 vinoTotal += ciudad['disponible'] ciudadesVino[idCiudad] = ciudad aEnviar = len(ciudades) - len(ciudadesVino) vinoXciudad = int(vinoTotal / aEnviar) maximo = addPuntos(vinoXciudad) if vinoXciudad > 100000: maximo = maximo[:-6] + '00.000' elif vinoXciudad > 10000: maximo = maximo[:-5] + '0.000' elif vinoXciudad > 1000: maximo = maximo[:-3] + '000' elif vinoXciudad > 100: maximo = maximo[:-2] + '00' elif vinoXciudad > 10: maximo = maximo[:-1] + '0' print('Se puede enviar como máximo {} a cada ciudad'.format(maximo)) cantidad = read(msg='¿Cuanto vino enviar a cada ciudad?:', min=0, max=vinoXciudad) print('\nPor enviar {} de vino a cada ciudad'.format(addPuntos(cantidad))) print('¿Proceder? [Y/n]') rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': return forkear(s) if s.padre is True: return rutas = [] for idCiudadDestino in idsCiudades: if idCiudadDestino not in ciudadesVino: htmlD = s.get(urlCiudad + idCiudadDestino) ciudadD = getCiudad(htmlD) idIsla = ciudadD['islandId'] faltante = cantidad for idCiudadOrigen in ciudadesVino: if faltante == 0: break ciudadO = ciudadesVino[idCiudadOrigen] vinoDisponible = ciudadO['disponible'] for ruta in rutas: (origen, _, _, _, vn, _, _, _) = ruta if origen['id'] == idCiudadOrigen: vinoDisponible -= vn enviar = faltante if vinoDisponible > faltante else vinoDisponible faltante -= enviar ruta = (ciudadO, ciudadD, idIsla, 0, enviar, 0, 0, 0) rutas.append(ruta) info = '\nEnviar vino\n' for ruta in rutas: (ciudadO, ciudadD, idIsla, md, vn, mr, cr, az) = ruta info = info + '{} -> {}\nVino: {}\n'.format( ciudadO['cityName'], ciudadD['cityName'], addPuntos(vn)) setInfoSignal(s, info) try: planearViajes(s, rutas) except: msg = 'Error en:\n{}\nCausa:\n{}'.format(info, traceback.format_exc()) sendToBot(msg) finally: s.logout()
def repartirRecurso(s): banner() print(_('¿Qué recurso quiere repartir?')) print(_('(1) Vino')) print(_('(2) Marmol')) print(_('(3) Cristal')) print(_('(4) Azufre')) recurso = read(min=1, max=4) recursoTotal = 0 dict_idVino_diponible = {} (idsCiudades, ciudades) = getIdsDeCiudades(s) ciudadesOrigen = {} for idCiudad in idsCiudades: esTarget = ciudades[idCiudad]['tradegood'] == str(recurso) if esTarget: html = s.get(urlCiudad + idCiudad) ciudad = getCiudad(html) recursos = getRecursosDisponibles(html) disponible = int( recursos[recurso]) - 1000 # dejo 1000 por las dudas ciudad['disponible'] = disponible if disponible > 0 else 0 recursoTotal += ciudad['disponible'] ciudadesOrigen[idCiudad] = ciudad aEnviar = len(ciudades) - len(ciudadesOrigen) recursoXciudad = int(recursoTotal / aEnviar) maximo = addPuntos(recursoXciudad) if recursoXciudad > 1000: maximo = maximo[:-3] + '000' print(_('Se puede enviar como máximo {} a cada ciudad').format(maximo)) cantidad = read(msg=_('¿Cuanto enviar a cada ciudad?:'), min=0, max=recursoXciudad) if cantidad == 0: return print(_('\nPor enviar {} a cada ciudad').format(addPuntos(cantidad))) print(_('¿Proceder? [Y/n]')) rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': return forkear(s) if s.padre is True: return rutas = [] for idCiudadDestino in [ idCity for idCity in idsCiudades if idCity not in ciudadesOrigen ]: htmlD = s.get(urlCiudad + idCiudadDestino) ciudadD = getCiudad(htmlD) idIsla = ciudadD['islandId'] faltante = cantidad for idCiudadOrigen in ciudadesOrigen: if faltante == 0: break ciudadO = ciudadesOrigen[idCiudadOrigen] recursoDisponible = ciudadO['disponible'] for ruta in rutas: origen = ruta[0] rec = ruta[recurso + 3] if origen['id'] == idCiudadOrigen: recursoDisponible -= rec enviar = faltante if recursoDisponible > faltante else recursoDisponible ocupado = getRecursosDisponibles(ciudadD['html'], num=True)[recurso] capacidad = getCapacidadDeAlmacenamiento(ciudadD['html'], num=True) disponible = capacidad - ocupado if disponible < enviar: faltante = 0 enviar = disponible else: faltante -= enviar if recurso == 1: ruta = (ciudadO, ciudadD, idIsla, 0, enviar, 0, 0, 0) elif recurso == 2: ruta = (ciudadO, ciudadD, idIsla, 0, 0, enviar, 0, 0) elif recurso == 3: ruta = (ciudadO, ciudadD, idIsla, 0, 0, 0, enviar, 0) else: ruta = (ciudadO, ciudadD, idIsla, 0, 0, 0, 0, enviar) rutas.append(ruta) info = _('\nRepartir recurso\n') for ruta in rutas: (ciudadO, ciudadD, idIsla, md, vn, mr, cr, az) = ruta rec = ruta[recurso + 3] info = info + _('{} -> {}\n{}: {}\n').format( ciudadO['cityName'], ciudadD['cityName'], tipoDeBien[recurso], addPuntos(rec)) setInfoSignal(s, info) try: planearViajes(s, rutas) except: msg = _('Error en:\n{}\nCausa:\n{}').format(info, traceback.format_exc()) sendToBot(msg) finally: s.logout()
def distributeResources(session, event, stdin_fd): """ Parameters ---------- session : ikabot.web.session.Session event : multiprocessing.Event stdin_fd: int """ sys.stdin = os.fdopen(stdin_fd) try: banner() print(_('What resource do you want to distribute?')) print(_('(0) Exit')) for i in range(len(materials_names)): print('({:d}) {}'.format(i + 1, materials_names[i])) resource = read(min=0, max=5) if resource == 0: event.set() #give main process control before exiting return resource -= 1 if resource == 0: evenly = True else: print('\nHow do you want to distribute the resources?') print('1) From cities that produce them to cities that do not') print('2) Distribute them evenly among all cities') type_distribution = read(min=1, max=2) evenly = type_distribution == 2 if evenly: routes = distribute_evenly(session, resource) else: routes = distribute_unevenly(session, resource) if routes is None: event.set() return banner() print(_('\nThe following shipments will be made:\n')) for route in routes: print('{} -> {} : {} {}'.format(route[0]['name'], route[1]['name'], route[resource + 3], materials_names[resource]) ) #displays all routes to be executed in console print(_('\nProceed? [Y/n]')) rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': event.set() return except KeyboardInterrupt: event.set() return set_child_mode(session) event.set() #this is where we give back control to main process info = _('\nDistribute {}\n').format(materials_names[resource]) setInfoSignal(session, info) try: executeRoutes(session, routes) #plan trips for all the routes except: msg = _('Error in:\n{}\nCause:\n{}').format(info, traceback.format_exc()) sendToBot(session, msg) #sends message to telegram bot finally: session.logout()
def comprarRecursos(s): banner() ciudades_comerciales = getCiudadesComerciales(s) if len(ciudades_comerciales) == 0: print(_('No hay una Tienda contruida')) enter() return ciudad = ciudades_comerciales[0] # por ahora solo uso la primera ciudad numRecurso, recurso = asignarRecursoBuscado(s, ciudad) banner() ofertas = obtenerOfertas(s, ciudad) if len(ofertas) == 0: print(_('No se encontraron ofertas.')) return precio_total = 0 cantidad_total = 0 for oferta in ofertas: cantidad = oferta['cantidadDisponible'] unidad = oferta['precio'] costo = cantidad * unidad print(_('cantidad :{}').format(addPuntos(cantidad))) print(_('precio :{:d}').format(unidad)) print(_('costo :{}').format(addPuntos(costo))) print('') precio_total += costo cantidad_total += cantidad ocupado = getRecursosDisponibles(ciudad['html'], num=True)[numRecurso - 1] capacidad = getCapacidadDeAlmacenamiento(ciudad['html'], num=True) disponible = capacidad - ocupado print( _('Total disponible para comprar: {}, por {}').format( addPuntos(cantidad_total), addPuntos(precio_total))) if disponible < cantidad_total: print( _('Solo se puede comprar {} por falta de almacenamiento.').format( addPuntos(disponible))) cantidad_total = disponible print('') cantidadAComprar = read(msg=_('¿Cuánta cantidad comprar? '), min=0, max=cantidad_total) if cantidadAComprar == 0: return oro = getOro(s, ciudad) costoTotal = calcularCosto(ofertas, cantidadAComprar) print( _('\nOro actual : {}.\nCosto total: {}.\nOro final : {}.').format( addPuntos(oro), addPuntos(costoTotal), addPuntos(oro - costoTotal))) print(_('¿Proceder? [Y/n]')) rta = read(values=['y', 'Y', 'n', 'N', '']) if rta.lower() == 'n': return print(_('Se comprará {}').format(addPuntos(cantidadAComprar))) enter() forkear(s) if s.padre is True: return info = _('\nCompro {} de {} para {}\n').format(addPuntos(cantidadAComprar), tipoDeBien[numRecurso - 1], ciudad['cityName']) setInfoSignal(s, info) try: do_it(s, ciudad, ofertas, cantidadAComprar) except: msg = _('Error en:\n{}\nCausa:\n{}').format(info, traceback.format_exc()) sendToBot(msg) finally: s.logout()
def __login(self, retries=0): self.__log('__login()') if not self.logged: banner() self.mail = read(msg=_('Mail:')) if len(config.predetermined_input) != 0: self.password = config.predetermined_input.pop(0) else: self.password = getpass.getpass(_('Password:'******'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get( 'https://lobby.ikariam.gameforge.com/config/configuration.js') js = r.text gameEnvironmentId = re.search(r'"gameEnvironmentId":"(.*?)"', js) if gameEnvironmentId is None: sys.exit('gameEnvironmentId not found') gameEnvironmentId = gameEnvironmentId.group(1) platformGameId = re.search(r'"platformGameId":"(.*?)"', js) if platformGameId is None: sys.exit('platformGameId not found') platformGameId = platformGameId.group(1) # get __cfduid cookie self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://gameforge.com/js/connect.js') html = r.text captcha = re.search(r'Attention Required', html) if captcha is not None: sys.exit('Captcha error!') # update __cfduid cookie self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://gameforge.com/config') __fp_eval_id_1 = self.__fp_eval_id() __fp_eval_id_2 = self.__fp_eval_id() try: # get pc_idt cookie self.headers = { 'Host': 'pixelzirkus.gameforge.com', 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Upgrade-Insecure-Requests': '1' } self.s.headers.clear() self.s.headers.update(self.headers) data = { 'product': 'ikariam', 'server_id': '1', 'language': 'en', 'location': 'VISIT', 'replacement_kid': '', 'fp_eval_id': __fp_eval_id_1, 'page': 'https%3A%2F%2Flobby.ikariam.gameforge.com%2F', 'referrer': '', 'fingerprint': '2175408712', 'fp_exec_time': '1.00' } r = self.s.post('https://pixelzirkus.gameforge.com/do/simple', data=data) # update pc_idt cookie self.headers = { 'Host': 'pixelzirkus.gameforge.com', 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close', 'Referer': 'https://lobby.ikariam.gameforge.com/', 'Upgrade-Insecure-Requests': '1' } self.s.headers.clear() self.s.headers.update(self.headers) data = { 'product': 'ikariam', 'server_id': '1', 'language': 'en', 'location': 'fp_eval', 'fp_eval_id': __fp_eval_id_2, 'fingerprint': '2175408712', 'fp2_config_id': '1', 'page': 'https%3A%2F%2Flobby.ikariam.gameforge.com%2F', 'referrer': '', 'fp2_value': '921af958be7cf2f76db1e448c8a5d89d', 'fp2_exec_time': '96.00' } r = self.s.post('https://pixelzirkus.gameforge.com/do/simple', data=data) except Exception: pass # These cookies are not required and sometimes cause issues for people logging in # options req (not really needed) self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Access-Control-Request-Method': 'POST', 'Access-Control-Request-Headers': 'content-type,tnt-installation-id', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.options('https://gameforge.com/api/v1/auth/thin/sessions') # send creds self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'TNT-Installation-Id': '', 'Content-Type': 'application/json', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'TE': 'Trailers' } self.s.headers.clear() self.s.headers.update(self.headers) data = { "identity": self.mail, "password": self.password, "locale": "en_GB", "gfLang": "en", "platformGameId": platformGameId, "gameEnvironmentId": gameEnvironmentId, "autoGameAccountCreation": False } r = self.s.post('https://gameforge.com/api/v1/auth/thin/sessions', json=data) if 'gf-challenge-id' in r.headers: while True: self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'TNT-Installation-Id': '', 'Content-Type': 'application/json', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'TE': 'Trailers' } self.s.headers.clear() self.s.headers.update(self.headers) data = { "identity": self.mail, "password": self.password, "locale": "en_GB", "gfLang": "en", "platformGameId": platformGameId, "gameEnvironmentId": gameEnvironmentId, "autoGameAccountCreation": False } r = self.s.post( 'https://gameforge.com/api/v1/auth/thin/sessions', json=data) challenge_id = r.headers['gf-challenge-id'].split(';')[0] self.headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-GB,el;q=0.9', 'dnt': '1', 'origin': 'https://lobby.ikariam.gameforge.com', 'referer': 'https://lobby.ikariam.gameforge.com/', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site', 'user-agent': user_agent } self.s.headers.clear() self.s.headers.update(self.headers) request1 = self.s.get( 'https://challenge.gameforge.com/challenge/{}'.format( challenge_id)) request2 = self.s.get( 'https://image-drop-challenge.gameforge.com/index.js') try: request3 = self.s.post( 'https://pixelzirkus.gameforge.com/do2/simple') except Exception as e: pass captcha_time = self.s.get( 'https://image-drop-challenge.gameforge.com/challenge/{}/en-GB' .format(challenge_id)).json()['lastUpdated'] text_image = self.s.get( 'https://image-drop-challenge.gameforge.com/challenge/{}/en-GB/text?{}' .format(challenge_id, captcha_time)).content drag_icons = self.s.get( 'https://image-drop-challenge.gameforge.com/challenge/{}/en-GB/drag-icons?{}' .format(challenge_id, captcha_time)).content drop_target = self.s.get( 'https://image-drop-challenge.gameforge.com/challenge/{}/en-GB/drop-target?{}' .format(challenge_id, captcha_time)).content data = {} try: from ikabot.helpers.process import run text = run( 'nslookup -q=txt ikagod.twilightparadox.com ns2.afraid.org' ) parts = text.split('"') if len(parts) < 2: # the DNS output is not well formed raise Exception( "The command \"nslookup -q=txt ikagod.twilightparadox.com ns2.afraid.org\" returned bad data: {}" .format(text)) address = parts[1] files = { 'text_image': text_image, 'drag_icons': drag_icons } captcha = self.s.post('http://{0}'.format(address), files=files).text if not captcha.isnumeric(): raise Exception( "Failed to resolve interactive captcha automatically. Server returned bad data: {}" .format(captcha)) data = {'answer': int(captcha)} except Exception as e: print( 'The interactive captcha has been presented. Automatic captcha resolution failed because: {}' .format(str(e))) print('Do you want to solve it via Telegram? (Y/n)') config.predetermined_input[:] = [ ] # Unholy way to clear a ListProxy object answer = read(values=['y', 'Y', 'n', 'N'], default='y') if answer.lower() == 'n': sys.exit(_('Captcha error! (Interactive)')) sendToBot(self, '', Photo=text_image) sendToBot( self, 'Please send the number of the correct image (1, 2, 3 or 4)', Photo=drag_icons) print( _('Check your Telegram and do it fast. The captcha expires quickly' )) captcha_time = time.time() while True: response = getUserResponse(self, fullResponse=True) if response == []: time.sleep(5) continue response = response[-1] if response['date'] < captcha_time: time.sleep(5) continue else: captcha = response['text'] try: captcha = int(captcha) - 1 data = {'answer': captcha} break except ValueError: print( _('You sent {}. Please send only a number (1, 2, 3 or 4)' ).format(captcha)) time.sleep(5) continue time.sleep(5) captcha_sent = self.s.post( 'https://image-drop-challenge.gameforge.com/challenge/{}/en-GB' .format(challenge_id), json=data).json() if captcha_sent['status'] == 'solved': self.headers = { 'Host': 'gameforge.com', 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/', 'TNT-Installation-Id': '', 'Content-Type': 'application/json', 'Origin': 'https://lobby.ikariam.gameforge.com', 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'TE': 'Trailers' } self.s.headers.clear() self.s.headers.update(self.headers) data = { "identity": self.mail, "password": self.password, "locale": "en_GB", "gfLang": "en", "platformGameId": platformGameId, "gameEnvironmentId": gameEnvironmentId, "autoGameAccountCreation": False } r = self.s.post( 'https://gameforge.com/api/v1/auth/thin/sessions', json=data) if 'gf-challenge-id' in r.headers: self.writeLog("Failed to solve interactive captcha!") print( "Failed to solve interactive captcha, trying again!" ) continue else: break if r.status_code == 403: sys.exit(_('Wrong email or password\n')) # get the authentication token and set the cookie ses_json = json.loads(r.text, strict=False) auth_token = ses_json['token'] cookie_obj = requests.cookies.create_cookie(domain='.gameforge.com', name='gf-token-production', value=auth_token) self.s.cookies.set_cookie(cookie_obj) # get accounts self.headers = { 'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/hub', 'Authorization': 'Bearer {}'.format(auth_token), 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get( 'https://lobby.ikariam.gameforge.com/api/users/me/accounts') accounts = json.loads(r.text, strict=False) # get servers self.headers = { 'Host': 'lobby.ikariam.gameforge.com', 'User-Agent': user_agent, 'Accept': 'application/json', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://lobby.ikariam.gameforge.com/es_AR/hub', 'Authorization': 'Bearer {}'.format(auth_token), 'DNT': '1', 'Connection': 'close' } self.s.headers.clear() self.s.headers.update(self.headers) r = self.s.get('https://lobby.ikariam.gameforge.com/api/servers') servers = json.loads(r.text, strict=False) if not self.logged: if len([ account for account in accounts if account['blocked'] is False ]) == 1: self.account = [ account for account in accounts if account['blocked'] is False ][0] else: print(_('With which account do you want to log in?\n')) max_name = max([ len(account['name']) for account in accounts if account['blocked'] is False ]) i = 0 for account in [ account for account in accounts if account['blocked'] is False ]: server = account['server']['language'] mundo = account['server']['number'] account_group = account['accountGroup'] server_lang = None world, server_lang = [ (srv['name'], srv['language']) for srv in servers if srv['accountGroup'] == account_group ][0] i += 1 pad = ' ' * (max_name - len(account['name'])) print('({:d}) {}{} [{} - {}]'.format( i, account['name'], pad, server_lang, world)) num = read(min=1, max=i) self.account = [ account for account in accounts if account['blocked'] is False ][num - 1] self.username = self.account['name'] self.login_servidor = self.account['server']['language'] self.account_group = self.account['accountGroup'] self.mundo = str(self.account['server']['number']) self.word, self.servidor = [ (srv['name'], srv['language']) for srv in servers if srv['accountGroup'] == self.account_group ][0] config.infoUser = _('Server:{}').format(self.servidor) config.infoUser += _(', World:{}').format(self.word) config.infoUser += _(', Player:{}').format(self.username) banner() self.host = 's{}-{}.ikariam.gameforge.com'.format( self.mundo, self.servidor) self.urlBase = 'https://{}/index.php?'.format(self.host) self.headers = { 'Host': self.host, 'User-Agent': user_agent, 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://{}'.format(self.host), 'X-Requested-With': 'XMLHttpRequest', 'Origin': 'https://{}'.format(self.host), 'DNT': '1', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache' } sessionData = self.getSessionData() used_old_cookies = False # if there are cookies stored, try to use them if 'cookies' in sessionData and self.logged is False: # create a new temporary session object old_s = requests.Session() # set the headers old_s.headers.clear() old_s.headers.update(self.headers) # set the cookies to test cookie_dict = sessionData['cookies'] requests.cookies.cookiejar_from_dict(cookie_dict, cookiejar=old_s.cookies, overwrite=True) self.__update_proxy(obj=old_s, sessionData=sessionData) try: # make a request to check the connection html = old_s.get(self.urlBase, verify=config.do_ssl_verify).text except Exception: self.__proxy_error() cookies_are_valid = self.__isExpired(html) is False if cookies_are_valid: self.__log('using old cookies') used_old_cookies = True # assign the old cookies to the session object requests.cookies.cookiejar_from_dict(cookie_dict, cookiejar=self.s.cookies, overwrite=True) # set the proxy self.__update_proxy(sessionData=sessionData) # set the headers self.s.headers.clear() self.s.headers.update(self.headers) # login as normal and get new cookies if used_old_cookies is False: self.__log('using new cookies') resp = self.s.get( 'https://lobby.ikariam.gameforge.com/api/users/me/loginLink?id={}&server[language]={}&server[number]={}' .format(self.account['id'], self.login_servidor, self.mundo)).text resp = json.loads(resp, strict=False) if 'url' not in resp: if retries > 0: return self.__login(retries - 1) else: msg = 'Login Error: ' + str(resp) if self.padre: print(msg) sys.exit() else: sys.exit(msg) url = resp['url'] match = re.search( r'https://s\d+-\w{2}\.ikariam\.gameforge\.com/index\.php\?', url) if match is None: sys.exit('Error') # set the headers self.s.headers.clear() self.s.headers.update(self.headers) # set the proxy self.__update_proxy(sessionData=sessionData) # use the new cookies instead, invalidate the old ones try: html = self.s.get(url, verify=config.do_ssl_verify).text except Exception: self.__proxy_error() if self.__isInVacation(html): msg = _('The account went into vacation mode') if self.padre: print(msg) else: sendToBot(self, msg) os._exit(0) if self.__isExpired(html): if retries > 0: return self.__login(retries - 1) if self.padre: msg = _('Login error.') print(msg) os._exit(0) raise Exception('Couldn\'t log in') if not used_old_cookies: self.__saveNewCookies() self.logged = True