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

Gps noise #3912

Merged
merged 7 commits into from
Aug 20, 2016
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
5 changes: 5 additions & 0 deletions configs/config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@
"walk_min": 2.16,
"alt_min": 500,
"alt_max": 1000,
"gps_default_altitude": 8.0,
"replicate_gps_xy_noise": false,
"replicate_gps_z_noise": false,
"gps_xy_noise_range": 0.00025,
"gps_z_noise_range": 12.5,
"debug": false,
"test": false,
"health_record": true,
Expand Down
42 changes: 42 additions & 0 deletions pokecli.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,48 @@ def _json_loader(filename):
type=float,
default=1000
)
add_config(
parser,
load,
long_flag="--replicate_gps_xy_noise",
help="Add noise to current position",
type=bool,
default=False
)
add_config(
parser,
load,
long_flag="--replicate_gps_z_noise",
help="Add noise to current position",
type=bool,
default=False
)
add_config(
parser,
load,
long_flag="--gps_xy_noise_range",
help="Intensity of gps noise (unit is lat and lng,) high values may cause issues (default=0.00025)",
type=float,
default=0.00025
)
add_config(
parser,
load,
long_flag="--gps_z_noise_range",
help="Intensity of gps noise (unit is in meter, default=12.5)",
type=float,
default=12.5
)
add_config(
parser,
load,
long_flag="--gps_default_altitude",
help="Initial altitude (default=8.0)",
type=float,
default=8.0
)


# Start to parse other attrs
config = parser.parse_args()
if not config.username and 'username' not in load:
Expand Down
17 changes: 8 additions & 9 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@
class PokemonGoBot(Datastore):
@property
def position(self):
return self.api._position_lat, self.api._position_lng, self.api._position_alt
return self.api.actual_lat, self.api.actual_lng, self.api.actual_alt

@position.setter
def position(self, position_tuple):
self.api._position_lat, self.api._position_lng, self.api._position_alt = position_tuple
#@position.setter # these should be called through api now that gps replication is there...
#def position(self, position_tuple):
# self.api._position_lat, self.api._position_lng, self.api._position_alt = position_tuple

@property
def player_data(self):
Expand Down Expand Up @@ -78,7 +78,7 @@ def __init__(self, config):
self.last_map_object = None
self.last_time_map_object = 0
self.logger = logging.getLogger(type(self).__name__)
self.alt = 1
self.alt = self.config.gps_default_altitude

# Make our own copy of the workers for this instance
self.workers = []
Expand Down Expand Up @@ -683,9 +683,8 @@ def check_session(self, position):
level='info',
formatted='Session stale, re-logging in.'
)
position = self.position
self.api = ApiWrapper(config=self.config)
self.position = position
self.api.set_position(*self.position)
self.login()
self.api.activate_signature(self.get_encryption_lib())

Expand All @@ -705,7 +704,7 @@ def login(self):
formatted="Login procedure started."
)
lat, lng = self.position[0:2]
self.api.set_position(lat, lng, 0)
self.api.set_position(lat, lng, self.alt) # or should the alt kept to zero?

while not self.api.login(
self.config.auth_service,
Expand Down Expand Up @@ -1043,7 +1042,7 @@ def get_pos_by_name(self, location_name):
'[x] Coordinates found in passed in location, '
'not geocoding.'
)
return float(possible_coordinates[0]), float(possible_coordinates[1]), float("0.0")
return float(possible_coordinates[0]), float(possible_coordinates[1]), self.alt

geolocator = GoogleV3(api_key=self.config.gmapkey)
loc = geolocator.geocode(location_name, timeout=10)
Expand Down
26 changes: 25 additions & 1 deletion pokemongo_bot/api_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from pgoapi.protos.POGOProtos.Networking.Envelopes.Signature_pb2 import Signature
from pgoapi.utilities import get_time
from pokemongo_bot.datastore import Datastore
from human_behaviour import sleep
from human_behaviour import sleep, gps_noise_rng
from pokemongo_bot.base_dir import _base_dir

class PermaBannedException(Exception):
Expand All @@ -25,6 +25,9 @@ class ApiWrapper(Datastore, PGoApi):

