def __update(self): now = EDTime.py_epoch_now() transits = self.db.execute( 'SELECT id, ship_id, destination_system, destination_market_id FROM transits WHERE eta<=?', (now, )) for transit in transits: self.db.execute( 'UPDATE ships SET star_system=?, ship_market_id=?, eta=0 WHERE id=?', ( transit[2], transit[3], transit[1], )) self.db.execute('DELETE from transits WHERE id=?', (transit[0], )) now = EDTime.py_epoch_now() transits = self.db.execute( 'SELECT id, ship_id, destination_system, destination_market_id, eta FROM transits WHERE eta>?', (now, )) for transit in transits: self.db.execute( 'UPDATE ships SET star_system=?, ship_market_id=?, eta=? WHERE id=?', ( transit[2], transit[3], transit[4], transit[1], )) self.db.commit()
def credits_per_hour(self): now = EDTime.py_epoch_now() self.current = now elapsed_time = self.current - self.start if elapsed_time: return self.sum_awarded / (elapsed_time / 3600.0) return 0
def mineral_per_hour(self): now = EDTime.py_epoch_now() self.current = now elapsed_time = self.current - self.start if elapsed_time: return self.refined_nb / (elapsed_time / 3600.0) return 0
def __init__(self): self.type = None self.size = None self.name = None self.id = None self.identity = None self.rebuy = None self._value = None self.hot = False now = EDTime.py_epoch_now() self._hull_health = {"timestamp": now, "value": 100.0} self._shield_health = {"timestamp": now, "value": 100.0} self.shield_up = True self.subsystems = {} self.timestamp = now self.fight = {u"value": False, "large": False, u"timestamp": now} self._hardpoints_deployed = {u"value": False, u"timestamp": now} self._attacked = {u"value": False, u"timestamp": now} self.heat_damaged = {u"value": False, u"timestamp": now} self._in_danger = {u"value": False, u"timestamp": now} self._low_fuel = {u"value": False, u"timestamp": now} config = edrconfig.EDRConfig() self.fight_staleness_threshold = config.instance_fight_staleness_threshold() self.danger_staleness_threshold = config.instance_danger_staleness_threshold() self.seats = 1 self.fuel_capacity = None self.fuel_level = None self.attitude = EDVehicleAttitude() self.module_info_timestamp = None self.slots_timestamp = None self.slots = {} self.modules = None self.power_capacity = None self.cargo_capacity = 0 self.cargo = edcargo.EDCargo()
def in_a_fight(self): if self.fight["value"]: now = EDTime.py_epoch_now() return (now >= self.fight["timestamp"]) and ( (now - self.fight["timestamp"]) <= self.fight_staleness_threshold) return False
def hardpoints_deployed(self): if self._hardpoints_deployed["value"]: now = EDTime.py_epoch_now() return (now >= self._hardpoints_deployed["timestamp"]) and ( (now - self._hardpoints_deployed["timestamp"]) <= self.fight_staleness_threshold) return False
def in_danger(self): if self._in_danger["value"]: now = EDTime.py_epoch_now() return (now >= self._in_danger["timestamp"]) and ( (now - self._in_danger["timestamp"]) <= self.danger_staleness_threshold) return False
def reset(self): now = EDTime.py_epoch_now() self.timestamp = now self.players = {} self.npcs = {} self.npc_names_to_npcs = {} self._touched = True
def under_attack(self): if self._attacked["value"]: now = EDTime.py_epoch_now() return (now >= self._attacked["timestamp"]) and ( (now - self._attacked["timestamp"]) <= self.danger_staleness_threshold) return False
def transfer(self, transfer_event, dst_system, dst_market_id=""): if self.db is None: return if transfer_event.get("event", None) != "ShipyardTransfer": return ship_id = transfer_event.get("ShipID", None) src_system = transfer_event.get("System", None) src_market_id = transfer_event.get("MarketID", None) distance = transfer_event.get("Distance", None) eta = EDTime.py_epoch_now() + int( math.ceil(distance * 9.75 + 300)) #TODO refactor, 1 more copy of this in edrsystems self.db.execute('DELETE from transits WHERE ship_id=?', (ship_id, )) self.db.execute( '''INSERT INTO transits(ship_id, eta, source_system, source_market_id, destination_system, destination_market_id) VALUES (?,?,?,?,?,?)''', (ship_id, eta, src_system, src_market_id, dst_system, dst_market_id)) self.db.execute( 'UPDATE ships SET ship_market_id=?, star_system=?, piloted=0, eta=? WHERE id=?', ( dst_market_id, dst_system, eta, ship_id, )) self.db.commit() self.__update()
def subsystem_health(self, subsystem, health): if subsystem is None: return canonical = EDVehicleFactory.normalize_module_name(subsystem) now = EDTime.py_epoch_now() self.timestamp = now self.subsystems[canonical] = {u"timestamp": now, u"value": health}
def debug_repr(self): result = [] result.append(u"{} ; last_check:{} ; touched: {}".format(EDTime.t_minus(self.timestamp*1000), EDTime.t_minus(self.last_check_timestamp*1000) if self.last_check_timestamp else "", self._touched)) for cmdr_name in self.players: timestamp, player = self.players[cmdr_name.lower()].values() now = EDTime.py_epoch_now() if player.is_targeted(): timestamp = now result.append(u"Cmdr {} at {}: {} {}".format(cmdr_name, EDTime.t_minus(timestamp*1000), "[TGT]" if player.is_targeted() else "", player.json())) for name in self.npcs: timestamp, pilot = self.npcs[name.lower()].values() now = EDTime.py_epoch_now() if pilot.is_targeted(): timestamp = now result.append(u"NPC {} at {}: {} {}".format(name, EDTime.t_minus(timestamp*1000), "[TGT]" if pilot.is_targeted() else "", pilot.json())) return result
def player_out(self, cmdr_name): now = EDTime.py_epoch_now() try: del self.players[cmdr_name.lower()] self.timestamp = now self._touched = True except KeyError: pass
def add_subsystem(self, subsystem): if not subsystem: return canonical = EDVehicleFactory.normalize_module_name(subsystem) now = EDTime.py_epoch_now() self.timestamp = now self.outfit_probably_changed() self.subsystems[canonical] = {u"timestamp": now, u"value": None}
def __init__(self): now = EDTime.py_epoch_now() self.timestamp = now self.last_check_timestamp = None self._touched = True self.players = {} self.npcs = {} self.npc_names_to_npcs = {}
def cockpit_health(self, value): now = EDTime.py_epoch_now() self.timestamp = now cockpit_suffix = "_cockpit" for internal_name in self.subsystems: if not internal_name.endswith(cockpit_suffix): continue self.subsystem_health(internal_name, value) break
def json(self): result = {} for cmdr_name in self.players: timestamp, player = self.players[cmdr_name.lower()].values() if cmdr_name.is_targeted(): now = EDTime.py_epoch_now() timestamp = now result[cmdr_name.lower()] = {"timestamp": int(timestamp*1000), "player": player.json()} return result
def __prune_expired_signals(self): now_epoch = EDTime.py_epoch_now() for uss_type in self.uss["variants"]: signal = self.uss["variants"][uss_type] for expiring in signal["expiring"]: if now_epoch >= expiring: print("Removing expired signal: {}".format(uss_type)) signal["expiring"].remove(expiring) signal["count"] -= 1
def refined(self, entry): if entry.get("event", None) != "MiningRefined": return now = EDTime.py_epoch_now() self.current = now if entry.get("Type", "").lower() not in self.of_interest["types"]: return self.refined_nb += 1 self.refinements.append((now, 1)) self.__update_efficiency()
def low_fuel(self, low): before = self._low_fuel["value"] now = EDTime.py_epoch_now() self.timestamp = now self._low_fuel = {"timestamp": now, "value": low} if before != low and self.fuel_capacity: if low: self.fuel_level = min(self.fuel_level, self.fuel_capacity * .25) else: self.fuel_level = max(self.fuel_level, self.fuel_capacity * .25)
def npc_in(self, pilot): now = EDTime.py_epoch_now() self.timestamp = now hopefully_unique_name = "{}{}{}".format(pilot.name, pilot.rank, pilot.vehicle.name if pilot.vehicle else "") self.npcs[hopefully_unique_name] = {u"timestamp": now, u"pilot": pilot} if pilot.name in self.npc_names_to_npcs: self.npc_names_to_npcs[pilot.name].add(hopefully_unique_name) else: self.npc_names_to_npcs[pilot.name] = set([hopefully_unique_name]) self._touched = True
def __visit(self, system, planet): if self.db is None: return try: now = EDTime.py_epoch_now() self.db.execute( 'UPDATE hotspots SET last_visit= CASE WHEN last_visit < ? THEN (?) ELSE (last_visit) END WHERE name=? and planet=?', (self.__replenished_margin(), now, system, planet)) self.db.commit() except sqlite3.IntegrityError: pass
def noteworthy_changes_json(self): now = EDTime.py_epoch_now() if not self._touched: return None players = [] for cmdr_name in self.players: timestamp, player = self.players[cmdr_name.lower()].values() if timestamp is None or self.last_check_timestamp is None or timestamp >= self.last_check_timestamp: players.append(player.json()) self.last_check_timestamp = now self._touched = False return {"timestamp": int(self.timestamp * 1000), "players": players}
def prospected(self, entry): if entry.get("event", None) != "ProspectedAsteroid": return False if entry.get("Remaining", 0) <= 0: return False if self.__probably_previously_prospected(entry): return False self.prospected_raw_history.append(entry) now = EDTime.py_epoch_now() self.current = now self.prospected_nb += 1 self.__update_efficiency() lut_content = { "n/a": "-", "$AsteroidMaterialContent_Low;": "L", "$AsteroidMaterialContent_Medium;": "M", "$AsteroidMaterialContent_High;": "H" } key = lut_content.get(entry.get("Content", "-"), "-") self.lmh[key] += 1 materials = entry.get("Materials", []) self.last = { "timestamp": now, "proportion": 0, "raw": key, "materials": len(materials) } was_a_dud = True for material in materials: if material.get("Name", "").lower() in self.of_interest["names"]: proportion = material.get("Proportion", 0.0) self.sum += proportion / 100.0 self.previous_max = self.max self.previous_min = self.min self.max = max(self.max, proportion) self.min = min(self.min, proportion) index = int(round(proportion/100.0 * (len(self.distribution["bins"])-1), 0)) self.distribution["last_index"] = index self.distribution["bins"][index] += 1 self.prospectements.append((now, proportion)) self.last["proportion"] = proportion was_a_dud = False break # TODO: assumption, an asteroid can't have multiple mineral of interest (at least for now, can't have both LTD and Painite or VO) if was_a_dud: self.distribution["last_index"] = 0 self.distribution["bins"][0] += 1 self.prospectements.append((now, 0.0))
def prospected(self, proportion): if proportion: self.sum += proportion / 100.0 self.previous_max = self.max self.previous_min = self.min self.max = max(self.max, proportion) self.min = min(self.min, proportion) self.last["proportion"] = proportion index = int(round(proportion/100.0 * (len(self.distribution["bins"])-1), 0)) self.distribution["last_index"] = index self.distribution["bins"][index] += 1 now = EDTime.py_epoch_now() self.prospectements.append((now, proportion))
def remove_subsystem(self, subsystem): if subsystem is None: return canonical = EDVehicleFactory.normalize_module_name(subsystem) if canonical.startswith("shieldgenerator_"): self.shield_health = 0.0 now = EDTime.py_epoch_now() self.timestamp = now try: del self.subsystems[canonical] self.outfit_probably_changed() except: pass
def __expiring_rank(self, expiring): now_epoch = EDTime.py_epoch_now() best_one = max(expiring) duration = best_one - now_epoch if duration <= 60*5: return "-" return round(min(duration / (40*60), 1) * 5)*"+" # TODO: dangerous fleet carriers # TODO: report FC sightings # TODO: summarize fss insights (e.g. 3 HAZ Res, 3 Stations, 15 FC (3 Notorious))
def refined(self, entry): if entry.get("event", None) != "MiningRefined": return now = EDTime.py_epoch_now() self.current = now if entry.get("Type", "").lower() not in self.of_interest["types"]: return self.refined_nb += 1 self.__update_efficiency() cinternal_name = entry.get("Type", "").lower() if cinternal_name in self.of_interest["types"]: cname = self.minerals_types_lut[cinternal_name] self.stats[cname].refined()
def awarded(self, entry): if entry.get("event", None) != "Bounty": return now = EDTime.py_epoch_now() self.current = now total_rewards = 0 rewards = entry.get("Rewards", []) for reward in rewards: total_rewards += reward.get("Reward", 0) self.sum_awarded += total_rewards self.awarded_nb += 1 self.awarded_bounties.append((now, total_rewards)) self.__update_efficiency()
def npc_out(self, name, ship_internal_name=None, rank=None): now = EDTime.py_epoch_now() try: if ship_internal_name: hopefully_unique_name = "{}{}{}".format(name, rank, EDVehicleFactory.canonicalize(ship_internal_name)) del self.npcs[hopefully_unique_name] self.npc_names_to_npcs[name].remove(hopefully_unique_name) else: for hopefully_unique_name in self.npc_names_to_npcs[name]: del self.npcs[hopefully_unique_name] del self.npc_names_to_npcs[name] self.timestamp = now self._touched = True except KeyError: pass