From 6c9f865a580fed226e524529eae4236ca35bcc0d Mon Sep 17 00:00:00 2001 From: Stuart Travers Date: Sun, 28 Aug 2016 16:55:35 +1000 Subject: [PATCH 01/15] Expand simple logging options (#4832) * Fix bot crash at start on permaban * Expanded logging options Added "logging" section to config, with options "color", "show_datetime", "show_process_name" and "show_log_level" * Added warning about deprecated logging_color arg * Display log message moved No point trying to use the logger before it's been initialised. Moved to init_config. * Remove milliseconds from datetime Because really, do we need that? * Reversed condition order for clarity First check: "if not in config", OR Second check: "is in config AND set to true" If either condition matches, the logging detail will be displayed. * Documented new log options * Modified conditions again Removed unnecessary second check for config values and slightly modified parentheses as per suggestion from @mjmadsen --- configs/config.json.cluster.example | 10 ++++++---- configs/config.json.example | 10 ++++++---- configs/config.json.map.example | 10 ++++++---- configs/config.json.optimizer.example | 10 ++++++---- configs/config.json.path.example | 10 ++++++---- configs/config.json.pokemon.example | 10 ++++++---- docs/configuration_files.md | 8 ++++++++ pokecli.py | 8 ++++++-- pokemongo_bot/__init__.py | 17 ++++++++++++++--- 9 files changed, 64 insertions(+), 29 deletions(-) diff --git a/configs/config.json.cluster.example b/configs/config.json.cluster.example index 5e63052f69..ed7d9e6508 100644 --- a/configs/config.json.cluster.example +++ b/configs/config.json.cluster.example @@ -228,10 +228,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"}, "// Example of always catching Rattata:": {}, diff --git a/configs/config.json.example b/configs/config.json.example index e11dedd587..634ab60b13 100644 --- a/configs/config.json.example +++ b/configs/config.json.example @@ -266,10 +266,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": {"candy_threshold" : 400 ,"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"}, "// Example of always catching Rattata:": {}, diff --git a/configs/config.json.map.example b/configs/config.json.map.example index d675f18998..ea85fe44ed 100644 --- a/configs/config.json.map.example +++ b/configs/config.json.map.example @@ -485,10 +485,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"}, "// Example of always catching Rattata:": {}, diff --git a/configs/config.json.optimizer.example b/configs/config.json.optimizer.example index 70acc217f8..0f1da751d3 100644 --- a/configs/config.json.optimizer.example +++ b/configs/config.json.optimizer.example @@ -298,10 +298,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": { "always_catch": true diff --git a/configs/config.json.path.example b/configs/config.json.path.example index 9610fed2b5..2e053d6d8d 100644 --- a/configs/config.json.path.example +++ b/configs/config.json.path.example @@ -234,10 +234,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"}, "// Example of always catching Rattata:": {}, diff --git a/configs/config.json.pokemon.example b/configs/config.json.pokemon.example index 5592ab14f8..37d3cf98e7 100644 --- a/configs/config.json.pokemon.example +++ b/configs/config.json.pokemon.example @@ -238,10 +238,12 @@ "location_cache": true, "distance_unit": "km", "reconnecting_timeout": 15, - "logging": { - "color": true, - "clean": false - }, + "logging": { + "color": true, + "show_datetime": true, + "show_process_name": true, + "show_log_level": true + }, "catch": { "any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or" }, diff --git a/docs/configuration_files.md b/docs/configuration_files.md index ef47e7d07d..072b4b429d 100644 --- a/docs/configuration_files.md +++ b/docs/configuration_files.md @@ -87,6 +87,14 @@ Document the configuration options of PokemonGo-Bot. | `live_config_update.tasks_only` | false | True: quick update for Tasks only (without re-login). False: slower update for entire config file. +## Logging configuration +[[back to top](#table-of-contents)] + +'logging'.'color' (default false) Enabled colored logging +'logging'.'show_datetime' (default true) Show date and time in log +'logging'.'show_process_name' (default true) Show name of process generating output in log +'logging'.'show_log_level' (default true) Show level of log message in log (eg. "INFO") + ## Configuring Tasks [[back to top](#table-of-contents)] diff --git a/pokecli.py b/pokecli.py index d82320a3b4..6598efca34 100644 --- a/pokecli.py +++ b/pokecli.py @@ -632,7 +632,7 @@ def _json_loader(filename): type=bool, default=False ) - + # Start to parse other attrs config = parser.parse_args() if not config.username and 'username' not in load: @@ -652,6 +652,7 @@ def _json_loader(filename): config.live_config_update = load.get('live_config_update', {}) config.live_config_update_enabled = config.live_config_update.get('enabled', False) config.live_config_update_tasks_only = config.live_config_update.get('tasks_only', False) + config.logging = load.get('logging', {}) if config.map_object_cache_time < 0.0: parser.error("--map_object_cache_time is out of range! (should be >= 0.0)") @@ -696,7 +697,10 @@ def task_configuration_error(flag_name): if "daily_catch_limit" in load: logger.warning('The daily_catch_limit argument has been moved into the CatchPokemon Task') - + + if "logging_color" in load: + logger.warning('The logging_color argument has been moved into the logging config section') + if config.walk_min < 1: parser.error("--walk_min is out of range! (should be >= 1.0)") return None diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index d98520af94..6891da550e 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -132,7 +132,7 @@ def start(self): def _setup_event_system(self): handlers = [] - if self.config.logging_color: + if self.config.logging and 'color' in self.config.logging and self.config.logging['color']: handlers.append(ColoredLoggingHandler(self)) else: handlers.append(LoggingHandler(self)) @@ -760,8 +760,19 @@ def _setup_logging(self): logging.getLogger("pgoapi").setLevel(log_level) logging.getLogger("rpc_api").setLevel(log_level) - if self.config.logging_clean and not self.config.debug: - formatter = Formatter(fmt='[%(asctime)s] %(message)s', datefmt='%H:%M:%S') + if self.config.logging: + logging_format = '%(message)s' + logging_format_options = '' + + if ('show_log_level' not in self.config.logging) or self.config.logging['show_log_level']: + logging_format = '[%(levelname)s] ' + logging_format + if ('show_process_name' not in self.config.logging) or self.config.logging['show_process_name']: + logging_format = '[%(name)10s] ' + logging_format + if ('show_datetime' not in self.config.logging) or self.config.logging['show_datetime']: + logging_format = '[%(asctime)s] ' + logging_format + logging_format_options = '%Y-%m-%d %H:%M:%S' + + formatter = Formatter(logging_format,logging_format_options) for handler in logging.root.handlers[:]: handler.setFormatter(formatter) From 2832a3702a9c433b819e172fbe5b3fb297d20a7b Mon Sep 17 00:00:00 2001 From: LuckyMe4Evers Date: Sun, 28 Aug 2016 10:50:04 +0200 Subject: [PATCH 02/15] Changed ) to } (#4845) Fixed an faulty character --- windows_bat/PokemonGo-Bot-Configurator.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows_bat/PokemonGo-Bot-Configurator.bat b/windows_bat/PokemonGo-Bot-Configurator.bat index 29e12abc85..aff0acacb9 100644 --- a/windows_bat/PokemonGo-Bot-Configurator.bat +++ b/windows_bat/PokemonGo-Bot-Configurator.bat @@ -143,7 +143,7 @@ ECHO. ECHO. "encrypt_location": "",>>%auth% SET /p telegram="What's your telegram token? Enter for leave blank: " ECHO. "telegram_token": "%telegram%">>%auth% -ECHO.)>>%auth% +ECHO.}>>%auth% goto :eof From d896a806fc53474a12e962118154b98bb16d3337 Mon Sep 17 00:00:00 2001 From: Ingwar Wirjawan Date: Sun, 28 Aug 2016 16:36:49 +0700 Subject: [PATCH 03/15] fix incubator logic (#4848) --- pokemongo_bot/cell_workers/incubate_eggs.py | 76 ++++++++++----------- pokemongo_bot/test/incubate_eggs_test.py | 58 ++++++++++++++++ web | 2 +- 3 files changed, 94 insertions(+), 42 deletions(-) create mode 100644 pokemongo_bot/test/incubate_eggs_test.py diff --git a/pokemongo_bot/cell_workers/incubate_eggs.py b/pokemongo_bot/cell_workers/incubate_eggs.py index 76f9885018..10121c36cd 100644 --- a/pokemongo_bot/cell_workers/incubate_eggs.py +++ b/pokemongo_bot/cell_workers/incubate_eggs.py @@ -11,8 +11,8 @@ class IncubateEggs(BaseTask): def initialize(self): self.next_update = None - self.ready_incubators_breakable = [] - self.ready_incubators_infinite = [] + self.ready_breakable_incubators = [] + self.ready_infinite_incubators = [] self.used_incubators = [] self.eggs = [] self.km_walked = 0 @@ -49,39 +49,33 @@ def work(self): IncubateEggs.last_km_walked = self.km_walked - sorting = self.breakable_longer_eggs_first - self.eggs.sort(key=lambda x: x.get("km"), reverse=sorting) - if self.ready_incubators_breakable: - self._apply_incubators('breakable') + # if there is a ready infinite incubator + if self.ready_infinite_incubators: + # get available eggs + eggs = self._filter_sort_eggs(self.infinite_incubator, + self.infinite_longer_eggs_first) + self._apply_incubators(eggs, self.ready_infinite_incubators) - sorting = self.infinite_longer_eggs_first - self.eggs.sort(key=lambda x: x.get("km"), reverse=sorting) - if self.ready_incubators_infinite: - self._apply_incubators('infinite') + if self.ready_breakable_incubators: + # get available eggs + eggs = self._filter_sort_eggs(self.infinite_incubator, + self.infinite_longer_eggs_first) + self._apply_incubators(eggs, self.ready_infinite_incubators) - def _apply_incubators(self, type_of_incubator): - if type_of_incubator == 'breakable': - temp_ready_incubators = self.ready_incubators_breakable - elif type_of_incubator == 'infinite': - temp_ready_incubators = self.ready_incubators_infinite - - for incubator in temp_ready_incubators: - if incubator.get('used', False): - continue - for egg in self.eggs: - if egg["used"] or egg["km"] == -1: - continue - km = int(egg["km"]) + def _filter_sort_eggs(self, allowed, sorting): + eligible_eggs = filter(lambda egg: int(egg["km"]) in allowed, self.eggs) + eligible_eggs.sort(key=lambda egg: egg["km"], reverse=sorting) - # test if the incubator is of type breakable - if incubator.get('uses_remaining') is not None: - if km not in self.breakable_incubator: - continue - # test if the incubator is of type infinite - else: - if km not in self.infinite_incubator: - continue + return eligible_eggs + + + def _apply_incubators(self, available_eggs, available_incubators): + + for incubator in available_incubators: + for egg in available_eggs: + if egg["used"] or egg["km"] == -1: + continue self.emit_event( 'incubate_try', @@ -131,8 +125,8 @@ def _check_inventory(self, lookup_ids=[]): matched_pokemon = [] temp_eggs = [] temp_used_incubators = [] - temp_ready_incubators_breakable = [] - temp_ready_incubators_infinite = [] + temp_ready_breakable_incubators = [] + temp_ready_infinite_incubators = [] inv = reduce( dict.__getitem__, ["responses", "GET_INVENTORY", "inventory_delta", "inventory_items"], @@ -142,8 +136,8 @@ def _check_inventory(self, lookup_ids=[]): inv_data = inv_data.get("inventory_item_data", {}) if "egg_incubators" in inv_data: temp_used_incubators = [] - temp_ready_incubators_breakable = [] - temp_ready_incubators_infinite = [] + temp_ready_breakable_incubators = [] + temp_ready_infinite_incubators = [] incubators = inv_data.get("egg_incubators", {}).get("egg_incubator",[]) if isinstance(incubators, basestring): # checking for old response incubators = [incubators] @@ -158,11 +152,11 @@ def _check_inventory(self, lookup_ids=[]): }) else: if incubator.get('uses_remaining') is not None: - temp_ready_incubators_breakable.append({ + temp_ready_breakable_incubators.append({ "id": incubator.get('id', -1) }) else: - temp_ready_incubators_infinite.append({ + temp_ready_infinite_incubators.append({ "id": incubator.get('id', -1) }) continue @@ -187,10 +181,10 @@ def _check_inventory(self, lookup_ids=[]): self.km_walked = inv_data.get("player_stats", {}).get("km_walked", 0) if temp_used_incubators: self.used_incubators = temp_used_incubators - if temp_ready_incubators_breakable: - self.ready_incubators_breakable = temp_ready_incubators_breakable - if temp_ready_incubators_infinite: - self.ready_incubators_infinite = temp_ready_incubators_infinite + if temp_ready_breakable_incubators: + self.ready_breakable_incubators = temp_ready_breakable_incubators + if temp_ready_infinite_incubators: + self.ready_infinite_incubators = temp_ready_infinite_incubators if temp_eggs: self.eggs = temp_eggs return matched_pokemon diff --git a/pokemongo_bot/test/incubate_eggs_test.py b/pokemongo_bot/test/incubate_eggs_test.py new file mode 100644 index 0000000000..1a0099c6e2 --- /dev/null +++ b/pokemongo_bot/test/incubate_eggs_test.py @@ -0,0 +1,58 @@ +import unittest +from mock import patch +from pokemongo_bot.cell_workers.incubate_eggs import IncubateEggs + + +class IncubateEggsTestCase(unittest.TestCase): + + @patch('pokemongo_bot.PokemonGoBot') + def testFilterAndSort_AllowNone(self, mock_pokemongo_bot): + incubate_eggs = IncubateEggs(mock_pokemongo_bot, {}) + + incubate_eggs.eggs = [{"km": 2.0}, {"km": 5.0}, {"km": 5.0}] + + allowed = [] + sorting = True + + result = incubate_eggs._filter_sort_eggs(allowed, sorting) + self.assertEqual([], result) + + + @patch('pokemongo_bot.PokemonGoBot') + def testFilterAndSort_AllowSome(self, mock_pokemongo_bot): + incubate_eggs = IncubateEggs(mock_pokemongo_bot, {}) + + incubate_eggs.eggs = [{"km": 5.0}, {"km": 2.0}, {"km": 5.0}, {"km": 10.0}] + + allowed = [2, 10] + sorting = True + + result = incubate_eggs._filter_sort_eggs(allowed, sorting) + self.assertEqual([{"km": 10.0}, {"km": 2.0}], result) + + + @patch('pokemongo_bot.PokemonGoBot') + def testFilterAndSort_AllowSomeNoReverseSort(self, mock_pokemongo_bot): + incubate_eggs = IncubateEggs(mock_pokemongo_bot, {}) + + incubate_eggs.eggs = [{"km": 5.0}, {"km": 2.0}, {"km": 5.0}, {"km": 10.0}] + + allowed = [2, 10] + sorting = False + + result = incubate_eggs._filter_sort_eggs(allowed, sorting) + self.assertEqual([{"km": 2.0}, {"km": 10.0}], result) + + + + @patch('pokemongo_bot.PokemonGoBot') + def testFilterAndSort_AllowAll(self, mock_pokemongo_bot): + incubate_eggs = IncubateEggs(mock_pokemongo_bot, {}) + + incubate_eggs.eggs = [{"km": 5.0}, {"km": 2.0}, {"km": 5.0}] + + allowed = [2, 5, 10] + sorting = True + + result = incubate_eggs._filter_sort_eggs(allowed, sorting) + self.assertEqual([{"km": 5.0}, {"km": 5.0}, {"km": 2.0}], result) diff --git a/web b/web index 607397a13f..6ba5609c61 160000 --- a/web +++ b/web @@ -1 +1 @@ -Subproject commit 607397a13f344c0fdc44bd9961332c1efe205de9 +Subproject commit 6ba5609c6151507b5b832a74e471b6b7b1a182c9 From af985e8fa9984d521d53f1c9d61f589ab783429f Mon Sep 17 00:00:00 2001 From: Dmitri Barski Date: Sun, 28 Aug 2016 13:18:12 +0200 Subject: [PATCH 04/15] corrected logic to respect snipe = true --- pokemongo_bot/cell_workers/move_to_map_pokemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index a18a77545d..9b57c99109 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -144,7 +144,7 @@ def get_pokemon_from_social(self): pokemon['longitude'], ) - if pokemon['dist'] > self.config['max_distance'] or not self.config['snipe']: + if pokemon['dist'] > self.config['max_distance'] and not self.config['snipe']: continue # pokemon not reachable with mean walking speed (by config) From 6acdc534bbb605dc1e392b10f4ec2b2c941bb75b Mon Sep 17 00:00:00 2001 From: Alexander Skovpen Date: Sun, 28 Aug 2016 15:25:05 +0400 Subject: [PATCH 05/15] Update configuration_files.md (#4854) --- docs/configuration_files.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/configuration_files.md b/docs/configuration_files.md index 072b4b429d..0c98209ca4 100644 --- a/docs/configuration_files.md +++ b/docs/configuration_files.md @@ -46,6 +46,7 @@ - [Random Pause](#random-pause) - [Egg Incubator](#egg-incubator) - [ShowBestPokemon](#showbestpokemon) +- [Telegram Task](#telegram-task) #Configuration files @@ -912,3 +913,34 @@ Available `info_to_show` : ``` 2016-08-25 21:20:59,642 [ShowBestPokemon] [INFO] [show_best_pokemon] [Tauros, CP 575, IVCP 0.95, DPS 12.04] | [Grimer, CP 613, IVCP 0.93, DPS 13.93] | [Tangela, CP 736, IVCP 0.93, DPS 14.5] | [Staryu, CP 316, IVCP 0.92, DPS 10.75] | [Gastly, CP 224, IVCP 0.9, DPS 11.7] ``` + +## Telegram Task +[[back to top](#table-of-contents)] + +### Description +[[back to top](#table-of-contents)] + +[Telegram bot](https://telegram.org/) Announcer Level up, pokemon cought + +Bot answer on command '/info' self stats. + +### Options + +* `telegram_token` : bot token (getting [there](https://core.telegram.org/bots#6-botfather) - one token per bot) +* `master` : id (without quotes) or username (in quotes, first character @) of bot owner, who will gett announces. +* `alert_catch` : array of pokemons, which will be announced on catch. if first array item `all` - announce all pokemons. + +### Sample configuration +[[back to top](#table-of-contents)] +```json +{ + "type": "TelegramTask", + "config": { + "enabled": true, + "master": 12345678, + "//master": "@username", + "alert_catch": ["Lapras","Dragonite"], + "//alert_catch": ["all"] + } +} +``` From 5a1e24672df12764e06de9627fb0dbb159044925 Mon Sep 17 00:00:00 2001 From: DBa2016 Date: Sun, 28 Aug 2016 14:15:34 +0200 Subject: [PATCH 06/15] corrected logic to respect snipe = true (#4855) --- pokemongo_bot/cell_workers/move_to_map_pokemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index a18a77545d..9b57c99109 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -144,7 +144,7 @@ def get_pokemon_from_social(self): pokemon['longitude'], ) - if pokemon['dist'] > self.config['max_distance'] or not self.config['snipe']: + if pokemon['dist'] > self.config['max_distance'] and not self.config['snipe']: continue # pokemon not reachable with mean walking speed (by config) From 4dd28e345b36ff897fa453e8d62fd39714ade1c1 Mon Sep 17 00:00:00 2001 From: Matt J Madsen Date: Sun, 28 Aug 2016 08:32:56 -0500 Subject: [PATCH 07/15] Revert "corrected logic to respect snipe = true" (#4857) --- pokemongo_bot/cell_workers/move_to_map_pokemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index 9b57c99109..a18a77545d 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -144,7 +144,7 @@ def get_pokemon_from_social(self): pokemon['longitude'], ) - if pokemon['dist'] > self.config['max_distance'] and not self.config['snipe']: + if pokemon['dist'] > self.config['max_distance'] or not self.config['snipe']: continue # pokemon not reachable with mean walking speed (by config) From f1fe9421ac3da4d22096a723ff1df5cd8e807582 Mon Sep 17 00:00:00 2001 From: nivong Date: Sun, 28 Aug 2016 15:39:16 +0200 Subject: [PATCH 08/15] dont forget to update the docs when adding config changes... (#4856) * dont forget to update the docs when adding config changes... * reflect config changes.... --- docs/configuration_files.md | 2 +- docs/manual_installation.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/configuration_files.md b/docs/configuration_files.md index 0c98209ca4..1068ab8d57 100644 --- a/docs/configuration_files.md +++ b/docs/configuration_files.md @@ -86,7 +86,7 @@ Document the configuration options of PokemonGo-Bot. |`favorite_locations` | [] | Allows you to define a collection of locations and coordinates, allowing rapid switch using a "label" on your location config | `live_config_update.enabled` | false | Enable live config update | `live_config_update.tasks_only` | false | True: quick update for Tasks only (without re-login). False: slower update for entire config file. - +| `enable_social` | true | True: to chat with other pokemon go bot users [more information](https://github.com/PokemonGoF/PokemonGo-Bot/pull/4596) ## Logging configuration [[back to top](#table-of-contents)] diff --git a/docs/manual_installation.md b/docs/manual_installation.md index ceaba14ab9..cfeec61bc2 100644 --- a/docs/manual_installation.md +++ b/docs/manual_installation.md @@ -67,6 +67,8 @@ mv pgoencrypt/src/libencrypt.so encrypt.so ```bash cp configs/config.json.example configs/config.json vi configs/config.json +cp configs/auth.json.example configs/auth.json +vi configs/auth.json ``` #### - make shure your git repo is up to date @@ -78,7 +80,7 @@ pip install -r requirements.txt #### - finaly start the bot ```bash -./run.sh configs/config.json +./run.sh ``` #### - after reboot or closing the terminal at every new start go into the folder of the PokemonGo-Bot by going into the folder where you startet installing it an then @@ -86,7 +88,7 @@ pip install -r requirements.txt cd PokemonGo-Bot #activate virtualenv and start source bin/activate -./run.sh configs/config.json +./run.sh ``` From f6775cc9645481baffb377ac746064e7cdb18f54 Mon Sep 17 00:00:00 2001 From: nivong Date: Sun, 28 Aug 2016 16:02:55 +0200 Subject: [PATCH 09/15] please keep this as is (#4859) Add stuff in the right order. --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2e4bb63f80..a64e5774ea 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,23 @@ # PokemonGo-Bot PokemonGo bot is a project created by the [PokemonGoF](https://github.com/PokemonGoF) team. +## Table of Contents +- [Installation](https://github.com/PokemonGoF/PokemonGo-Bot/blob/dev/docs/installation.md) +- [Documentation](https://github.com/PokemonGoF/PokemonGo-Bot/blob/dev/docs/) +- [Support](#support) + - [help](#configuration-issueshelp) + - [bugs](#bugs--issues) + - [Feature request](#feature-requests) + - [Pull Requests](#pull-requests) +- [Features](#features) +- [Credits](#credits) + The project is currently setup in two main branches. - `dev` also known as `beta` - This is where the latest features are, but you may also experience some issues with stability/crashes - `master` also known as `stable` - The bot 'should' be stable on this branch, and is generally well tested -## [Desktop version](https://github.com/PokemonGoF/PokemonGo-Bot-Desktop) - ## Support -###Configuration issues/help +### Configuration issues/help If you need any help please don't create an issue as we have a great community on Slack. You can count on the community in [#help](https://pokemongo-bot.slack.com/messages/help/) channel. - [Click here to signup (first time only)](https://pokemongo-bot.herokuapp.com) - [Join if you're already a member](https://pokemongo-bot.slack.com/messages/general/). @@ -23,12 +32,6 @@ While you're there vote on other feature requests to let the devs know what is m ###[Pull Requests](https://github.com/PokemonGoF/PokemonGo-Bot/pulls) If you'd like to make your own changes, make sure you follow the pull request template, and ensure your PR is made against the 'dev' branch -## Table of Contents -- [Installation](https://github.com/PokemonGoF/PokemonGo-Bot/blob/dev/docs/installation.md) -- [Documentation](https://github.com/PokemonGoF/PokemonGo-Bot/blob/dev/docs/) -- [Features](#features) -- [Credits](#credits) - ## Features - [x] GPS Location configuration - [x] Search Pokestops From 1b90f3fad4023a6dd0466c350ebd9c92bd355919 Mon Sep 17 00:00:00 2001 From: Jasperrr91 Date: Sun, 28 Aug 2016 17:06:54 +0200 Subject: [PATCH 10/15] Clarify Max_distance for Sniping (#4858) * Clarify Max_distance * Added distance unit and updated configuration_files.md --- configs/config.json.map.example | 1 + docs/configuration_files.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/config.json.map.example b/configs/config.json.map.example index ea85fe44ed..ee0d99834a 100644 --- a/configs/config.json.map.example +++ b/configs/config.json.map.example @@ -180,6 +180,7 @@ "config": { "enabled": true, "address": "http://localhost:5000", + "//NOTE: Change the max_distance to adjust the max sniping range (km)": {}, "max_distance": 500, "min_ball": 50, "prioritize_vips": true, diff --git a/docs/configuration_files.md b/docs/configuration_files.md index 1068ab8d57..d56b213235 100644 --- a/docs/configuration_files.md +++ b/docs/configuration_files.md @@ -551,7 +551,7 @@ This task will fetch current pokemon spawns from /raw_data of an PokemonGo-Map i * `prioritize_vips` - Will prioritize vips in distance and priority mode above all normal pokemon if set to true * `min_time` - Minimum time the pokemon has to be available before despawn * `min_ball` - Minimum amount of balls required to run task -* `max_distance` - Maximum distance the pokemon is allowed to be when walking, ignored when sniping +* `max_distance` - Maximum distance the pokemon is allowed to be when sniping. (km) * `snipe`: - `True` - Will teleport to target pokemon, encounter it, teleport back then catch it - `False` - Will walk normally to the pokemon @@ -573,6 +573,7 @@ This task will fetch current pokemon spawns from /raw_data of an PokemonGo-Map i "type": "MoveToMapPokemon", "config": { "address": "http://localhost:5000", + "//NOTE: Change the max_distance to adjust the max sniping range (km)": {}, "max_distance": 500, "min_time": 60, "min_ball": 50, From a01f4dd02ba4008d04486de338bd315196a73d37 Mon Sep 17 00:00:00 2001 From: DBa2016 Date: Sun, 28 Aug 2016 18:18:16 +0200 Subject: [PATCH 11/15] - debug improvements for MoveToMap (#4860) - fix for Telegram to accept "@username" as "master", too, along with numeric IDs --- pokemongo_bot/__init__.py | 8 ++++++ .../cell_workers/move_to_map_pokemon.py | 25 ++++++++++++++----- pokemongo_bot/cell_workers/telegram_task.py | 17 ++++++++++++- .../event_handlers/telegram_handler.py | 17 ++++++++++--- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 6891da550e..5d9a945628 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -183,6 +183,8 @@ def _register_events(self): self.event_manager.register_event('set_start_location') self.event_manager.register_event('load_cached_location') self.event_manager.register_event('location_cache_ignored') + + self.event_manager.register_event('debug') # ignore candy above threshold self.event_manager.register_event( @@ -592,6 +594,12 @@ def _register_events(self): 'moving_to_pokemon_throught_fort', parameters=('fort_name', 'distance','poke_name','poke_dist') ) + self.event_manager.register_event( + 'move_to_map_pokemon', + parameters=('message') + ) + + # cached recent_forts self.event_manager.register_event('loaded_cached_forts') diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index a18a77545d..1003f781e0 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -3,6 +3,11 @@ Moves a trainer to a Pokemon. Events: + move_to_map_pokemon + When a generic message is logged + Returns: + message: Log message. + move_to_map_pokemon_fail When the worker fails. Returns: @@ -83,7 +88,7 @@ SNIPE_MAX_IN_CHAIN = 2 # Don't call sniper every time in workers -SNIPE_SKIP_IN_ROUND = 30 +SNIPE_SKIP_IN_ROUND = 5 DEBUG_ON = False @@ -130,7 +135,13 @@ def get_pokemon_from_social(self): pokemon['is_vip'] = pokemon['name'] in self.bot.config.vips if pokemon['name'] not in self.config['catch']: + if DEBUG_ON: + self._emit_failure("Not catching {}".format(pokemon['name'])) continue + else: + if DEBUG_ON: + self._emit_log("Catching {}".format(pokemon['name'])) + if self.was_caught(pokemon): continue @@ -144,7 +155,7 @@ def get_pokemon_from_social(self): pokemon['longitude'], ) - if pokemon['dist'] > self.config['max_distance'] or not self.config['snipe']: + if pokemon['dist'] > self.config['max_distance'] and not self.config['snipe']: continue # pokemon not reachable with mean walking speed (by config) @@ -300,7 +311,7 @@ def work(self): if (pokeballs_quantity + superballs_quantity + ultraballs_quantity) < self.min_ball: if DEBUG_ON: - print 'no enough balls' + self._emit_log("Not enough balls to start sniping (have {}, {} needed)".format(pokeballs_quantity + superballs_quantity + ultraballs_quantity, self.min_ball)) return WorkerResult.SUCCESS self.dump_caught_pokemon() @@ -308,6 +319,8 @@ def work(self): if self.config['snipe']: self.by_pass_times = self.by_pass_times + 1 if self.by_pass_times < SNIPE_SKIP_IN_ROUND: + if DEBUG_ON: + self._emit_log("Skipping pass {}".format(self.by_pass_times)) return WorkerResult.SUCCESS self.by_pass_times = 0 pokemon_list = self.get_pokemon_from_social() @@ -323,12 +336,12 @@ def work(self): if len(pokemon_list) < 1: if DEBUG_ON: - print 'No enough pokemon in list to snip' + self._emit_log("No pokemons in list to snipe") return WorkerResult.SUCCESS pokemon = pokemon_list[0] if DEBUG_ON: - print 'How many pokemon in list: {}'.format(len(pokemon_list)) + self._emit_log('How many pokemon in list: {}'.format(len(pokemon_list))) if self.config['snipe']: if self.snipe_high_prio_only: count = 0 @@ -342,7 +355,7 @@ def work(self): time.sleep(SNIPE_SLEEP_SEC*5) else: if DEBUG_ON: - print 'this pokemon is not good enough to snip {}'.format(pokemon) + self._emit_log('this pokemon is not good enough to snipe {}'.format(pokemon)) return WorkerResult.SUCCESS else: return self.snipe(pokemon) diff --git a/pokemongo_bot/cell_workers/telegram_task.py b/pokemongo_bot/cell_workers/telegram_task.py index 3478f30f37..6591b7183d 100644 --- a/pokemongo_bot/cell_workers/telegram_task.py +++ b/pokemongo_bot/cell_workers/telegram_task.py @@ -6,6 +6,10 @@ from pokemongo_bot.base_task import BaseTask from pokemongo_bot.base_dir import _base_dir from pokemongo_bot.event_handlers import TelegramHandler + +from pprint import pprint +import re + class TelegramTask(BaseTask): SUPPORTED_TASK_API_VERSION = 1 update_id = None @@ -37,8 +41,19 @@ def work(self): self.update_id = update.update_id+1 if update.message: self.logger.info("message from {} ({}): {}".format(update.message.from_user.username, update.message.from_user.id, update.message.text)) - if self.config.get('master',None) and self.config.get('master',None)<>update.message.from_user.id: + if self.config.get('master',None) and self.config.get('master',None) not in [update.message.from_user.id, "@{}".format(update.message.from_user.username)]: + self.emit_event( + 'debug', + formatted="Master wrong: expecting {}, got {}({})".format(self.config.get('master',None), update.message.from_user.username, update.message.from_user.id)) continue + else: + if not re.match(r'^[0-9]+$', "{}".format(self.config['master'])): # master was not numeric... + self.config['master'] = update.message.chat_id + idx = (i for i,v in enumerate(self.bot.event_manager._handlers) if type(v) is TelegramHandler).next() + self.bot.event_manager._handlers[idx] = TelegramHandler(self.tbot,self.config['master'], self.config.get('alert_catch')) + + + if update.message.text == "/info": stats = self._get_player_stats() if stats: diff --git a/pokemongo_bot/event_handlers/telegram_handler.py b/pokemongo_bot/event_handlers/telegram_handler.py index 826e2214f5..b32a083225 100644 --- a/pokemongo_bot/event_handlers/telegram_handler.py +++ b/pokemongo_bot/event_handlers/telegram_handler.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from pokemongo_bot.event_manager import EventHandler import thread +import re DEBUG_ON = False @@ -9,15 +10,23 @@ def __init__(self, tbot,master,pokemons): self.tbot = tbot self.master=master self.pokemons=pokemons + self.whoami="TelegramHandler" def handle_event(self, event, sender, level, formatted_msg, data): if self.master: + if not re.match(r'^[0-9]+$', str(self.master)): + return + master = self.master + if event == 'level_up': - self.tbot.sendMessage(chat_id=self.master, parse_mode='Markdown', text="level up ({})".format(data["current_level"])) + msg = "level up ({})".format(data["current_level"]) elif event == 'pokemon_caught': if data["pokemon"] in self.pokemons or self.pokemons[0]=="all": - self.tbot.sendMessage(chat_id=self.master, parse_mode='Markdown', - text="Caught {} CP: {}, IV: {}".format(data["pokemon"],data["cp"],data["iv"]) - ) + msg = "Caught {} CP: {}, IV: {}".format(data["pokemon"],data["cp"],data["iv"]) + else: + return + else: + return + self.tbot.sendMessage(chat_id=master, parse_mode='Markdown', text=msg) From 18d7589edd5c440e0c24f051ff8fcfcf7b7e2531 Mon Sep 17 00:00:00 2001 From: Jasperrr91 Date: Sun, 28 Aug 2016 19:04:47 +0200 Subject: [PATCH 12/15] Fixes catch rates. (#4863) --- pokemongo_bot/cell_workers/pokemon_catch_worker.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pokemongo_bot/cell_workers/pokemon_catch_worker.py b/pokemongo_bot/cell_workers/pokemon_catch_worker.py index d6300ff166..73aa62dee8 100644 --- a/pokemongo_bot/cell_workers/pokemon_catch_worker.py +++ b/pokemongo_bot/cell_workers/pokemon_catch_worker.py @@ -381,6 +381,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): min_ultraball_to_keep = self.min_ultraball_to_keep used_berry = False + original_catch_rate_by_ball = catch_rate_by_ball while True: # find lowest available ball @@ -492,6 +493,7 @@ def _do_catch(self, pokemon, encounter_id, catch_rate_by_ball, is_vip=False): data={'pokemon': pokemon.name} ) used_berry = False + catch_rate_by_ball = original_catch_rate_by_ball # sleep according to flee_count and flee_duration config settings # randomly chooses a number of times to 'show' wobble animation between 1 and flee_count From e43f8f98985de8d1bc254f0c04b2b4068101c879 Mon Sep 17 00:00:00 2001 From: DBa2016 Date: Mon, 29 Aug 2016 00:34:29 +0200 Subject: [PATCH 13/15] Implemented more granularity in the "alert_catch" parameter for Telegram alerts. --- configs/config.json.example | 7 ++++++- .../event_handlers/telegram_handler.py | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/configs/config.json.example b/configs/config.json.example index 634ab60b13..5cb0d9c2d9 100644 --- a/configs/config.json.example +++ b/configs/config.json.example @@ -12,7 +12,12 @@ "config": { "enabled": false, "master": null, - "alert_catch": ["all"] + "// old syntax, still supported: alert_catch": ["all"], + "// new syntax:": {}, + "alert_catch": { + "all": {"operator": "and", "cp": 1300, "iv": 0.95}, + "Snorlax": {"operator": "or", "cp": 900, "iv": 0.9} + } } }, { diff --git a/pokemongo_bot/event_handlers/telegram_handler.py b/pokemongo_bot/event_handlers/telegram_handler.py index b32a083225..4052e8c4ea 100644 --- a/pokemongo_bot/event_handlers/telegram_handler.py +++ b/pokemongo_bot/event_handlers/telegram_handler.py @@ -21,10 +21,22 @@ def handle_event(self, event, sender, level, formatted_msg, data): if event == 'level_up': msg = "level up ({})".format(data["current_level"]) elif event == 'pokemon_caught': - if data["pokemon"] in self.pokemons or self.pokemons[0]=="all": - msg = "Caught {} CP: {}, IV: {}".format(data["pokemon"],data["cp"],data["iv"]) + if isinstance(self.pokemons, list): + if data["pokemon"] in self.pokemons or "all" in self.pokemons: + msg = "Caught {} CP: {}, IV: {}".format(data["pokemon"],data["cp"],data["iv"]) + else: + return else: - return + if data["pokemon"] in self.pokemons: + trigger = self.pokemons[data["pokemon"]] + elif "all" in self.pokemons: + trigger = self.pokemons["all"] + else: + return + if (not "operator" in trigger or trigger["operator"] == "and") and data["cp"] >= trigger["cp"] and data["iv"] >= trigger["iv"] or ("operator" in trigger and trigger["operator"] == "or" and (data["cp"] >= trigger["cp"] or data["iv"] >= trigger["iv"])): + msg = "Caught {} CP: {}, IV: {}".format(data["pokemon"],data["cp"],data["iv"]) + else: + return else: return self.tbot.sendMessage(chat_id=master, parse_mode='Markdown', text=msg) From dc31c8d19052d6fdf70f206632fb60b10d30f634 Mon Sep 17 00:00:00 2001 From: Stuart Travers Date: Mon, 29 Aug 2016 19:52:45 +1000 Subject: [PATCH 14/15] Add exceptions to json file read/writes (#4877) * Fix bot crash at start on permaban * Expanded logging options Added "logging" section to config, with options "color", "show_datetime", "show_process_name" and "show_log_level" * Added warning about deprecated logging_color arg * Display log message moved No point trying to use the logger before it's been initialised. Moved to init_config. * Remove milliseconds from datetime Because really, do we need that? * Reversed condition order for clarity First check: "if not in config", OR Second check: "is in config AND set to true" If either condition matches, the logging detail will be displayed. * Documented new log options * Modified conditions again Removed unnecessary second check for config values and slightly modified parentheses as per suggestion from @mjmadsen * Add exception handling to json file read/write ops * Removed API call in update live stats Instead of making a new api call, utilise stats already contained in metrics. --- pokemongo_bot/__init__.py | 19 +++++++-- .../cell_workers/pokemon_optimizer.py | 25 +----------- pokemongo_bot/cell_workers/telegram_task.py | 21 +++++++--- .../cell_workers/update_live_stats.py | 39 ++++++++++++------- pokemongo_bot/inventory.py | 29 +++++++++++--- pokemongo_bot/metrics.py | 4 ++ 6 files changed, 85 insertions(+), 52 deletions(-) diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 5d9a945628..03d76dc7ce 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -41,6 +41,9 @@ from pgoapi.protos.POGOProtos.Enums import BadgeType_pb2 import struct +class FileIOException(Exception): + pass + class PokemonGoBot(Datastore): @property def position(self): @@ -1095,9 +1098,19 @@ def _set_starting_position(self): level='debug', formatted='Loading cached location...' ) - with open(os.path.join(_base_dir, 'data', 'last-location-%s.json' % - self.config.username)) as f: - location_json = json.load(f) + + json_file = os.path.join(_base_dir, 'data', 'last-location-%s.json' % self.config.username) + + try: + with open(json_file, "r") as infile: + location_json = json.load(infile) + except (IOError, ValueError): + # Unable to read json file. + # File may be corrupt. Create a new one. + location_json = [] + except: + raise FileIOException("Unexpected error reading from {}".web_inventory) + location = ( location_json['lat'], location_json['lng'], diff --git a/pokemongo_bot/cell_workers/pokemon_optimizer.py b/pokemongo_bot/cell_workers/pokemon_optimizer.py index 7b51d2703c..41b1c06f96 100644 --- a/pokemongo_bot/cell_workers/pokemon_optimizer.py +++ b/pokemongo_bot/cell_workers/pokemon_optimizer.py @@ -96,30 +96,7 @@ def open_inventory(self): self.family_by_family_id.setdefault(family_id, []).append(pokemon) def save_web_inventory(self): - web_inventory = os.path.join(_base_dir, "web", "inventory-%s.json" % self.bot.config.username) - - with open(web_inventory, "r") as infile: - ii = json.load(infile) - - ii = [x for x in ii if not x.get("inventory_item_data", {}).get("pokedex_entry", None)] - ii = [x for x in ii if not x.get("inventory_item_data", {}).get("candy", None)] - ii = [x for x in ii if not x.get("inventory_item_data", {}).get("item", None)] - ii = [x for x in ii if not x.get("inventory_item_data", {}).get("pokemon_data", None)] - - for pokedex in inventory.pokedex().all(): - ii.append({"inventory_item_data": {"pokedex_entry": pokedex}}) - - for family_id, candy in inventory.candies()._data.items(): - ii.append({"inventory_item_data": {"candy": {"family_id": family_id, "candy": candy.quantity}}}) - - for item_id, item in inventory.items()._data.items(): - ii.append({"inventory_item_data": {"item": {"item_id": item_id, "count": item.count}}}) - - for pokemon in inventory.pokemons().all(): - ii.append({"inventory_item_data": {"pokemon_data": pokemon._data}}) - - with open(web_inventory, "w") as outfile: - json.dump(ii, outfile) + inventory.update_web_inventory() def get_family_optimized(self, family_id, family): evolve_best = [] diff --git a/pokemongo_bot/cell_workers/telegram_task.py b/pokemongo_bot/cell_workers/telegram_task.py index 6591b7183d..5c2b60787e 100644 --- a/pokemongo_bot/cell_workers/telegram_task.py +++ b/pokemongo_bot/cell_workers/telegram_task.py @@ -10,6 +10,9 @@ from pprint import pprint import re +class FileIOException(Exception): + pass + class TelegramTask(BaseTask): SUPPORTED_TASK_API_VERSION = 1 update_id = None @@ -18,7 +21,6 @@ class TelegramTask(BaseTask): def initialize(self): if not self.enabled: return - self.logger = logging.getLogger(type(self).__name__) api_key = self.bot.config.telegram_token if api_key == None: self.emit_event( @@ -40,7 +42,7 @@ def work(self): for update in self.tbot.getUpdates(offset=self.update_id, timeout=10): self.update_id = update.update_id+1 if update.message: - self.logger.info("message from {} ({}): {}".format(update.message.from_user.username, update.message.from_user.id, update.message.text)) + self.bot.logger.info("message from {} ({}): {}".format(update.message.from_user.username, update.message.from_user.id, update.message.text)) if self.config.get('master',None) and self.config.get('master',None) not in [update.message.from_user.id, "@{}".format(update.message.from_user.username)]: self.emit_event( 'debug', @@ -89,9 +91,18 @@ def _get_player_stats(self): :rtype: dict """ web_inventory = os.path.join(_base_dir, "web", "inventory-%s.json" % self.bot.config.username) - with open(web_inventory, "r") as infile: - json_inventory = json.load(infile) - infile.close() + + try: + with open(web_inventory, "r") as infile: + json_inventory = json.load(infile) + except ValueError: + # Unable to read json from web inventory + # File may be corrupt. Create a new one. + self.bot.logger.info('[x] Error while opening inventory file for read: %s' % e) + json_inventory = [] + except: + raise FileIOException("Unexpected error reading from {}".web_inventory) + return next((x["inventory_item_data"]["player_stats"] for x in json_inventory if x.get("inventory_item_data", {}).get("player_stats", {})), diff --git a/pokemongo_bot/cell_workers/update_live_stats.py b/pokemongo_bot/cell_workers/update_live_stats.py index 9fb8ea9d46..743e3b9f19 100644 --- a/pokemongo_bot/cell_workers/update_live_stats.py +++ b/pokemongo_bot/cell_workers/update_live_stats.py @@ -1,6 +1,8 @@ import ctypes import json import os +import logging + from sys import stdout, platform as _platform from datetime import datetime, timedelta @@ -12,6 +14,9 @@ # XP file import json +class FileIOException(Exception): + pass + class UpdateLiveStats(BaseTask): """ Periodically displays stats about the bot in the terminal and/or in its title. @@ -420,25 +425,31 @@ def _get_player_stats(self): :rtype: dict """ # TODO : find a better solution than calling the api - inventory_items = self.bot.api.get_inventory() \ - .get('responses', {}) \ - .get('GET_INVENTORY', {}) \ - .get('inventory_delta', {}) \ - .get('inventory_items', {}) - return next((x["inventory_item_data"]["player_stats"] - for x in inventory_items - if x.get("inventory_item_data", {}).get("player_stats", {})), - None) - + return self.bot.metrics.player_stats + def update_web_stats(self,player_data): web_inventory = os.path.join(_base_dir, "web", "inventory-%s.json" % self.bot.config.username) - with open(web_inventory, "r") as infile: - json_stats = json.load(infile) + try: + with open(web_inventory, "r") as infile: + json_stats = json.load(infile) + except (IOError, ValueError): + # Unable to read json from web inventory + # File may be corrupt. Create a new one. + self.bot.logger.info('[x] Error while opening inventory file for read: %s' % e, 'red') + json_stats = [] + except: + raise FileIOException("Unexpected error loading information from json.") json_stats = [x for x in json_stats if not x.get("inventory_item_data", {}).get("player_stats", None)] json_stats.append({"inventory_item_data": {"player_stats": player_data}}) - with open(web_inventory, "w") as outfile: - json.dump(json_stats, outfile) + try: + with open(web_inventory, "w") as outfile: + json.dump(json_stats, outfile) + except (IOError, ValueError): + self.bot.logger.info('[x] Error while opening inventory file for write: %s' % e, 'red') + pass + except: + raise FileIOException("Unexpected error writing to {}".web_inventory) diff --git a/pokemongo_bot/inventory.py b/pokemongo_bot/inventory.py index 0cffa16095..0459bd4d34 100644 --- a/pokemongo_bot/inventory.py +++ b/pokemongo_bot/inventory.py @@ -14,6 +14,9 @@ https://www.reddit.com/r/pokemongodev/comments/4w7mdg/combat_damage_calculation_formula_exactly/ ''' +class FileIOException(Exception): + pass + # # Abstraction @@ -1122,6 +1125,8 @@ def init_inventory_outfile(self): web_inventory = os.path.join(_base_dir, "web", "inventory-%s.json" % self.bot.config.username) if not os.path.exists(web_inventory): + self.bot.logger.info('No inventory file %s found. Creating a new one' % web_inventory) + json_inventory = [] with open(web_inventory, "w") as outfile: @@ -1134,9 +1139,16 @@ def update_web_inventory(self): if not os.path.exists(web_inventory): self.init_inventory_outfile() - with open(web_inventory, "r") as infile: - json_inventory = json.load(infile) - infile.close() + try: + with open(web_inventory, "r") as infile: + json_inventory = json.load(infile) + except (IOError, ValueError): + # Unable to read json from web inventory + # File may be corrupt. Create a new one. + self.bot.logger.info('[x] Error while opening inventory file for read: %s' % e, 'red') + json_inventory = [] + except: + raise FileIOException("Unexpected error reading from {}".web_inventory) json_inventory = [x for x in json_inventory if not x.get("inventory_item_data", {}).get("pokedex_entry", None)] json_inventory = [x for x in json_inventory if not x.get("inventory_item_data", {}).get("candy", None)] @@ -1145,9 +1157,14 @@ def update_web_inventory(self): json_inventory = json_inventory + self.jsonify_inventory() - with open(web_inventory, "w") as outfile: - json.dump(json_inventory, outfile) - outfile.close() + try: + with open(web_inventory, "w") as outfile: + json.dump(json_inventory, outfile) + except (IOError, ValueError): + self.bot.logger.info('[x] Error while opening inventory file for write: %s' % e, 'red') + pass + except: + raise FileIOException("Unexpected error writing to {}".web_inventory) def jsonify_inventory(self): json_inventory = [] diff --git a/pokemongo_bot/metrics.py b/pokemongo_bot/metrics.py index 775258155d..693a357cfd 100644 --- a/pokemongo_bot/metrics.py +++ b/pokemongo_bot/metrics.py @@ -24,6 +24,9 @@ def __init__(self, bot): self.uniq_pokemons_caught = None self.uniq_pokemons_list = None + + self.player_stats = [] + self.inventory_data = [] def runtime(self): return timedelta(seconds=round(time.time() - self.start_time)) @@ -114,6 +117,7 @@ def capture_stats(self): if 'inventory_item_data' in item: if 'player_stats' in item['inventory_item_data']: playerdata = item['inventory_item_data']['player_stats'] + self.player_stats = playerdata self.xp['latest'] = playerdata.get('experience', 0) if self.xp['start'] < 0: self.xp['start'] = self.xp['latest'] From 3ebabfb13fe75d54556d595809b61ca4627396ae Mon Sep 17 00:00:00 2001 From: DeXtroTip Date: Mon, 29 Aug 2016 14:39:52 +0100 Subject: [PATCH 15/15] Incubate eggs fix (#4881) * Fixed incubator_eggs wrong print * Fixed pokemon hatched from eggs not added to cached inventory * Fix * Fixed not using breakable incubators * Fixed error adding pokemon to cached inventory * Moved remove egg and add Pokemon to _hatch_eggs --- pokemongo_bot/cell_workers/incubate_eggs.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pokemongo_bot/cell_workers/incubate_eggs.py b/pokemongo_bot/cell_workers/incubate_eggs.py index 10121c36cd..2bf147d5ab 100644 --- a/pokemongo_bot/cell_workers/incubate_eggs.py +++ b/pokemongo_bot/cell_workers/incubate_eggs.py @@ -1,5 +1,6 @@ from datetime import datetime, timedelta +from pokemongo_bot import inventory from pokemongo_bot.human_behaviour import sleep from pokemongo_bot.base_task import BaseTask @@ -35,15 +36,18 @@ def work(self): except: return + should_print = self._should_print() + if self.used_incubators and IncubateEggs.last_km_walked != self.km_walked: self.used_incubators.sort(key=lambda x: x.get("km")) km_left = self.used_incubators[0]['km']-self.km_walked if km_left <= 0: self._hatch_eggs() + should_print = False else: self.bot.metrics.next_hatching_km(km_left) - if self._should_print(): + if should_print: self._print_eggs() self._compute_next_update() @@ -58,9 +62,9 @@ def work(self): if self.ready_breakable_incubators: # get available eggs - eggs = self._filter_sort_eggs(self.infinite_incubator, - self.infinite_longer_eggs_first) - self._apply_incubators(eggs, self.ready_infinite_incubators) + eggs = self._filter_sort_eggs(self.breakable_incubator, + self.breakable_longer_eggs_first) + self._apply_incubators(eggs, self.ready_breakable_incubators) def _filter_sort_eggs(self, allowed, sorting): @@ -203,13 +207,15 @@ def _hatch_eggs(self): candy = result.get('candy_awarded', "error") xp = result.get('experience_awarded', "error") sleep(self.hatching_animation_delay) - self.bot.latest_inventory = None try: pokemon_data = self._check_inventory(pokemon_ids) for pokemon in pokemon_data: # pokemon ids seem to be offset by one if pokemon['pokemon_id']!=-1: pokemon['name'] = self.bot.pokemon_list[(pokemon.get('pokemon_id')-1)]['Name'] + #remove as egg and add as pokemon + inventory.pokemons().remove(pokemon['id']) + inventory.pokemons().add(inventory.Pokemon(pokemon)) else: pokemon['name'] = "error" except: