diff --git a/MultiBot.py b/MultiBot.py index 53549045a6..7e6cf49dec 100644 --- a/MultiBot.py +++ b/MultiBot.py @@ -45,14 +45,14 @@ def getProxy(): if proxyCur >= proxyNum: proxyCur = 0 headers = {'user-agent': 'Niantic App'} - if requests.get('https://pgorelease.nianticlabs.com/plfe/', headers=headers, proxies=proxies).status_code == 200: + if requests.get('https://pgorelease.nianticlabs.com/plfe/', headers=headers, proxies=proxies, timeout=15).status_code == 200: headers = {'user-agent': 'pokemongo/1 CFNetwork/758.5.3 Darwin/15.6.0'} - if requests.get('https://sso.pokemon.com/', headers=headers, proxies=proxies).status_code == 200: + if requests.get('https://sso.pokemon.com/', headers=headers, proxies=proxies, timeout=15).status_code == 200: return proxy else: - Lprint ("Proxy is Banned") + Lprint ("Proxy {} is Banned or offline".format(proxy)) else: - Lprint ("Proxy is Banned") + Lprint ("Proxy {} is Banned or offline".format(proxy)) except Exception as e: Lprint (e) @@ -147,13 +147,37 @@ def MakeConf(CurThread, username, password): stop() except: jsonData.items().append("{u'websocket':,{u'server_url': u'" + MultiBotConfig[u'WebSocket'][u'IP'] + ":" + str(MultiBotConfig[u'WebSocket'][u'Port'] + CurThread) + "u'start_embedded_server': True}") - - - + elif not MultiBotConfig[u'WebSocket'][u'start_embedded_server']: + try: + del jsonData[u'websocket'] + except KeyboardInterrupt: + stop() + except: + pass + if MultiBotConfig[u'TelegramTask']: + try: + for i in range(len(jsonData[u'tasks'])): + if jsonData[u'tasks'][1][u'type'] == u'TelegramTask': + jsonData[u'tasks'][i][u'config'][u'enabled'] = True + except KeyboardInterrupt: + stop() + except: + pass + + if not MultiBotConfig[u'TelegramTask']: + try: + for i in range(len(jsonData[u'tasks'])): + if jsonData[u'tasks'][1][u'type'] == u'TelegramTask': + jsonData[u'tasks'][i][u'config'][u'enabled'] = False + except KeyboardInterrupt: + stop() + except: + pass + with open('configs/temp/config-' + str(CurThread) + '.json', 'w') as s: s.write(json.dumps(jsonData)) s.close() - + except IOError: Lprint ('config file error') time.sleep(30) @@ -181,15 +205,14 @@ def run(self): Lprint ('Thread-{0} using account {1}'.format(self.CurThread, self.username)) try: MakeConf(self.CurThread, self.username, self.password) + StartCmd = "python pokecli.py -af configs/temp/auth-{0}.json -cf configs/temp/config-{0}.json --walker_limit_output {1}".format(self.CurThread, MultiBotConfig[u'walker_limit_output']) if MultiBotConfig[u'UseProxy']: self.proxy = getProxy() if platform.system() == "Linux": - self.os.system('export HTTP_PROXY="http://' + proxy + '"; export HTTPS_PROXY="https://' + proxy + '"') + os.system('export HTTP_PROXY="http://' + proxy + '"; export HTTPS_PROXY="https://' + proxy + '"; ' + StartCmd) if platform.system() == "Windows": - self.os.system('') - os.system( - "python pokecli.py -af configs/temp/auth-{0}.json -cf configs/temp/config-{0}.json --walker_limit_output {1}".format( - self.CurThread, MultiBotConfig[u'walker_limit_output'])) + os.system('set HTTP_PROXY="http://' + proxy + '" & set HTTPS_PROXY="https://' + proxy + '" & ' + StartCmd) + os.system(StartCmd) except Exception as e: import traceback Lprint ((e)) diff --git a/configs/MultiBotConfig.json.example b/configs/MultiBotConfig.json.example index 140818cc72..c395a75593 100644 --- a/configs/MultiBotConfig.json.example +++ b/configs/MultiBotConfig.json.example @@ -1,4 +1,5 @@ { + "Threads": "set it to (account number / 2)", "Threads": 2, "HashKeyFile": "MultiBotConfigHashkey.txt", "UseProxy": false, @@ -6,11 +7,15 @@ "AccountsFile": "MultiBotConfigAccounts.txt", "AuthJsonFile": "auth.json", "ConfigJsonFile": "config.json", + "CompleteTutorialNickName": "set to true to use login as username", "CompleteTutorialNickName": true, + "TelegramTask": "should be false or Telegram maybe crash the bot", + "TelegramTask": false, "WebSocket": { "start_embedded_server": false, "IP": "127.0.0.1", "Port": 4000 }, + "walker_limit_output": "set to true to reduce spam in console", "walker_limit_output": true } diff --git a/data/items.json b/data/items.json index 5e565021cf..5c788e5cc2 100644 --- a/data/items.json +++ b/data/items.json @@ -43,5 +43,5 @@ "1301": "Rare Candy", "1401": "Free Raid Ticket", "1402": "Paid Raid Ticket", - "1403": "Legendart Raid Ticket" + "1403": "Legendary Raid Ticket" } diff --git a/docs/manual_installation.md b/docs/manual_installation.md index c210fa1611..d5461be1cc 100644 --- a/docs/manual_installation.md +++ b/docs/manual_installation.md @@ -55,7 +55,7 @@ rm -f get-pip.py (Please keep in mind that `master` is stable and tested but `dev` is bleeding edge. In the installation note below change `master` to `dev` if you want to get and use the latest version.) ```bash -git clone --recursive -b master https://github.com/PokemonGoF/PokemonGo-Bot +git clone --recursive -b master https://github.com/PokemonGoF/PokemonGo-Bot.git cd PokemonGo-Bot ``` @@ -73,8 +73,6 @@ source bin/activate - install the requirements ```bash pip install -r requirements.txt -make -cd ../../ ``` #### @@ -82,6 +80,7 @@ cd ../../ - copy and edit the config (after copying it you can use any editor you like if you don't like `vi`) ```bash +cd ../PokemonGo-Bot/configs/ cp configs/config.json.example configs/config.json vi configs/config.json cp configs/auth.json.example configs/auth.json @@ -132,7 +131,7 @@ cd C:\Python27\ pip install --upgrade pip cd .. cd to PokemonGo-Bot directory -git clone --recursive -b dev https://github.com/PokemonGoF/PokemonGo-Bot +git clone --recursive -b dev https://github.com/PokemonGoF/PokemonGo-Bot.git pip install --upgrade -r requirements.txt git pull cd web diff --git a/pokecli.py b/pokecli.py index 5efd00ab23..4d8eef1737 100644 --- a/pokecli.py +++ b/pokecli.py @@ -66,7 +66,7 @@ try: import pkg_resources pgoapi_version = pkg_resources.get_distribution("pgoapi").version - if pgoapi_version != '1.2.1': + if pgoapi_version != '2.13.0': print "Run following command to get latest update: `pip install -r requirements.txt --upgrade`" sys.exit(1) except pkg_resources.DistributionNotFound: diff --git a/pokemongo_bot/cell_workers/buddy_pokemon.py b/pokemongo_bot/cell_workers/buddy_pokemon.py index 6d8d108cdd..3cd1d2b394 100644 --- a/pokemongo_bot/cell_workers/buddy_pokemon.py +++ b/pokemongo_bot/cell_workers/buddy_pokemon.py @@ -132,6 +132,9 @@ def work(self): if not self.buddy: return WorkerResult.SUCCESS + if not self.buddy.has_key('last_km_awarded'): + self.buddy['last_km_awarded'] = 0 + if self._km_walked() - self.buddy['last_km_awarded'] >= self.buddy_distance_needed: self.buddy['last_km_awarded'] += self.buddy_distance_needed if not self._get_award(): diff --git a/pokemongo_bot/cell_workers/sniper.py b/pokemongo_bot/cell_workers/sniper.py index 9ad7d168f5..c841aae8e6 100644 --- a/pokemongo_bot/cell_workers/sniper.py +++ b/pokemongo_bot/cell_workers/sniper.py @@ -7,9 +7,6 @@ import calendar import difflib import hashlib - -from geopy.distance import great_circle - from random import uniform from operator import itemgetter, methodcaller from itertools import izip @@ -20,6 +17,7 @@ from pokemongo_bot.worker_result import WorkerResult from pokemongo_bot.event_handlers.telegram_handler import TelegramSnipe from pokemongo_bot.cell_workers.pokemon_catch_worker import PokemonCatchWorker +from pokemongo_bot.cell_workers.utils import wait_time_sec, distance, convert # Represents a URL source and its mappings class SniperSource(object): @@ -361,15 +359,17 @@ def snipe(self, pokemon): # Backup position before anything last_position = self.bot.position[0:2] teleport_position = [pokemon['latitude'], pokemon['longitude']] - teleport_distance = self._get_distance(last_position, teleport_position) - sleep_time = self._get_sleep_sec(teleport_distance) + #teleport_distance = self._get_distance(last_position, teleport_position) + teleport_distance = convert(distance(last_position[0],last_position[1],float(pokemon['latitude']),float(pokemon['longitude'])),"m","km") + #sleep_time = self._get_sleep_sec(teleport_distance) + sleep_time = wait_time_sec(teleport_distance) if sleep_time > 900: success = False exists = False self._log('Sniping distance is more than supported distance, abort sniping') else: - self._log('Base on distance, pausing for {} sec'.format(sleep_time)) + self._log('Base on distance, pausing for {0:.2f} Mins'.format(sleep_time/60)) # Teleport, so that we can see nearby stuff self.bot.hb_locked = True @@ -695,9 +695,3 @@ def _teleport_back_and_catch(self, position_array, pokemon): api_encounter_response = catch_worker.create_encounter_api_call() self._teleport_back(position_array) catch_worker.work(api_encounter_response) - - def _get_distance(self, location_from, location_to): - return great_circle(location_from, location_to).kilometers - - def _get_sleep_sec(self, distance): - return distance * 60 diff --git a/pokemongo_bot/cell_workers/utils.py b/pokemongo_bot/cell_workers/utils.py index 25a8f6a9ce..b3c626b633 100644 --- a/pokemongo_bot/cell_workers/utils.py +++ b/pokemongo_bot/cell_workers/utils.py @@ -67,6 +67,25 @@ def encode(cellid): encoder._VarintEncoder()(output.append, cellid) return ''.join(output) +def wait_time_sec(distance): + if distance <= 1: + return distance*60 + elif distance <= 3: + return (distance/3)*(60*2) + elif distance <= 7: + return (distance/7)*(60*5) + elif distance <= 10: + return (distance/10)*(60*7) + elif distance <= 12: + return (distance/12)*(60*8) + elif distance <= 18: + return (distance/18)*(60*10) + elif distance <= 30: + return (distance/30)*(60*15) + else: + return distance*60 + + def distance(lat1, lon1, lat2, lon2): p = 0.017453292519943295 diff --git a/pokemongo_bot/event_handlers/telegram_handler.py b/pokemongo_bot/event_handlers/telegram_handler.py index 8f661db066..54abb3cb29 100644 --- a/pokemongo_bot/event_handlers/telegram_handler.py +++ b/pokemongo_bot/event_handlers/telegram_handler.py @@ -7,8 +7,14 @@ from telegram.utils import request from chat_handler import ChatHandler from pokemongo_bot.inventory import Pokemons +from pokemongo_bot import inventory +from pokemongo_bot.item_list import Item +from pokemongo_bot.cell_workers.utils import wait_time_sec, distance, convert DEBUG_ON = False +SUCCESS = 1 +ERROR_XP_BOOST_ALREADY_ACTIVE = 3 +ERROR_INCENSE_ALREADY_ACTIVE = 2 class TelegramSnipe(object): ENABLED = False @@ -16,6 +22,7 @@ class TelegramSnipe(object): POKEMON_NAME = '' LATITUDE = float(0) LONGITUDE = float(0) + SNIPE_DISABLED = False class TelegramClass: update_id = None @@ -213,6 +220,24 @@ def request_snipe(self, update, pkm, lat, lng): outMsg = 'Catching pokemon: ' + TelegramSnipe.POKEMON_NAME + ' at Latitude: ' + str(TelegramSnipe.LATITUDE) + ' Longitude: ' + str(TelegramSnipe.LONGITUDE) + '\n' self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="".join(outMsg)) + def request_snipe_time(self, update, lat, lng): + last_position = self.bot.position[0:2] + snipe_distance = convert(distance(last_position[0],last_position[1],float(lat),float(lng)),"m","km") + time_to_snipe = wait_time_sec(snipe_distance)/60 + if time_to_snipe <= 900: + outMsg = "Estimate Time to Snipe: " + "{0:.2f}".format(time_to_snipe) + " Mins. Distance: " + "{0:.2f}".format(snipe_distance) + "KM" + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="".join(outMsg)) + else: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Sniping distance is more than supported distance") + + def request_snipe_disable(self, update, config): + if config.lower() == "true": + TelegramSnipe.SNIPE_DISABLED = True + return True + else: + TelegramSnipe.SNIPE_DISABLED = False + return False + def send_evolved(self, update, num, order): evolved = self.chat_handler.get_evolved(num, order) outMsg = '' @@ -225,6 +250,93 @@ def send_evolved(self, update, num, order): else: self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="No Evolutions Found.\n") + + def request_luckyegg_count(self,update): + lucky_egg = inventory.items().get(Item.ITEM_LUCKY_EGG.value) # @UndefinedVariable + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Lucky Egg Count: " + str(lucky_egg.count)) + + def request_ordincense_count(self,update): + ord_incense = inventory.items().get(Item.ITEM_INCENSE_ORDINARY.value) # @UndefinedVariable + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Ordinary Incense Count: " + str(ord_incense.count)) + + def request_luckyegg(self,update): + lucky_egg = inventory.items().get(Item.ITEM_LUCKY_EGG.value) # @UndefinedVariable + + if lucky_egg.count == 0: + return False + + response_dict = self.bot.use_lucky_egg() + + if not response_dict: + self.bot.logger.info("Telegram Request: Failed to use lucky egg!") + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Failed to use lucky egg!\n") + return False + + result = response_dict.get("responses", {}).get("USE_ITEM_XP_BOOST", {}).get("result", 0) + + if result == SUCCESS: + lucky_egg.remove(1) + self.bot.logger.info("Telegram Request: Used lucky egg, {} left.".format(lucky_egg.count)) + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Used lucky egg, " + str(lucky_egg.count) + " left.") + return True + elif result == ERROR_XP_BOOST_ALREADY_ACTIVE: + self.bot.logger.info("Telegram Request: Lucky egg already active, {} left.".format(lucky_egg.count)) + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Lucky egg already active, " + str(lucky_egg.count) + " left.") + return True + else: + self.bot.logger.info("Telegram Request: Failed to use lucky egg!") + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Failed to use lucky egg!\n") + return False + + def request_ordincense(self,update): + ord_incense = inventory.items().get(Item.ITEM_INCENSE_ORDINARY.value) # @UndefinedVariable + + if ord_incense.count == 0: + return False + + request = self.bot.api.create_request() + request.use_incense(incense_type=401) + response_dict = request.call() + + if not response_dict: + self.bot.logger.info("Telegram Request: Failed to use ordinary incense!") + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Failed to use ordinary incense!\n") + return False + + result = response_dict.get('responses', {}).get('USE_INCENSE', {}).get('result', 0) + + self.bot.logger.info("Result = " + str(result)) + + if result == SUCCESS: + ord_incense.remove(1) + self.bot.logger.info("Telegram Request: Used ordinary incense, {} left.".format(ord_incense.count)) + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Used ordinary incense, " + str(ord_incense.count) + " left.") + return True + elif result == ERROR_INCENSE_ALREADY_ACTIVE: + self.bot.logger.info("Telegram Request: Ordinary incense already active, {} left.".format(ord_incense.count)) + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Ordinary incense already active, " + str(ord_incense.count) + " left and has " + str(currentincense.expire_ms) + " remaining") + return True + else: + self.bot.logger.info("Telegram Request: Failed to use ordinary incense! Result=" + str(result)) + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="Failed to use ordinary incense!\n") + return False + + def request_incensetime(self, update): + self.bot.logger.info("Time Started") + currentincense = inventory.applied_items().get('401') + self.bot.logger.info(currentincense) + #self.bot.logger.info(currentincense.expire_ms) + return True def send_pokestops(self, update, num): pokestops = self.chat_handler.get_pokestops( num) @@ -329,6 +441,11 @@ def send_start(self, update): "/released - show top x released, sorted by CP, IV, or Date", "/vanished - show top x vanished, sorted by CP, IV, or Date", "/snipe - to snipe a pokemon at location Latitude, Longitude", + "/snipetime - return time that will be teaken to snipe at given location", + "/luckyegg - activate luckyegg", + "/luckyeggcount - return number of luckyegg", + "/ordincense - activate ordinary incense", + "/ordincensecount - return number of ordinary incense", "/softbans - info about possible softbans" ) self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', @@ -466,6 +583,74 @@ def run(self): self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="An Error has occured") continue + if re.match(r'^/snipetime ', update.message.text): + try: + (cmd, lat, lng) = self.tokenize(update.message.text, 3) + self.request_snipe_time(update, lat, lng) + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + + if re.match(r'^/luckyeggcount', update.message.text): + try: + self.request_luckyegg_count(update) + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + if re.match(r'^/luckyegg', update.message.text): + try: + if self.request_luckyegg(update): + self.bot.logger.info("Telegram has called for lucky egg. Success.") + else: + self.bot.logger.info("Telegram has called for lucky egg. Failed.") + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + if re.match(r'^/ordincensecount', update.message.text): + try: + self.request_ordincense_count(update) + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + if re.match(r'^/ordincense', update.message.text): + try: + if self.request_ordincense(update): + self.bot.logger.info("Telegram has called for ordinary incense. Success.") + else: + self.bot.logger.info("Telegram has called for ordinary incense. Failed.") + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + if re.match(r'^/itime', update.message.text): + try: + if self.request_incensetime(update): + self.bot.logger.info("Telegram has called for incense time. Success.") + else: + self.bot.logger.info("Telegram has called for incense time. Failed.") + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue + if re.match(r'^/snipedisabled ', update.message.text): + try: + (cmd, config) = self.tokenize(update.message.text, 2) + success = self.request_snipe_disable(update, config) + if success: + msg = "Sniper disabled" + else: + msg = "Sniper set as default" + + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text=msg) + except: + self.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', + text="An Error has occured") + continue if re.match(r'^/softbans ', update.message.text): (cmd, num) = self.tokenize(update.message.text, 2) self.send_softbans(update, num) diff --git a/run.sh b/run.sh index 8eefcb9700..3907d5a9b2 100755 --- a/run.sh +++ b/run.sh @@ -22,7 +22,7 @@ then fi git fetch -a installed=(`pip list 2>/dev/null |sed -e 's/ //g' -e 's/(/:/' -e 's/)//' -e 's/[-_]//g' | awk '{print tolower($0)}'`) -required=(`cat requirements.txt | sed -e 's/.*pgoapi$/pgoapi==1.2.1/' -e 's/[-_]//g' -e 's/==\(.*\)/:\1/' | awk '{print tolower($0)}'`) +required=(`cat requirements.txt | sed -e 's/.*pgoapi$/pgoapi==2.13.0/' -e 's/[-_]//g' -e 's/==\(.*\)/:\1/' | awk '{print tolower($0)}'`) for package in ${required[@]} do if [[ ! (${installed[*]} =~ $package) ]]; diff --git a/runMultiBot.sh b/runMultiBot.sh old mode 100644 new mode 100755 index 2f8bc98fed..847c5a7f89 --- a/runMultiBot.sh +++ b/runMultiBot.sh @@ -10,7 +10,7 @@ then fi git fetch -a installed=(`pip list 2>/dev/null |sed -e 's/ //g' -e 's/(/:/' -e 's/)//' -e 's/[-_]//g' | awk '{print tolower($0)}'`) -required=(`cat requirements.txt | sed -e 's/.*pgoapi$/pgoapi==1.2.0/' -e 's/[-_]//g' -e 's/==\(.*\)/:\1/' | awk '{print tolower($0)}'`) +required=(`cat requirements.txt | sed -e 's/.*pgoapi$/pgoapi==2.13.0/' -e 's/[-_]//g' -e 's/==\(.*\)/:\1/' | awk '{print tolower($0)}'`) for package in ${required[@]} do if [[ ! (${installed[*]} =~ $package) ]]; @@ -31,5 +31,4 @@ then fi fi python MultiBot.py -done exit 0 diff --git a/setup.sh b/setup.sh index 869d1b45e8..830dd08b6c 100755 --- a/setup.sh +++ b/setup.sh @@ -75,9 +75,12 @@ Configure userdata.js for web " read -p "Input E-Mail (Google) or Username (PTC) " webusername +read -p "Input Friendly Name For Your Bot (Name you want bot to show up as on the map) +" webfriendlyname read -p "Input Google API Key (gmapkey) " webgmapkey sed -e "s/username1/$webusername/g" -e "s/YOUR_API_KEY_HERE/$webgmapkey/g" \ + -e "s/FriendlyName1/$webfriendlyname/g" \ config/userdata.js.example > config/userdata.js echo "Your userdata.js is now configured." else diff --git a/web b/web index acbf10115e..8c5a43a57e 160000 --- a/web +++ b/web @@ -1 +1 @@ -Subproject commit acbf10115e401edd6f276005bd362795da6b60bf +Subproject commit 8c5a43a57e3e703853cade50f1cda1f06ce31fc7 diff --git a/windows_bat/PokemonGo-Bot-Configurator.bat b/windows_bat/PokemonGo-Bot-Configurator.bat index 66192e493d..50eacd1f9d 100644 --- a/windows_bat/PokemonGo-Bot-Configurator.bat +++ b/windows_bat/PokemonGo-Bot-Configurator.bat @@ -205,6 +205,8 @@ ECHO. users: [{>>%UserData% ECHO. enable: true,>>%UserData% Set /p users="What's the username to use ?: " ECHO. username: "%users%",>>%UserData% +Set /p friendlyname="What's the friendly/display name to use ?: " +ECHO. alias: "%friendlyname%",>>%UserData% ECHO. socketAddress: "127.0.0.1:4000",>>%UserData% ECHO. enableSocket: true>>%UserData% ECHO. }],>>%UserData%