Exemple #1
0
    def _walk_after_teleport(self, walk_distance_post_teleport) -> float:
        """
        Args:
            walk_distance_post_teleport:

        Returns:
            Distance walked in one way
        """
        lat_offset, lng_offset = get_lat_lng_offsets_by_distance(
            walk_distance_post_teleport)
        to_walk = get_distance_of_two_points_in_meters(
            float(self.current_location.lat), float(self.current_location.lng),
            float(self.current_location.lat) + lat_offset,
            float(self.current_location.lng) + lng_offset)
        self.logger.info("Walking roughly: {:.2f}m", to_walk)
        time.sleep(0.3)
        self._communicator.walk_from_to(
            self.current_location,
            Location(self.current_location.lat + lat_offset,
                     self.current_location.lng + lng_offset),
            WALK_AFTER_TELEPORT_SPEED)
        self.logger.debug("Walking back")
        time.sleep(0.3)
        self._communicator.walk_from_to(
            Location(self.current_location.lat + lat_offset,
                     self.current_location.lng + lng_offset),
            self.current_location, WALK_AFTER_TELEPORT_SPEED)
        self.logger.debug("Done walking")
        return to_walk
Exemple #2
0
 def _get_relations_in_range_within_time(self, queue, max_radius):
     relations = {}
     for event in queue:
         for other_event in queue:
             if (event[1].lat == other_event[1].lat
                     and event[1].lng == other_event[1].lng
                     and event not in relations.keys()):
                 relations[event] = []
             distance = get_distance_of_two_points_in_meters(
                 event[1].lat, event[1].lng, other_event[1].lat,
                 other_event[1].lng)
             # we will always build relations from the event at hand subtracted by the event inspected
             timedelta = event[0] - other_event[0]
             if 0 <= distance <= max_radius * 2 and 0 <= timedelta <= self.max_timedelta_seconds:
                 if event not in relations.keys():
                     relations[event] = []
                 # avoid duplicates
                 already_present = False
                 for relation in relations[event]:
                     if (relation[0][1].lat == other_event[1].lat
                             and relation[0][1].lng == other_event[1].lng):
                         already_present = True
                 if not already_present:
                     relations[event].append(
                         Relation(other_event, distance, timedelta))
     return relations
Exemple #3
0
    def _check_data_distance(self, data):
        max_radius = self._mapping_manager.routemanager_get_max_radius(
            self._routemanager_name)
        if not max_radius:
            return True
        max_radius: int = self._applicationArgs.maximum_valid_distance \
            if max_radius < self._applicationArgs.maximum_valid_distance else max_radius
        mode = self._mapping_manager.routemanager_get_mode(
            self._routemanager_name)
        if mode in ["mon_mitm", "iv_mitm"]:
            data_to_check = "wild_pokemon"
        else:
            data_to_check = "forts"
        lat_sum, lng_sum, counter = 0, 0, 0

        if data_to_check == "forts":
            for cell in data:
                if cell[data_to_check]:
                    cell_id = cell["id"]
                    if cell_id < 0:
                        cell_id = cell_id + 2**64
                    lat, lng, alt = S2Helper.get_position_from_cell(cell_id)
                    counter += 1
                    lat_sum += lat
                    lng_sum += lng
        else:
            for cell in data:
                for element in cell[data_to_check]:
                    counter += 1
                    lat_sum += element["latitude"]
                    lng_sum += element["longitude"]

        if counter == 0:
            return None
        avg_lat = lat_sum / counter
        avg_lng = lng_sum / counter
        distance = get_distance_of_two_points_in_meters(
            float(avg_lat), float(avg_lng), float(self.current_location.lat),
            float(self.current_location.lng))
        if distance > max_radius:
            logger.debug2(
                "Data is too far away!! avg location {}, {} from "
                "data with self.current_location location {}, {} - that's a "
                "{}m distance with max_radius {} for mode {}", avg_lat,
                avg_lng, self.current_location.lat, self.current_location.lng,
                distance, max_radius, mode)
            return False
        else:
            logger.debug(
                "Data distance is ok! found avg location {}, {} "
                "from data with self.current_location location {}, {} - that's "
                "a {}m distance with max_radius {} for mode {}", avg_lat,
                avg_lng, self.current_location.lat, self.current_location.lng,
                distance, max_radius, mode)
            return True
Exemple #4
0
 def _get_route_manager_settings_and_distance_to_current_location(self):
     if not self._mapping_manager.routemanager_present(self._routemanager_name) \
             or self._stop_worker_event.is_set():
         raise InternalStopWorkerException
     routemanager_settings = self._mapping_manager.routemanager_get_settings(
         self._routemanager_name)
     distance = get_distance_of_two_points_in_meters(
         float(self.last_location.lat), float(self.last_location.lng),
         float(self.current_location.lat), float(self.current_location.lng))
     self.logger.debug('Moving {} meters to the next position',
                       round(distance, 2))
     return distance, routemanager_settings