def __init__(self, config=None):
PGoApi.__init__(self)
# Set to default, just for CI...
self.actual_lat, self.actual_lng, self.actual_alt = PGoApi.get_position(self)

self.useVanillaRequest = False
self.config = config
did_path = os.path.join(_base_dir, 'data', 'deviceid-%s.txt' % self.config.username)
Expand Down Expand Up @@ -67,6 +70,27 @@ def login(self, *args):
self.useVanillaRequest = False
return ret_value

def set_position(self, lat, lng, alt=None):
self.actual_lat = lat
self.actual_lng = lng
if None != alt:
self.actual_alt = alt
else:
alt = self.actual_alt

if self.config.replicate_gps_xy_noise:
lat_noise = gps_noise_rng(self.config.gps_xy_noise_range)
lng_noise = gps_noise_rng(self.config.gps_xy_noise_range)
lat = lat + lat_noise
lng = lng + lng_noise
if self.config.replicate_gps_z_noise:
alt_noise = gps_noise_rng(self.config.gps_z_noise_range)
alt = alt + alt_noise
PGoApi.set_position(self, lat, lng, alt)

def get_position(self):
return (self.actual_lat, self.actual_lng, self.actual_alt)


class ApiRequest(PGoApiRequest):
def __init__(self, *args):
Expand Down
10 changes: 9 additions & 1 deletion pokemongo_bot/human_behaviour.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-

import time
from random import random, uniform
from random import random, uniform, gauss


def sleep(seconds, delta=0.3):
Expand All @@ -25,3 +25,11 @@ def random_lat_long_delta():
# should be 364,000 * .000025 = 9.1. So it returns between [-9.1, 9.1]
return ((random() * 0.00001) - 0.000005) * 5

def gps_noise_rng(radius):
'''
Simulates gps noise.
'''
noise = gauss(0, radius/3.0)
noise = min(max(-radius, noise), radius)
return noise

Empty file modified setup.sh
100755 → 100644
Empty file.
17 changes: 17 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@
from pokemongo_bot.api_wrapper import ApiWrapper, ApiRequest
from pokemongo_bot import PokemonGoBot

import json

def get_fake_conf():
class ConfObj:
pass

conf_dict = json.load(open('configs/config.json.example'))
conf_obj = ConfObj()
for key, value in conf_dict.items():
setattr(conf_obj, key, value)

return conf_obj


class FakeApi(ApiWrapper):
def __init__(self):
super(FakeApi, self).__init__(get_fake_conf())

def create_request(self, return_value='mock return'):
request = ApiWrapper.create_request(self)
request.can_call = MagicMock(return_value=True)
Expand Down
10 changes: 5 additions & 5 deletions tests/api_wrapper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,33 @@
from mock import MagicMock, patch
from timeout_decorator import timeout, TimeoutError

from tests import FakeApi
from tests import FakeApi, get_fake_conf

from pgoapi import PGoApi
from pgoapi.exceptions import NotLoggedInException, ServerBusyOrOfflineException, NoPlayerPositionSetException, EmptySubrequestChainException
from pokemongo_bot.api_wrapper import ApiWrapper

class TestApiWrapper(unittest.TestCase):
def test_raises_not_logged_in_exception(self):
api = ApiWrapper()
api = ApiWrapper(get_fake_conf())
api.set_position(*(42, 42, 0))
request = api.create_request()
request.get_inventory(test='awesome')
with self.assertRaises(NotLoggedInException):
request.call()

def test_api_call_with_no_requests_set(self):
request = ApiWrapper().create_request()
request = ApiWrapper(get_fake_conf()).create_request()
with self.assertRaises(EmptySubrequestChainException):
request.call()

def test_api_wrong_request(self):
request = ApiWrapper().create_request()
request = ApiWrapper(get_fake_conf()).create_request()
with self.assertRaises(AttributeError):
request.wrong_request()

def test_raises_no_player_position_set_exception(self):
request = ApiWrapper().create_request()
request = ApiWrapper(get_fake_conf()).create_request()
request.get_inventory(test='awesome')
with self.assertRaises(NoPlayerPositionSetException):
request.call()
Expand Down