Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev merge to master #6076

Merged
merged 19 commits into from
Jul 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/configuration_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
- [CompleteTutorial](#completetutorial)
- [BuddyPokemon](#buddypokemon)
- [PokemonHunter](#pokemonhunter)
- [BadPokemon](#badpokemon)

# Configuration files

Expand Down Expand Up @@ -172,6 +173,8 @@ The behaviors of the bot are configured via the `tasks` key in the `config.json`
[[back to top](#table-of-contents)]
* CatchPokemon
* `enabled`: Default "true" | Enable/Disable the task.
* `always_catch_family_of_vip`: Default "false" | Always catch family members of a VIP, even if locked on a target.
* `always_catch_trash`: Default "false" | Always catch trash Pokemon (12 candy evolve), even if locked on a target.
* `treat_unseen_as_vip`: Default `"true"` | If true, treat new to dex as VIP
* `catch_visible_pokemon`: Default "true" | If enabled, attempts to catch "visible" pokemon that are reachable
* `catch_lured_pokemon`: Default "true" | If enabled, attempts to catch "lured" pokemon that are reachable
Expand Down Expand Up @@ -1421,6 +1424,11 @@ Hunts down nearby Pokemon. Searches for Pokemon to complete the Pokedex, or if a
* `treat_family_of_vip_as_vip`: `Default: false`. Should we see family of an VIP as a VIP (locking onto it if enabled)
* `hunt_for_trash_to_fill_bag`: `Default: false`. Should we try to fill the bag with trash if a set amount of slots is left?
* `trash_hunt_open_slots`: `Default: 25`. The amount of slots for the previous setting
* `run_to_vip`: `Default: false`. Run to a VIP Pokemon? Running sets the speed of the walker to the walk_max value!

### Hunting family members of VIPs
If enabled (`target_family_of_vip` = true), the hunter will also hunt down family members of a VIP. For example, if you marked Gyarados as a VIP Pokemon then the hunter will now also hunt down Magikarps.
When on the hunt for a family member of a VIP, and `treat_family_of_vip_as_vip` is false, the hunter will keep a look out for "real" VIPs. So when hunting for a Magikarp, if a Snorlax shows up in the sightings, the hunter will target the Snorlax.

### Hunting for trash
If enabled the hunter will start hunting down Pidgeys, Weedles and Caterpies when a set amount of slots (defaults to 25) are left in the bag to fill. The idea is simple; we are about to start evolving Pokemon. So the priority of the hunter shiftes. BUT when a VIP Pokemon is nearby, the Hunter will always start chasing that VIP first.
Expand Down Expand Up @@ -1448,3 +1456,33 @@ Also hunting for trash does NOT lock the target, catching all Pokemon it find on
}
}
```
## BadPokemon
[[back to top](#table-of-contents)]

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

If you have any Pokemon that Niantic has marked as bad (red slashes) this will notify you. If you set the option, it will also transfer those Pokemon.

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

* `transfer`: `Default: False`. Must we transfer the bad Pokemon?
* `bulktransfer_enabled`: `Default: True`. If we do transfer the bad Pokemon, may we do so in a batch?
* `action_wait_min`: `Default: 3`. Wait time min
* `action_wait_min`: `Default: 5`. Wait time max
* `min_interval`: `Default: 120`. Run once every X seconds


### Sample configuration
[[back to top](#table-of-contents)]
```json
{
"type": "BadPokemon",
"config": {
"enabled": true,
"transfer": true,
"min_interval": 240
}
}
```
161 changes: 118 additions & 43 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ def player_data(self):
"""
return self._player

@property
def inbox(self):
"""
Returns the inbox data as received from the API.
:return: The inbox data.
:rtype: dict
"""
return self._inbox

@property
def stardust(self):
dust = filter(lambda y: y['name'] == 'STARDUST', self._player['currencies'])[0]
Expand Down Expand Up @@ -352,6 +361,13 @@ def _register_events(self):
'longitude'
)
)
self.event_manager.register_event(
'moving_to_hunter_target',
parameters=(
'target_name',
'distance'
)
)
self.event_manager.register_event(
'moving_to_fort',
parameters=(
Expand Down Expand Up @@ -777,6 +793,16 @@ def _register_events(self):
self.event_manager.register_event('catch_limit_on')
self.event_manager.register_event('catch_limit_off')

self.event_manager.register_event(
'pokemon_knock_out_gym',
parameters=('pokemon', 'gym_name', 'notification_date', 'awarded_coins', 'awarded_coins_today')
)

self.event_manager.register_event(
'pokemon_hungy',
parameters=('pokemon', 'gym_name', 'notification_date')
)


def tick(self):
self.health_record.heartbeat()
Expand Down Expand Up @@ -1042,20 +1068,14 @@ def login(self):
formatted="Niantic Official API Version: {}".format(officalAPI)
)

link = "https://pokehash.buddyauth.com/api/hash/versions"
f = urllib2.urlopen(link)
myfile = f.read()
f.close()
bossland_hash_endpoint = myfile.split(",")
total_entry = int(len(bossland_hash_endpoint))
last_bossland_entry = bossland_hash_endpoint[total_entry-1]
bossland_lastestAPI = last_bossland_entry.split(":")[0].replace('\"','')
hashingAPI_temp = 0
PGoAPI_version = PGoApi.get_api_version()
PGoAPI_version_str = str(PGoAPI_version)
PGoAPI_version_str = "0."+ PGoAPI_version_str[0:2] + "." + PGoAPI_version_str[-1]
self.event_manager.emit(
'security_check',
sender=self,
level='info',
formatted="Latest Bossland Hashing API Version: {}".format(bossland_lastestAPI)
formatted="Bot is currently running on API {}".format(PGoAPI_version_str)
)

if self.config.check_niantic_api is True:
Expand All @@ -1067,28 +1087,13 @@ def login(self):
formatted="Warning: Bot is running on legacy API"
)
else:
PGoAPI_hash_endpoint = HashServer.endpoint.split("com/",1)[1]
PGoAPI_hash_version = []
# Check if PGoAPI hashing is in Bossland versioning
bossland_hash_data = json.loads(myfile)

for version, endpoint in bossland_hash_data.items():
if endpoint == PGoAPI_hash_endpoint:
# Version should always be in this format x.xx.x
# Check total len, if less than 4, pack a zero behind
if len(version.replace('.','')) < 4:
version = version + ".0"
hashingAPI_temp = int(version.replace('.',''))
# iOS versioning is always more than 1.19.0
if hashingAPI_temp < 1190:
PGoAPI_hash_version.append(version)
# assuming andorid versioning is always last entry
PGoAPI_hash_version.sort(reverse=True)
# covert official api version & hashing api version to numbers
officialAPI_int = int(officalAPI.replace('.',''))
hashingAPI_int = int(PGoAPI_hash_version[0].replace('.',''))

PGoAPI_version_tmp = str(PGoAPI_version)
PGoAPI_version_tmp = PGoAPI_version_tmp[0:2] + PGoAPI_version_tmp[-1]
PGoAPI_version_int = int(PGoAPI_version_tmp)

if hashingAPI_int < officialAPI_int:
if PGoAPI_version_int < officialAPI_int:
self.event_manager.emit(
'security_check',
sender=self,
Expand All @@ -1101,7 +1106,7 @@ def login(self):
'security_check',
sender=self,
level='info',
formatted="Current PGoAPI is using API Version: {}. Niantic API Check Pass".format(PGoAPI_hash_version[0])
formatted="Current PGoAPI is using {} API. Niantic API Check Pass".format(PGoAPI_version_str)
)

self.heartbeat()
Expand Down Expand Up @@ -1243,41 +1248,50 @@ def _print_character_info(self):
# Items Output
self.logger.info(
'PokeBalls: ' + str(items_inventory.get(1).count) +
' | GreatBalls: ' + str(items_inventory.get(2).count) +
' | UltraBalls: ' + str(items_inventory.get(3).count) +
' | MasterBalls: ' + str(items_inventory.get(4).count))
' | Great Balls: ' + str(items_inventory.get(2).count) +
' | Ultra Balls: ' + str(items_inventory.get(3).count) +
' | Master Balls: ' + str(items_inventory.get(4).count))

self.logger.info(
'RazzBerries: ' + str(items_inventory.get(701).count) +
' | Nanab Berries: ' + str(items_inventory.get(703).count) +
' | Pinap Berries: ' + str(items_inventory.get(705).count))
' | Pinap Berries: ' + str(items_inventory.get(705).count) +
' | Golden RazzBerries: ' + str(items_inventory.get(706).count) +
' | Golden Nanab Berries: ' + str(items_inventory.get(707).count) +
' | Golden Pinap Berries: ' + str(items_inventory.get(708).count))

self.logger.info(
'LuckyEgg: ' + str(items_inventory.get(301).count) +
' | Incubator: ' + str(items_inventory.get(902).count) +
' | TroyDisk: ' + str(items_inventory.get(501).count))
' | Incubator: ' + str(items_inventory.get(902).count))

self.logger.info(
'Potion: ' + str(items_inventory.get(101).count) +
' | SuperPotion: ' + str(items_inventory.get(102).count) +
' | HyperPotion: ' + str(items_inventory.get(103).count) +
' | MaxPotion: ' + str(items_inventory.get(104).count))
' | Super Potion: ' + str(items_inventory.get(102).count) +
' | Hyper Potion: ' + str(items_inventory.get(103).count) +
' | Max Potion: ' + str(items_inventory.get(104).count))

self.logger.info(
'Incense: ' + str(items_inventory.get(401).count) +
' | IncenseSpicy: ' + str(items_inventory.get(402).count) +
' | IncenseCool: ' + str(items_inventory.get(403).count))
' | Lure Module: ' + str(items_inventory.get(501).count))

self.logger.info(
'Revive: ' + str(items_inventory.get(201).count) +
' | MaxRevive: ' + str(items_inventory.get(202).count))
' | Max Revive: ' + str(items_inventory.get(202).count))

self.logger.info(
'Sun Stone: ' + str(items_inventory.get(1101).count) +
' | Kings Rock: ' + str(items_inventory.get(1102).count) +
' | Metal Coat: ' + str(items_inventory.get(1103).count) +
' | Dragon Scale: ' + str(items_inventory.get(1104).count) +
' | Upgrade: ' + str(items_inventory.get(1105).count))

self.logger.info(
'Fast TM: ' + str(items_inventory.get(1201).count) +
' | Charge TM: ' + str(items_inventory.get(1202).count) +
' | Rare Candy: ' + str(items_inventory.get(1301).count) +
' | Free Raid Pass: ' + str(items_inventory.get(1401).count) +
' | Premium Raid Pass: ' + str(items_inventory.get(1402).count) +
' | Legendary Raid Pass: ' + str(items_inventory.get(1403).count))

if warn:
self.logger.info('')
Expand Down Expand Up @@ -1548,10 +1562,13 @@ def heartbeat(self):
if timeout >= now * 1000}

if now - self.last_heartbeat >= self.heartbeat_threshold and not self.hb_locked:
previous_heartbeat = self.last_heartbeat
self.last_heartbeat = now
request = self.api.create_request()
request.get_player()
request.check_awarded_badges()
request.get_inbox()
responses = None
try:
responses = request.call()
except NotLoggedInException:
Expand All @@ -1572,6 +1589,64 @@ def heartbeat(self):
formatted='player_data: {player_data}',
data={'player_data': self._player}
)
if responses['responses']['GET_INBOX']['result'] == 1:
self._inbox = responses['responses']['GET_INBOX']['inbox']
# self.logger.info("Got inbox messages?")
# self.logger.info("Inbox: %s" % responses['responses']['GET_INBOX'])
if 'notifications' in self._inbox:
for notification in self._inbox['notifications']:
notification_date = datetime.datetime.fromtimestamp(int(notification['create_timestamp_ms']) / 1e3)
if previous_heartbeat > (int(notification['create_timestamp_ms']) / 1e3):
# Skipp old notifications!
continue

if notification['category'] == 'pokemon_hungry':
gym_name = pokemon = 'Unknown'
for variable in notification['variables']:
if variable['name'] == 'GYM_NAME':
gym_name = variable['literal']
if variable['name'] == 'POKEMON_NICKNAME':
pokemon = variable['literal']

self.event_manager.emit(
'pokemon_hungy',
sender=self,
level='info',
formatted='{pokemon} in the Gym {gym_name} is hungy and want a candy! {notification_date}',
data={
'pokemon': pokemon,
'gym_name': gym_name,
'notification_date': notification_date.strftime('%Y-%m-%d %H:%M:%S.%f')
}
)

if notification['category'] == 'gym_removal':
gym_name = pokemon = 'Unknown'
for variable in notification['variables']:
if variable['name'] == 'GYM_NAME':
gym_name = variable['literal']
if variable['name'] == 'POKEMON_NICKNAME':
pokemon = variable['literal']
if variable['name'] == 'POKECOIN_AWARDED':
coins_awared = variable['literal']
if variable['name'] == 'POKECOIN_AWARDED_TODAY':
coins_awared_today = variable['literal']

self.event_manager.emit(
'pokemon_knock_out_gym',
sender=self,
level='info',
formatted='{pokemon} has been knocked out the Gym {gym_name} at {notification_date}. Awarded coins: {awarded_coins} | Today awared: {awarded_coins_today}',
data={
'pokemon': pokemon,
'gym_name': gym_name,
'notification_date': notification_date.strftime('%Y-%m-%d %H:%M:%S.%f'),
'awarded_coins': coins_awared,
'awarded_coins_today': coins_awared_today
}
)


if responses['responses']['CHECK_AWARDED_BADGES']['success'] == True:
# store awarded_badges reponse to be used in a task or part of heartbeat
self._awarded_badges = responses['responses']['CHECK_AWARDED_BADGES']
Expand Down
3 changes: 2 additions & 1 deletion pokemongo_bot/cell_workers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@
from .discord_task import DiscordTask
from .buddy_pokemon import BuddyPokemon
from .catch_limiter import CatchLimiter
from .update_hash_stats import UpdateHashStats
from .update_hash_stats import UpdateHashStats
from .bad_pokemon import BadPokemon
Loading