Exemple #5
0
 def walk_from_to(self, location_from: Location, location_to: Location, speed: float) -> Optional[MessageTyping]:
     # calculate the time it will take to walk and add it to the timeout!
     distance = get_distance_of_two_points_in_meters(
         location_from.lat, location_from.lng,
         location_to.lat, location_to.lng)
     # speed is in kmph, distance in m
     # we want m/s -> speed / 3.6
     speed_meters = speed / 3.6
     seconds_traveltime = distance / speed_meters
     return self.__run_get_gesponse("geo walk {} {} {} {} {}\r\n".format(location_from.lat, location_from.lng,
                                                                         location_to.lat, location_to.lng,
                                                                         speed),
                                    self.__command_timeout + seconds_traveltime)
Exemple #6
0
    def _get_count_and_coords_in_circle_within_timedelta(
            self, middle, relations, earliest_timestamp, latest_timestamp,
            max_radius):
        inside_circle = []
        highest_timedelta = 0
        if self.useS2:
            region = s2sphere.CellUnion(
                S2Helper.get_S2cells_from_circle(middle.lat, middle.lng,
                                                 self.max_radius,
                                                 self.S2level))

        for event_relations in relations:
            # exclude previously clustered events...
            if len(event_relations) == 4 and event_relations[3]:
                inside_circle.append(event_relations)
                continue
            distance = get_distance_of_two_points_in_meters(
                middle.lat, middle.lng, event_relations[1].lat,
                event_relations[1].lng)
            event_in_range = 0 <= distance <= max_radius
            if self.useS2:
                event_in_range = region.contains(
                    s2sphere.LatLng.from_degrees(
                        event_relations[1].lat,
                        event_relations[1].lng).to_point())
            # timedelta of event being inspected to the earliest timestamp
            timedelta_end = latest_timestamp - event_relations[0]
            timedelta_start = event_relations[0] - earliest_timestamp
            if timedelta_end < 0 and event_in_range:
                # we found an event starting past the current latest timestamp, let's update the latest_timestamp
                latest_timestamp_temp = latest_timestamp + abs(timedelta_end)
                if latest_timestamp_temp - earliest_timestamp <= self.max_timedelta_seconds:
                    latest_timestamp = latest_timestamp_temp
                    highest_timedelta = highest_timedelta + abs(timedelta_end)
                    inside_circle.append(event_relations)
            elif timedelta_start < 0 and event_in_range:
                # we found an event starting before earliest_timestamp, let's check that...
                earliest_timestamp_temp = earliest_timestamp - \
                                          abs(timedelta_start)
                if latest_timestamp - earliest_timestamp_temp <= self.max_timedelta_seconds:
                    earliest_timestamp = earliest_timestamp_temp
                    highest_timedelta = highest_timedelta + \
                                        abs(timedelta_start)
                    inside_circle.append(event_relations)
            elif timedelta_end >= 0 and timedelta_start >= 0 and event_in_range:
                # we found an event within our current timedelta and proximity, just append it to the list
                inside_circle.append(event_relations)

        return len(
            inside_circle), inside_circle, highest_timedelta, latest_timestamp
Exemple #7
0
 def walkFromTo(self, startLat, startLng, destLat, destLng, speed):
     with self.__sendMutex:
         # calculate the time it will take to walk and add it to the timeout!
         distance = get_distance_of_two_points_in_meters(
             startLat, startLng, destLat, destLng)
         # speed is in kmph, distance in m
         # we want m/s -> speed / 3.6
         speed_meters = speed / 3.6
         seconds_traveltime = distance / speed_meters
         response = self.websocket_handler.send_and_wait(
             self.worker_id, self.worker_instance_ref,
             "geo walk {} {} {} {} {}\r\n".format(startLat, startLng,
                                                  destLat, destLng, speed),
             self.__command_timeout + seconds_traveltime)
         return response
Exemple #8
0
    def _generate_locations(distance: float, geofence_helper: GeofenceHelper):
        south, east, north, west = geofence_helper.get_polygon_from_fence()

        corners = [
            Location(south, east),
            Location(south, west),
            Location(north, east),
            Location(north, west)
        ]
        # get the center
        center = get_middle_of_coord_list(corners)

        # get the farthest to the center...
        farthest_dist = 0
        for corner in corners:
            dist_temp = get_distance_of_two_points_in_meters(
                center.lat, center.lng, corner.lat, corner.lng)
            if dist_temp > farthest_dist:
                farthest_dist = dist_temp

        # calculate step_limit, round up to reduce risk of losing stuff
        step_limit = math.ceil(farthest_dist / distance)

        # This will loop thorugh all the rings in the hex from the centre
        # moving outwards
        logger.info("Calculating positions for init scan")
        num_cores = multiprocessing.cpu_count()
        with multiprocessing.Pool(processes=num_cores) as pool:
            temp = [pool.apply(S2Helper._generate_star_locs, args=(
                center, distance, i)) for i in range(1, step_limit)]

        results = [item for sublist in temp for item in sublist]
        results.append(Location(center.lat, center.lng))

        logger.info("Filtering positions for init scan")
        # Geofence results.
        if geofence_helper is not None and geofence_helper.is_enabled():
            results = geofence_helper.get_geofenced_coordinates(results)
            if not results:
                logger.error('No cells regarded as valid for desired scan area. Check your provided geofences. '
                             'Aborting.')
            else:
                logger.info("Ordering location")
                results = S2Helper.order_location_list_rows(results)
        return results
