Skip to content

Commit

Permalink
Merge branch 'Debug_2017_07_18' into Basic-Gym-Support
Browse files Browse the repository at this point in the history
  • Loading branch information
goedzo authored Jul 17, 2017
2 parents 5ffcfc8 + 3d5f6a0 commit ea3e660
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 12 deletions.
27 changes: 17 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,24 @@ RUN apk -U --no-cache add python py-pip tzdata \
&& rm -rf /var/cache/apk/* \
&& find / -name '*.pyc' -o -name '*.pyo' | xargs -rn1 rm -f

ADD http://pgoapi.com/pgoencrypt.tar.gz /tmp/pgoencrypt.tar.gz
ADD https://raw.githubusercontent.com/$BUILD_REPO/$BUILD_BRANCH/requirements.txt .
RUN apk -U --no-cache add --virtual .build-dependencies python-dev gcc make musl-dev git \
&& tar zxf /tmp/pgoencrypt.tar.gz -C /tmp \
&& make -C /tmp/pgoencrypt/src \
&& cp /tmp/pgoencrypt/src/libencrypt.so /usr/src/app/encrypt.so \
&& ln -s locale.h /usr/include/xlocale.h \
&& pip install --no-cache-dir -r requirements.txt \
&& apk del .build-dependencies \
&& rm -rf /var/cache/apk/* /tmp/pgoencrypt* /usr/include/xlocale.h \
&& find / -name '*.pyc' -o -name '*.pyo' | xargs -rn1 rm -f

#Need to load cert for WGET
RUN apk update
RUN apk add ca-certificates wget
RUN update-ca-certificates
RUN wget -P /tmp/ http://pgoapi.com/pgoencrypt.tar.gz

RUN apk -U --no-cache add --virtual .build-dependencies python-dev gcc make musl-dev git
RUN tar xvzf /tmp/pgoencrypt.tar.gz -C /tmp
RUN make -C /tmp/pgoencrypt/src
RUN cp /tmp/pgoencrypt/src/libencrypt.so /usr/src/app/encrypt.so
RUN ln -s locale.h /usr/include/xlocale.h
RUN pip install --no-cache-dir -r requirements.txt
RUN apk del .build-dependencies
RUN rm -rf /var/cache/apk/* /tmp/pgoencrypt* /usr/include/xlocale.h
RUN find / -name '*.pyc' -o -name '*.pyo' | xargs -rn1 rm -f


ADD https://api.github.com/repos/$BUILD_REPO/commits/$BUILD_BRANCH /tmp/pgobot-version
RUN apk -U --no-cache add --virtual .pgobot-dependencies wget ca-certificates tar jq \
Expand Down
30 changes: 30 additions & 0 deletions docs/configuration_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- [BuddyPokemon](#buddypokemon)
- [PokemonHunter](#pokemonhunter)
- [BadPokemon](#badpokemon)
- [HealPokemon](#healpokemon)

# Configuration files

Expand Down Expand Up @@ -1486,3 +1487,32 @@ If you have any Pokemon that Niantic has marked as bad (red slashes) this will n
}
}
```

## HealPokemon
[[back to top](#table-of-contents)]

### Description
[[back to top](#table-of-contents)]

If you have any Pokemon that are dead or need healing, this task will try to do that.

### Options
[[back to top](#table-of-contents)]

* `heal`: `Default: True`. Should Pokemon be healed?
* `revive`: `Default: True`. Should dead Pokemon be revived?


### Sample configuration
[[back to top](#table-of-contents)]
```json
{
"type": "BadPokemon",
"config": {
"enabled": true,
"heal": true,
"revive": true
}
}
```

2 changes: 2 additions & 0 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,8 @@ def _register_events(self):
self.event_manager.register_event('catch_limit')
self.event_manager.register_event('spin_limit')
self.event_manager.register_event('show_best_pokemon', parameters=('pokemons'))
self.event_manager.register_event('revived_pokemon')
self.event_manager.register_event('healing_pokemon')

# level up stuff
self.event_manager.register_event(
Expand Down
1 change: 1 addition & 0 deletions pokemongo_bot/cell_workers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@
from .catch_limiter import CatchLimiter
from .update_hash_stats import UpdateHashStats
from .bad_pokemon import BadPokemon
from .heal_pokemon import HealPokemon
from .gym_pokemon import GymPokemon
251 changes: 251 additions & 0 deletions pokemongo_bot/cell_workers/heal_pokemon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import absolute_import

from datetime import datetime, timedelta
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot import inventory
from pokemongo_bot.item_list import Item
from pokemongo_bot.human_behaviour import sleep, action_delay

class HealPokemon(BaseTask):
SUPPORTED_TASK_API_VERSION = 1

def __init__(self, bot, config):
super(HealPokemon, self).__init__(bot, config)
self.bot = bot
self.config = config
self.enabled = self.config.get("enabled", False)
self.revive_pokemon = self.config.get("revive", True)
self.heal_pokemon = self.config.get("heal", True)
self.next_update = None
self.to_heal = []

def work(self):

if not self.enabled:
return WorkerResult.SUCCESS

# Check for pokemon to heal or revive
to_revive = []
self.to_heal = []
pokemons = inventory.pokemons().all()
pokemons.sort(key=lambda p: p.hp)
for pokemon in pokemons:
if pokemon.hp < 1.0:
self.logger.info("Dead: %s (%s CP| %s/%s )" % (pokemon.name, pokemon.cp, pokemon.hp, pokemon.hp_max))
to_revive += [pokemon]
elif pokemon.hp < pokemon.hp_max:
self.logger.info("Heal: %s (%s CP| %s/%s )" % (pokemon.name, pokemon.cp, pokemon.hp, pokemon.hp_max))
self.to_heal += [pokemon]

if len(self.to_heal) == 0 and len(to_revive) == 0:
if self._should_print:
self.next_update = datetime.now() + timedelta(seconds=120)
#self.logger.info("No pokemon to heal or revive")
return WorkerResult.SUCCESS
# Okay, start reviving pokemons
# Check revives and potions
revives = inventory.items().get(Item.ITEM_REVIVE.value).count
max_revives = inventory.items().get(Item.ITEM_MAX_REVIVE.value).count
normal = inventory.items().get(Item.ITEM_POTION.value).count
super_p = inventory.items().get(Item.ITEM_SUPER_POTION.value).count
hyper = inventory.items().get(Item.ITEM_HYPER_POTION.value).count
max_p = inventory.items().get(Item.ITEM_MAX_POTION.value).count

self.logger.info("Healing %s pokemon" % len(self.to_heal))
self.logger.info("Reviving %s pokemon" % len(to_revive))

if self.revive_pokemon:
if len(to_revive) > 0 and revives == 0 and max_revives == 0:
self.logger.info("No revives left! Can't revive %s pokemons." % len(to_revive))
elif len(to_revive) > 0:
self.logger.info("Reviving %s pokemon..." % len(to_revive))
for pokemon in to_revive:
self._revive_pokemon(pokemon)

if self.heal_pokemon:
if len(self.to_heal) > 0 and (normal + super_p + hyper + max_p) == 0:
self.logger.info("No potions left! Can't heal %s pokemon" % len(self.to_heal))
elif len(self.to_heal) > 0:
self.logger.info("Healing %s pokemon" % len(self.to_heal))
for pokemon in self.to_heal:
self._heal_pokemon(pokemon)

if self._should_print:
self.next_update = datetime.now() + timedelta(seconds=120)
self.logger.info("Done healing/reviving pokemon")

def _revive_pokemon(self, pokemon):
item = Item.ITEM_REVIVE.value
amount = inventory.items().get(item).count
if amount == 0:
self.logger.info("No normal revives left, using MAX revive!")
item = Item.ITEM_MAX_REVIVE.value

amount = inventory.items().get(item).count
if amount > 0:
response_dict_revive = self.bot.api.use_item_revive(item_id=item, pokemon_id=pokemon.unique_id)
action_delay(2, 3)
if response_dict_revive:
result = response_dict_revive.get('responses', {}).get('USE_ITEM_REVIVE', {}).get('result', 0)
revive_item = inventory.items().get(item)
# Remove the revive from the iventory
revive_item.remove(1)
if result is 1: # Request success
self.emit_event(
'revived_pokemon',
formatted='Revived {name}.',
data={
'name': pokemon.name
}
)
if item == Item.ITEM_REVIVE.value:
pokemon.hp = int(pokemon.hp_max / 2)
self.to_heal.append(pokemon)
else:
# Set pokemon as revived
pokemon.hp = pokemon.hp_max
return True
else:
self.emit_event(
'revived_pokemon',
level='error',
formatted='Failed to revive {name}!',
data={
'name': pokemon.name
}
)
return False

def _heal_pokemon(self, pokemon):
if pokemon.hp == 0:
self.logger.info("Can't heal a dead %s" % pokemon.name)
return False
# normal = inventory.items().get(Item.ITEM_POTION.value).count
# super_p = inventory.items().get(Item.ITEM_SUPER_POTION.value).count
# hyper = inventory.items().get(Item.ITEM_HYPER_POTION.value).count
max_p = inventory.items().get(Item.ITEM_MAX_POTION.value).count
# Figure out how much healing needs to be done.
def hp_to_restore(pokemon):
pokemon = inventory.pokemons().get_from_unique_id(pokemon.unique_id)
return pokemon.hp_max - pokemon.hp

if hp_to_restore(pokemon) > 200 and max_p > 0:
# We should use a MAX Potion
self._use_potion(Item.ITEM_MAX_POTION.value, pokemon)
pokemon.hp = pokemon.hp_max
return True
# Okay, now we see to heal as effective as possible
potions = [103, 102, 101]
heals = [200, 50, 20]

for item_id, max_heal in zip(potions, heals):
if inventory.items().get(item_id).count > 0:
while hp_to_restore(pokemon) > max_heal:
if inventory.items().get(item_id).count == 0:
break
action_delay(2, 3)
# More than 200 to restore, use a hyper first
if self._use_potion(item_id, pokemon):
pokemon.hp += max_heal
if pokemon.hp > pokemon.hp_max:
pokemon.hp = pokemon.hp_max
else:
break
# return WorkerResult.ERROR

# Now we use the least
potion_id = 101 # Normals first
while hp_to_restore(pokemon) > 0:
action_delay(2, 4)
if inventory.items().get(potion_id).count > 0:
if potion_id == 104:
self.logger.info("Using MAX potion to heal a %s" % pokemon.name)
if self._use_potion(potion_id, pokemon):
if potion_id == 104:
pokemon.hp = pokemon.hp_max
else:
pokemon.hp += heals[potion_id - 101]
if pokemon.hp > pokemon.hp_max:
pokemon.hp = pokemon.hp_max
else:
if potion_id < 104:
self.logger.info("Failed with potion %s. Trying next." % potion_id)
potion_id += 1
else:
self.logger.info("Failed with MAX potion. Done.")
break
elif potion_id < 104:
potion_id += 1
else:
self.logger.info("Can't heal a %s" % pokemon.name)
break


def _use_potion(self, potion_id, pokemon):
potion_count = inventory.items().get(potion_id).count
healing = 0
if potion_count == 0:
return False
if potion_id == 101:
self.logger.info("Healing with a normal potion we have %s left." % (potion_count - 1))
healing = 20
if potion_id == 102:
self.logger.info("Healing with a Super potion we have %s left." % (potion_count - 1))
healing = 50
if potion_id == 103:
self.logger.info("Healing with a HYper potion we have %s left." % (potion_count - 1))
healing = 200
if potion_id == 104:
self.logger.info("Healing with a MAX potion we have %s left." % (potion_count - 1))
healing = pokemon.hp_max - pokemon.hp

response_dict_potion = self.bot.api.use_item_potion(item_id=potion_id, pokemon_id=pokemon.unique_id)
# Select potion
sleep(2)
if response_dict_potion:
result = response_dict_potion.get('responses', {}).get('USE_ITEM_POTION', {}).get('result', 0)
if result is 1 or result is 0: # Request success
potion_item = inventory.items().get(potion_id)
# Remove the potion from the iventory
potion_item.remove(1)
self.emit_event(
'healing_pokemon',
formatted='Healing {name} ({hp} -> {hp_new}/{hp_max}).',
data={
'name': pokemon.name,
'hp': pokemon.hp,
'hp_new': pokemon.hp + healing,
'hp_max': pokemon.hp_max
}
)
return True
elif result == 3:
# ERROR_CANNOT_USE
pokemon.hp = pokemon.hp_max
self.logger.info("Can't use this to heal the %s" % pokemon.name)
return False
else:
self.logger.info("Result was: %s" % result)
self.emit_event(
'healing_pokemon',
level='error',
formatted='Failed to heal {name} ({hp} -> {hp_new}/{hp_max})!',
data={
'name': pokemon.name,
'hp': pokemon.hp,
'hp_new': pokemon.hp + healing,
'hp_max': pokemon.hp_max
}
)
return False

def _should_print(self):
"""
Returns a value indicating whether the pokemon should be displayed.
:return: True if the stats should be displayed; otherwise, False.
:rtype: bool
"""
return self.next_update is None or datetime.now() >= self.next_update
4 changes: 3 additions & 1 deletion pokemongo_bot/event_handlers/logging_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,11 @@ class LoggingHandler(EventHandler):
'used_lucky_egg': 'none',
'catch_limit_on': 'yellow',
'catch_limit_off': 'green',
'revived_pokemon': 'green',
'healing_pokemon': 'green',
'deployed_pokemon': 'green',
'gym_error': 'red',
'fed_pokemon': 'white'
'fed_pokemon': 'white
}
COLOR_CODE = {
'gray': '\033[90m',
Expand Down
5 changes: 5 additions & 0 deletions pokemongo_bot/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,11 @@ def add(self, pokemon):
raise ValueError("Pokemon already present in the inventory")
self._data[pokemon.unique_id] = pokemon

def get_from_unique_id(self, pokemon_unique_id):
if pokemon_unique_id not in self._data:
raise ValueError("Pokemon not present in the inventory")
return self._data[pokemon_unique_id]

def remove(self, pokemon_unique_id):
if pokemon_unique_id not in self._data:
raise ValueError("Pokemon not present in the inventory")
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
numpy==1.11.0
networkx==1.11
six==1.10
git+https://github.com/goedzo/pgoapi.git@develop#egg=pgoapi
git+https://github.com/pogodevorg/pgoapi.git@develop#egg=pgoapi
geopy==1.11.0
geographiclib==1.46.3
requests==2.10.0
Expand Down

0 comments on commit ea3e660

Please sign in to comment.