Exemple #9
0
 def _is_location_within_allowed_range(self, latest_location):
     self.logger.debug2(
         "Checking (data) location reported by {} at {} against real data location {}",
         self._origin, self.current_location, latest_location)
     distance_to_data = get_distance_of_two_points_in_meters(
         float(latest_location.lat), float(latest_location.lng),
         float(self.current_location.lat), float(self.current_location.lng))
     max_distance_of_mode = self._mapping_manager.routemanager_get_max_radius(
         self._routemanager_name)
     max_distance_for_worker = self._applicationArgs.maximum_valid_distance
     if max_distance_for_worker > max_distance_of_mode > MINIMUM_DISTANCE_ALLOWANCE_FOR_GMO:
         # some modes may be too strict (e.g. quests with 0.0001m calculations for routes)
         # yet, the route may "require" a stricter ruling than max valid distance
         max_distance_for_worker = max_distance_of_mode
     self.logger.debug2("Distance of worker {} to (data) location: {}",
                        self._origin, distance_to_data)
     if distance_to_data > max_distance_for_worker:
         self.logger.debug(
             "Location too far from worker position, max distance allowed: {}m",
             max_distance_for_worker)
     return distance_to_data <= max_distance_for_worker
Exemple #10
0
    def _wait_for_data(self,
                       timestamp: float = None,
                       proto_to_wait_for=106,
                       timeout=None):
        if timestamp is None:
            timestamp = time.time()

        if timeout is None:
            timeout = self.get_devicesettings_value("mitm_wait_timeout", 45)

        # since the GMOs may only contain mons if we are not "too fast" (which is the case when teleporting) after
        # waiting a certain period of time (usually the 2nd GMO), we will multiply the timeout by 2 for mon-modes
        mode = self._mapping_manager.routemanager_get_mode(
            self._routemanager_name)
        if mode in ["mon_mitm", "iv_mitm"
                    ] or self._mapping_manager.routemanager_get_init(
                        self._routemanager_name):
            timeout *= 2
        # let's fetch the latest data to add the offset to timeout (in case device and server times are off...)
        latest = self._mitm_mapper.request_latest(self._origin)
        timestamp_last_data = latest.get("timestamp_last_data", 0)
        timestamp_last_received = latest.get("timestamp_receiver", 0)

        # we can now construct the rough estimate of the diff of time of mobile vs time of server, subtract our
        # timestamp by the diff
        # TODO: discuss, probably wiser to add to timeout or get the diff of how long it takes for RGC to issue a cmd
        timestamp = timestamp - (timestamp_last_received - timestamp_last_data)

        self.logger.info('Waiting for data after {}',
                         datetime.fromtimestamp(timestamp))
        data_requested = LatestReceivedType.UNDEFINED

        failover_timestamp: int = time.time()

        while data_requested == LatestReceivedType.UNDEFINED and \
                (timestamp + timeout >= int(time.time()) and int(failover_timestamp + timeout) >= int(time.time())) \
                and not self._stop_worker_event.is_set():
            latest = self._mitm_mapper.request_latest(self._origin)
            latest_location: Optional[Location] = latest.get("location", None)
            check_data = True
            if (proto_to_wait_for == 106 and latest_location is not None
                    and latest_location.lat != 0.0
                    and latest_location.lng != 0.0):
                self.logger.debug(
                    "Checking worker location {} against real data location {}",
                    self.current_location, latest_location)
                distance_to_data = get_distance_of_two_points_in_meters(
                    float(latest_location.lat), float(latest_location.lng),
                    float(self.current_location.lat),
                    float(self.current_location.lng))
                max_distance_of_mode = self._mapping_manager.routemanager_get_max_radius(
                    self._routemanager_name)
                max_distance_for_worker: int = self._applicationArgs.maximum_valid_distance \
                    if max_distance_of_mode < self._applicationArgs.maximum_valid_distance else max_distance_of_mode
                self.logger.debug("Distance of worker {} to data location: {}",
                                  self._origin, distance_to_data)
                if max_distance_for_worker and distance_to_data > max_distance_for_worker:
                    self.logger.debug(
                        "Real data too far from worker position, waiting...")
                    check_data = False

            if check_data:
                data_requested = self._wait_data_worker(
                    latest, proto_to_wait_for, timestamp)
            if not self._mapping_manager.routemanager_present(self._routemanager_name) \
                    or self._stop_worker_event.is_set():
                self.logger.error("killed while sleeping")
                raise InternalStopWorkerException

            time.sleep(1)

        position_type = self._mapping_manager.routemanager_get_position_type(
            self._routemanager_name, self._origin)
        if position_type is None:
            self.logger.warning(
                "Mappings/Routemanagers have changed, stopping worker to be created again"
            )
            raise InternalStopWorkerException
        if data_requested != LatestReceivedType.UNDEFINED:
            self.logger.success('Got the data requested')
            self._reboot_count = 0
            self._restart_count = 0
            self._rec_data_time = datetime.now()

            self._mitm_mapper.collect_location_stats(
                self._origin, self.current_location, 1,
                self._waittime_without_delays, position_type, time.time(),
                self._mapping_manager.routemanager_get_mode(
                    self._routemanager_name), self._transporttype)

        else:
            # TODO: timeout also happens if there is no useful data such as mons nearby in mon_mitm mode, we need to
            # TODO: be more precise (timeout vs empty data)
            self.logger.warning("Timeout waiting for data")

            self._mitm_mapper.collect_location_stats(
                self._origin, self.current_location, 0,
                self._waittime_without_delays, position_type, 0,
                self._mapping_manager.routemanager_get_mode(
                    self._routemanager_name), self._transporttype)

            self._restart_count += 1

            restart_thresh = self.get_devicesettings_value("restart_thresh", 5)
            reboot_thresh = self.get_devicesettings_value("reboot_thresh", 3)
            if self._mapping_manager.routemanager_get_route_stats(
                    self._routemanager_name, self._origin) is not None:
                if self._init:
                    restart_thresh = self.get_devicesettings_value(
                        "restart_thresh", 5) * 2
                    reboot_thresh = self.get_devicesettings_value(
                        "reboot_thresh", 3) * 2

            if self._restart_count > restart_thresh:
                self._reboot_count += 1
                if self._reboot_count > reboot_thresh \
                        and self.get_devicesettings_value("reboot", True):
                    self.logger.error("Too many timeouts - Rebooting device")
                    self._reboot(mitm_mapper=self._mitm_mapper)
                    raise InternalStopWorkerException

                # self._mitm_mapper.
                self._restart_count = 0
                self.logger.error("Too many timeouts - Restarting game")
                self._restart_pogo(True, self._mitm_mapper)

        self.worker_stats()
        return data_requested
Exemple #11
0
    def statistics_detection_worker_data(self):
        minutes = request.args.get('minutes', 120)
        worker = request.args.get('worker')

        # spawns
        mon = []
        mon_iv = []
        raid = []
        quest = []
        usage = []

        data = self._db_stats_reader.get_detection_count(minutes=minutes,
                                                         worker=worker)
        for dat in data:
            mon.append([dat[0] * 1000, int(dat[2])])
            mon_iv.append([dat[0] * 1000, int(dat[3])])
            raid.append([dat[0] * 1000, int(dat[4])])
            quest.append([dat[0] * 1000, int(dat[5])])

        usage.append({'label': 'Mon', 'data': mon})
        usage.append({'label': 'Mon_IV', 'data': mon_iv})
        usage.append({'label': 'Raid', 'data': raid})
        usage.append({'label': 'Quest', 'data': quest})

        # locations avg
        locations_avg = []

        data = self._db_stats_reader.get_avg_data_time(minutes=minutes,
                                                       worker=worker)
        for dat in data:
            dtime = datetime.datetime.fromtimestamp(dat[0]).strftime(
                self._datetimeformat)
            locations_avg.append({
                'dtime': dtime,
                'ok_locations': dat[3],
                'avg_datareceive': float(dat[4]),
                'transporttype': dat[1],
                'type': dat[5]
            })

        # locations
        ok = []
        nok = []
        sumloc = []
        locations = []
        data = self._db_stats_reader.get_locations(minutes=minutes,
                                                   worker=worker)
        for dat in data:
            ok.append([dat[0] * 1000, int(dat[3])])
            nok.append([dat[0] * 1000, int(dat[4])])
            sumloc.append([dat[0] * 1000, int(dat[2])])

        locations.append({'label': 'Locations', 'data': sumloc})
        locations.append({'label': 'Locations_ok', 'data': ok})
        locations.append({'label': 'Locations_nok', 'data': nok})

        # dataratio
        loctionratio = []
        data = self._db_stats_reader.get_locations_dataratio(minutes=minutes,
                                                             worker=worker)
        if len(data) > 0:
            for dat in data:
                loctionratio.append({'label': dat[3], 'data': dat[2]})
        else:
            loctionratio.append({'label': '', 'data': 0})

        # all spaws
        all_spawns = []
        data = self._db_stats_reader.get_detection_count(grouped=False,
                                                         worker=worker)
        all_spawns.append({'type': 'Mon', 'amount': int(data[0][2])})
        all_spawns.append({'type': 'Mon_IV', 'amount': int(data[0][3])})
        all_spawns.append({'type': 'Raid', 'amount': int(data[0][4])})
        all_spawns.append({'type': 'Quest', 'amount': int(data[0][5])})

        # raw detection data
        detections_raw = []
        data, data2 = self._db_stats_reader.get_detection_raw(minutes=minutes,
                                                              worker=worker)
        for dat in data:
            detections_raw.append({
                'type': dat[1],
                'id': dat[2],
                'count': dat[3]
            })
        for dat in data2:
            detections_raw.append({
                'type': dat[1],
                'id': dat[2],
                'count': dat[3]
            })

        # location raw
        location_raw = []
        last_lat = 0
        last_lng = 0
        distance = 0
        data = self._db_stats_reader.get_location_raw(minutes=minutes,
                                                      worker=worker)
        for dat in data:
            if last_lat != 0 and last_lng != 0:
                distance = round(
                    get_distance_of_two_points_in_meters(
                        last_lat, last_lng, dat[1], dat[2]), 2)
                last_lat = dat[1]
                last_lng = dat[2]
            if last_lat == 0 and last_lng == 0:
                last_lat = dat[1]
                last_lng = dat[2]
            if dat[1] == 0 and dat[2] == 0:
                distance = ''

            location_raw.append({
                'lat':
                dat[1],
                'lng':
                dat[2],
                'distance':
                distance,
                'type':
                dat[3],
                'data':
                dat[4],
                'fix_ts':
                datetime.datetime.fromtimestamp(dat[5]).strftime(
                    self._datetimeformat),
                'data_ts':
                datetime.datetime.fromtimestamp(dat[6]).strftime(
                    self._datetimeformat),
                'transporttype':
                dat[8]
            })

        workerstats = {
            'avg': locations_avg,
            'receiving': usage,
            'locations': locations,
            'ratio': loctionratio,
            'allspawns': all_spawns,
            'detections_raw': detections_raw,
            'location_raw': location_raw
        }
        return jsonify(workerstats)
Exemple #12
0
    def _check_if_stop_was_nearby_and_update_location(self, gmo_cells):
        self.logger.info("Checking stops around current location ({}) for deleted stops.", self.current_location)
        stops: Dict[str, Tuple[Location, datetime]] = self._db_wrapper.get_stop_ids_and_locations_nearby(
            self.current_location
        )
        self.logger.debug("Checking if GMO contains location changes or DB has stops that are already deleted. In DB: "
                          "{}. GMO cells: {}", str(stops), gmo_cells)
        # stops may contain multiple stops now. We can check each ID (key of dict) with the IDs in the GMO.
        # Then cross check against the location. If that differs, we need to update/delete the entries in the DB
        for cell in gmo_cells:
            forts: list = cell.get("forts", None)
            if not forts:
                continue

            for fort in forts:
                latitude: float = fort.get("latitude", None)
                longitude: float = fort.get("longitude", None)
                fort_id: str = fort.get("id", None)
                if not latitude or not longitude or not fort_id:
                    self.logger.warning("Cannot process fort without id, lat or lon")
                    continue
                location_last_updated: Tuple[Location, datetime] = stops.get(fort_id)
                if location_last_updated is None:
                    # new stop we have not seen before, MITM processors should take care of that
                    self.logger.debug2("Stop not in DB (in range) with ID {} at {}, {}", fort_id, latitude, longitude)
                    continue
                else:
                    stops.pop(fort_id)
                stop_location_known, last_updated = location_last_updated
                if stop_location_known.lat == latitude and stop_location_known.lng == longitude:
                    # Location of fort has not changed
                    self.logger.debug2("Fort {} has not moved", fort_id)
                    continue
                else:
                    # now we have a location from DB for the given stop we are currently processing but does not equal
                    # the one we are currently processing, thus SAME fort_id
                    # now update the stop
                    self.logger.warning("Updating fort {} with previous location {} now placed at {}, {}",
                                        fort_id, str(stop_location_known), latitude, longitude)
                    self._db_wrapper.update_pokestop_location(fort_id, latitude, longitude)

        timedelta_to_consider_deletion = timedelta(days=3)
        for fort_id in stops.keys():
            # Call delete of stops that have been not been found within 100m range of current position
            stop_location_known, last_updated = stops[fort_id]
            self.logger.debug("Considering stop {} at {} (last updated {}) for deletion",
                              fort_id, stop_location_known, last_updated)
            if last_updated and last_updated > datetime.now() - timedelta_to_consider_deletion:
                self.logger.info("Stop considered for deletion was last updated recently, not gonna delete it for now.",
                                 last_updated)
                continue
            distance_to_location = get_distance_of_two_points_in_meters(float(stop_location_known.lat),
                                                                        float(stop_location_known.lng),
                                                                        float(self.current_location.lat),
                                                                        float(self.current_location.lng))
            self.logger.debug("Distance to {} at {} (last updated {})",
                              fort_id, stop_location_known, last_updated)
            if distance_to_location < 100:
                self.logger.warning(
                    "Deleting stop {} at {} since it could not be found in the GMO but was present in DB and within "
                    "100m of worker ({}m) and was last updated more than 3 days ago ()",
                    fort_id, str(stop_location_known), distance_to_location, last_updated)
                self._db_wrapper.delete_stop(stop_location_known.lat, stop_location_known.lng)
                self._mapping_manager.routemanager_add_coords_to_be_removed(self._routemanager_name,
                                                                            stop_location_known.lat,
                                                                            stop_location_known.lng)
Exemple #13
0
    def _move_to_location(self):
        if not self._mapping_manager.routemanager_present(self._routemanager_name) \
                or self._stop_worker_event.is_set():
            raise InternalStopWorkerException
        routemanager_settings = self._mapping_manager.routemanager_get_settings(
            self._routemanager_name)
        # get the distance from our current position (last) to the next gym (cur)
        distance = get_distance_of_two_points_in_meters(
            float(self.last_location.lat), float(self.last_location.lng),
            float(self.current_location.lat), float(self.current_location.lng))
        logger.debug('Moving {} meters to the next position',
                     round(distance, 2))
        if not self._mapping_manager.routemanager_get_init(
                self._routemanager_name):
            speed = routemanager_settings.get("speed", 0)
            max_distance = routemanager_settings.get("max_distance", None)
        else:
            speed = int(25)
            max_distance = int(200)

        if (speed == 0 or (max_distance and 0 < max_distance < distance) or
            (self.last_location.lat == 0.0 and self.last_location.lng == 0.0)):
            logger.debug("main: Teleporting...")
            self._transporttype = 0
            self._communicator.set_location(
                Location(self.current_location.lat, self.current_location.lng),
                0)
            # the time we will take as a starting point to wait for data...
            cur_time = math.floor(time.time())

            delay_used = self.get_devicesettings_value('post_teleport_delay',
                                                       7)
            # Test for cooldown / teleported distance TODO: check this block...
            if self.get_devicesettings_value('cool_down_sleep', False):
                if distance > 10000:
                    delay_used = 15
                elif distance > 5000:
                    delay_used = 10
                elif distance > 2500:
                    delay_used = 8
                logger.debug("Need more sleep after Teleport: {} seconds!",
                             str(delay_used))
                # curTime = math.floor(time.time())  # the time we will take as a starting point to wait for data...
            walk_distance_post_teleport = self.get_devicesettings_value(
                'walk_after_teleport_distance', 0)
            if 0 < walk_distance_post_teleport < distance:
                # TODO: actually use to_walk for distance
                lat_offset, lng_offset = get_lat_lng_offsets_by_distance(
                    walk_distance_post_teleport)

                to_walk = get_distance_of_two_points_in_meters(
                    float(self.current_location.lat),
                    float(self.current_location.lng),
                    float(self.current_location.lat) + lat_offset,
                    float(self.current_location.lng) + lng_offset)
                logger.info("Walking roughly: {}", str(to_walk))
                time.sleep(0.3)
                self._communicator.walk_from_to(
                    self.current_location,
                    Location(self.current_location.lat + lat_offset,
                             self.current_location.lng + lng_offset), 11)
                logger.debug("Walking back")
                time.sleep(0.3)
                self._communicator.walk_from_to(
                    Location(self.current_location.lat + lat_offset,
                             self.current_location.lng + lng_offset),
                    self.current_location, 11)
                logger.debug("Done walking")
                time.sleep(1)
        else:
            logger.info("main: Walking...")
            self._transporttype = 1
            self._communicator.walk_from_to(self.last_location,
                                            self.current_location, speed)
            # the time we will take as a starting point to wait for data...
            cur_time = math.floor(time.time())
            logger.debug2("Done walking, fetching time to sleep")
            delay_used = self.get_devicesettings_value('post_walk_delay', 7)
        logger.debug2("Sleeping for {}s".format(str(delay_used)))
        time.sleep(float(delay_used))
        self.set_devicesettings_value("last_location", self.current_location)
        self.last_location = self.current_location
        self._waittime_without_delays = time.time()
        return cur_time, True
Exemple #14
0
    def _move_to_location(self):
        if not self._mapping_manager.routemanager_present(self._routemanager_name) \
                or self._stop_worker_event.is_set():
            raise InternalStopWorkerException

        routemanager_settings = self._mapping_manager.routemanager_get_settings(
            self._routemanager_name)

        distance = get_distance_of_two_points_in_meters(
            float(self.last_location.lat), float(self.last_location.lng),
            float(self.current_location.lat), float(self.current_location.lng))
        self.logger.debug('Moving {} meters to the next position',
                          round(distance, 2))

        delay_used = 0
        self.logger.debug("Getting time")
        speed = routemanager_settings.get("speed", 0)
        max_distance = routemanager_settings.get("max_distance", None)
        if (speed == 0 or (max_distance and 0 < max_distance < distance) or
            (self.last_location.lat == 0.0 and self.last_location.lng == 0.0)):
            self.logger.debug("main: Teleporting...")
            self._transporttype = 0
            self._communicator.set_location(
                Location(self.current_location.lat, self.current_location.lng),
                0)
            # the time we will take as a starting point to wait for data...
            cur_time = math.floor(time.time())

            delay_used = self.get_devicesettings_value('post_teleport_delay',
                                                       0)
            speed = 16.67  # Speed can be 60 km/h up to distances of 3km

            if self.last_location.lat == 0.0 and self.last_location.lng == 0.0:
                self.logger.info('Starting fresh round - using lower delay')
            else:
                if distance >= 1335000:
                    speed = 180.43  # Speed can be abt 650 km/h
                elif distance >= 1100000:
                    speed = 176.2820513
                elif distance >= 1020000:
                    speed = 168.3168317
                elif distance >= 1007000:
                    speed = 171.2585034
                elif distance >= 948000:
                    speed = 166.3157895
                elif distance >= 900000:
                    speed = 164.8351648
                elif distance >= 897000:
                    speed = 166.1111111
                elif distance >= 839000:
                    speed = 158.9015152
                elif distance >= 802000:
                    speed = 159.1269841
                elif distance >= 751000:
                    speed = 152.6422764
                elif distance >= 700000:
                    speed = 151.5151515
                elif distance >= 650000:
                    speed = 146.3963964
                elif distance >= 600000:
                    speed = 142.8571429
                elif distance >= 550000:
                    speed = 138.8888889
                elif distance >= 500000:
                    speed = 134.4086022
                elif distance >= 450000:
                    speed = 129.3103448
                elif distance >= 400000:
                    speed = 123.4567901
                elif distance >= 350000:
                    speed = 116.6666667
                elif distance >= 328000:
                    speed = 113.8888889
                elif distance >= 300000:
                    speed = 108.6956522
                elif distance >= 250000:
                    speed = 101.6260163
                elif distance >= 201000:
                    speed = 90.54054054
                elif distance >= 175000:
                    speed = 85.78431373
                elif distance >= 150000:
                    speed = 78.125
                elif distance >= 125000:
                    speed = 71.83908046
                elif distance >= 100000:
                    speed = 64.1025641
                elif distance >= 90000:
                    speed = 60
                elif distance >= 80000:
                    speed = 55.55555556
                elif distance >= 70000:
                    speed = 50.72463768
                elif distance >= 60000:
                    speed = 47.61904762
                elif distance >= 45000:
                    speed = 39.47368421
                elif distance >= 40000:
                    speed = 35.0877193
                elif distance >= 35000:
                    speed = 32.40740741
                elif distance >= 30000:
                    speed = 29.41176471
                elif distance >= 25000:
                    speed = 27.77777778
                elif distance >= 20000:
                    speed = 27.77777778
                elif distance >= 15000:
                    speed = 27.77777778
                elif distance >= 10000:
                    speed = 23.80952381
                elif distance >= 8000:
                    speed = 26.66666667
                elif distance >= 5000:
                    speed = 22.34137623
                elif distance >= 4000:
                    speed = 22.22222222

                delay_used = distance / speed

                if delay_used > 7200:  # There's a maximum of 2 hours wait time
                    delay_used = 7200
            self.logger.debug("Need more sleep after Teleport: {} seconds!",
                              int(delay_used))
        else:
            delay_used = distance / (
                speed / 3.6)  # speed is in kmph , delay_used need mps
            self.logger.info("main: Walking {} m, this will take {} seconds",
                             distance, delay_used)
            self._transporttype = 1
            self._communicator.walk_from_to(self.last_location,
                                            self.current_location, speed)
            # the time we will take as a starting point to wait for data...
            cur_time = math.floor(time.time())
            delay_used = self.get_devicesettings_value('post_walk_delay', 0)
        walk_distance_post_teleport = self.get_devicesettings_value(
            'walk_after_teleport_distance', 0)
        if 0 < walk_distance_post_teleport < distance:
            # TODO: actually use to_walk for distance
            lat_offset, lng_offset = get_lat_lng_offsets_by_distance(
                walk_distance_post_teleport)

            to_walk = get_distance_of_two_points_in_meters(
                float(self.current_location.lat),
                float(self.current_location.lng),
                float(self.current_location.lat) + lat_offset,
                float(self.current_location.lng) + lng_offset)
            self.logger.info("Walking roughly: {:.2f}m", to_walk)
            time.sleep(0.3)
            self._communicator.walk_from_to(
                self.current_location,
                Location(self.current_location.lat + lat_offset,
                         self.current_location.lng + lng_offset), 11)
            self.logger.debug("Walking back")
            time.sleep(0.3)
            self._communicator.walk_from_to(
                Location(self.current_location.lat + lat_offset,
                         self.current_location.lng + lng_offset),
                self.current_location, 11)
            self.logger.debug("Done walking")
            time.sleep(1)
            delay_used -= (
                to_walk / 3.05
            ) - 1.  # We already waited for a bit because of this walking part
            if delay_used < 0:
                delay_used = 0

        if self._init:
            delay_used = 5

        if self.get_devicesettings_value('last_action_time', None) is not None:
            timediff = time.time() - self.get_devicesettings_value(
                'last_action_time', 0)
            self.logger.info("Timediff between now and last action time: {}",
                             int(timediff))
            delay_used = delay_used - timediff
        elif self.get_devicesettings_value(
                'last_action_time', None) is None and not self._level_mode:
            self.logger.info(
                'Starting first time - we wait because of some default pogo delays ...'
            )
            delay_used = 20
        else:
            self.logger.debug("No last action time found - no calculation")
            delay_used = -1

        if self.get_devicesettings_value('screendetection', True) and \
                self._WordToScreenMatching.return_memory_account_count() > 1 and delay_used >= self._rotation_waittime \
                and self.get_devicesettings_value('account_rotation', False) and not self._level_mode:
            # Waiting time to long and more then one account - switch! (not level mode!!)
            self.logger.info(
                'Could use more then 1 account - switch & no cooldown')
            self.switch_account()
            delay_used = -1

        if delay_used < 0:
            self._current_sleep_time = 0
            self.logger.info('No need to wait before spinning, continuing...')
        else:
            delay_used = math.floor(delay_used)
            self.logger.info("Real sleep time: {} seconds: next action {}",
                             delay_used,
                             datetime.now() + timedelta(seconds=delay_used))
            cleanupbox: bool = False
            lastcleanupbox = self.get_devicesettings_value(
                'last_cleanup_time', None)

            self._current_sleep_time = delay_used
            self.worker_stats()

            if lastcleanupbox is not None:
                if time.time() - lastcleanupbox > 900:
                    # just cleanup if last cleanup time > 15 minutes ago
                    cleanupbox = True
            else:
                cleanupbox = True
            self._mapping_manager.routemanager_set_worker_sleeping(
                self._routemanager_name, self._origin, delay_used)
            while time.time() <= int(cur_time) + int(delay_used):
                if delay_used > 200 and cleanupbox and not self._enhanced_mode:
                    self.clear_thread_task = ClearThreadTasks.BOX
                cleanupbox = False
                if not self._mapping_manager.routemanager_present(self._routemanager_name) \
                        or self._stop_worker_event.is_set():
                    self.logger.error("Worker was killed while sleeping")
                    self._current_sleep_time = 0
                    raise InternalStopWorkerException
                time.sleep(1)

        self._current_sleep_time = 0
        self.set_devicesettings_value("last_location", self.current_location)
        self.last_location = self.current_location
        return cur_time, True
Exemple #15
0
    def _generate_locations(distance: float, geofence_helper: GeofenceHelper):
        south, east, north, west = geofence_helper.get_polygon_from_fence()

        corners = [
            Location(south, east),
            Location(south, west),
            Location(north, east),
            Location(north, west)
        ]
        # get the center
        center = get_middle_of_coord_list(corners)

        # get the farthest to the center...
        farthest_dist = 0
        for corner in corners:
            dist_temp = get_distance_of_two_points_in_meters(
                center.lat, center.lng, corner.lat, corner.lng)
            if dist_temp > farthest_dist:
                farthest_dist = dist_temp

        # calculate step_limit, round up to reduce risk of losing stuff
        step_limit = math.ceil(farthest_dist / distance)

        # This will loop thorugh all the rings in the hex from the centre
        # moving outwards
        logger.info("Calculating positions for init scan")
        num_cores = multiprocessing.cpu_count()
        with multiprocessing.Pool(processes=num_cores) as pool:
            temp = [
                pool.apply(S2Helper._generate_star_locs,
                           args=(center, distance, i))
                for i in range(1, step_limit)
            ]

        results = [item for sublist in temp for item in sublist]
        results.append(Location(center.lat, center.lng))

        # for ring in range(1, step_limit):
        #     for i in range(0, 6):
        #         # Star_locs will contain the locations of the 6 vertices of
        #         # the current ring (90,150,210,270,330 and 30 degrees from
        #         # origin) to form a star
        #         star_loc = S2Helper.get_new_coords(center, distance * ring,
        #                                            90 + 60 * i)
        #         for j in range(0, ring):
        #             # Then from each point on the star, create locations
        #             # towards the next point of star along the edge of the
        #             # current ring
        #             loc = S2Helper.get_new_coords(star_loc, distance * j, 210 + 60 * i)
        #             results.append(loc)

        logger.info("Filtering positions for init scan")
        # Geofence results.
        if geofence_helper is not None and geofence_helper.is_enabled():
            results = geofence_helper.get_geofenced_coordinates(results)
            if not results:
                logger.error(
                    'No cells regarded as valid for desired scan area. '
                    'Check your provided geofences. Aborting.')
            else:
                logger.info("Ordering location")
                results = S2Helper.order_location_list_rows(results)
        return results