def update_from_loadout(self, event): other_id = event.get("ShipID", None) other_type = EDVehicleFactory.canonicalize(event.get( "Ship", "unknown")) if other_id != self.id or other_type != self.type: EDRLOG.log( u"Mismatch between ID ({} vs {}) and/or Type ({} vs. {}), can't update from loadout" .format(self.id, other_id, self.type, other_type), "WARNING") return self.identity = event.get('ShipIdent', None) self.name = event.get('ShipName', None) self.hull_health = event.get('HullHealth', None) * 100.0 # normalized to 0.0 ... 1.0 if not 'Modules' in event: return self.modules = event['Modules'] self.slots = {} timestamp = EDTime() self.slots_timestamp = timestamp.from_journal_timestamp( event['timestamp']) if 'timestamp' in event else timestamp self.module_info_timestamp = self.slots_timestamp # To prevent reading stale data from modulesinfo.json for module in self.modules: ed_module = edmodule.EDModule(module) self.slots[module['Slot']] = ed_module if module.get("Slot", "").lower() == "powerplant": self.power_capacity = ed_module.power_generation health = module['Health'] * 100.0 if 'Health' in module else None self.subsystem_health(module.get('Item', None), health) self.cargo_capacity = event.get("CargoCapacity", 0) self.cargo.update(event)
def edr_submit_scan(scan, timestamp, source, witness): edt = EDTime() edt.from_journal_timestamp(timestamp) report = scan report["starSystem"] = witness.star_system report["place"] = witness.place report["timestamp"] = edt.as_js_epoch() report["source"] = source report["reportedBy"] = witness.name if not witness.in_open(): EDRLOG.log(u"Scan not submitted due to unconfirmed Open mode", "INFO") EDR_CLIENT.status = _(u"not in Open? Start EDMC before Elite.") return if witness.has_partial_status(): EDRLOG.log(u"Scan not submitted due to partial status", "INFO") return if not EDR_CLIENT.scanned(scan["cmdr"], report): EDR_CLIENT.status = _(u"failed to report scan.") EDR_CLIENT.evict_cmdr(scan["cmdr"]) EDR_CLIENT.status = _(u"scan reported (cmdr {name}).").format( name=scan["cmdr"])
def summarize(self, cmdr_id): if not cmdr_id: EDRLOG.log(u"No cmdr_id, no records for {}".format(cmdr_id), "INFO") return None self.__update_records_if_stale(cmdr_id) records = self.records.get(cmdr_id)["records"] if self.records.has_key(cmdr_id) else None if not records: EDRLOG.log(u"No legal records for {}".format(cmdr_id), "INFO") return None EDRLOG.log(u"Got legal records for {}".format(cmdr_id), "INFO") overview = None (clean, wanted, bounties, recent_stats) = self.__process(records) timespan = EDTime.pretty_print_timespan(self.timespan, short=True, verbose=True) maxB = u"" lastB = u"" if recent_stats["maxBounty"]: max_bounty = EDFineOrBounty(recent_stats["maxBounty"]).pretty_print() maxB = _(u", max={} cr").format(max_bounty) if "last" in recent_stats and recent_stats["last"].get("value", None) and (recent_stats["last"].get("starSystem", "") not in ["", "unknown", "Unknown"]): tminus = EDTime.t_minus(recent_stats["last"]["timestamp"], short=True) last_bounty = EDFineOrBounty(recent_stats["last"]["value"]).pretty_print() lastB = _(u", last: {} cr in {} {}").format(last_bounty, recent_stats["last"]["starSystem"], tminus) # Translators: this is an overview of a cmdr's recent legal history for the 'last {}' days, number of clean and wanted scans, and optionally max and last bounties overview = _(u"[Past {}] clean:{} / wanted:{}{}{}").format(timespan, recent_stats["clean"], recent_stats["wanted"], maxB, lastB) return {"overview": overview, "clean": clean, "wanted": wanted, "bounties": bounties}
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 test_t_minus(self): nowish_ms = 1000 * calendar.timegm(time.gmtime()) ago_ms = nowish_ms - 1000 * 60 * 60 * 24 * 7 result = EDTime.t_minus(ago_ms) self.assertEqual(result, u"T-7d") ago_ms = nowish_ms - 1000 * 60 * 60 * (24 * 7 + 5) result = EDTime.t_minus(ago_ms) self.assertEqual(result, u"T-7d:5h") result = EDTime.t_minus(ago_ms, short=True) self.assertEqual(result, u"-7d")
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 __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 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 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 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 reset(self): now = EDTime.py_epoch_now() self.timestamp = now self.players = {} self.npcs = {} self.npc_names_to_npcs = {} self._touched = True
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.targeted: timestamp = now result.append(u"{} at {}: {} {}".format( cmdr_name, EDTime.t_minus(timestamp * 1000), "[TGT]" if player.targeted else "", player.json())) return result
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 update(self, ppoints): previous_value = self.history[-1]["value"] if len(self.history) >= 2 else None if previous_value is not None and previous_value == ppoints: # remove redundant data point self.history.pop() now = EDTime.ms_epoch_now() self.history.append({"timestamp": now, "value": ppoints})
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 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 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 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 __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 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 test_alignment(self): sample = EDRCmdrDexProfile() created = sample.created sample.alignment = u"outlaw" self.assertEquals(sample.alignment, u"outlaw") now = EDTime.js_epoch_now() self.assertAlmostEqual(sample.updated/100.0, now/100.0, 1) self.assertEqual(sample.created, created) sample.alignment = u"neutral" self.assertEquals(sample.alignment, u"neutral") now = EDTime.js_epoch_now() self.assertAlmostEqual(sample.updated/100.0, now/100.0, 1) self.assertEqual(sample.created, created) sample.alignment = u"enforcer" self.assertEquals(sample.alignment, u"enforcer") now = EDTime.js_epoch_now() self.assertAlmostEqual(sample.updated/100.0, now/100.0, 1) self.assertEqual(sample.created, created) current = sample.alignment updated = sample.updated sample.alignment = u"dummy" self.assertEquals(sample.alignment, current) self.assertEqual(sample.updated, updated) self.assertEqual(sample.created, created) sample.alignment = u"Outlaw" self.assertEquals(sample.alignment, current) self.assertEqual(sample.updated, updated) self.assertEqual(sample.created, created) sample.alignment = None self.assertEquals(sample.alignment, None) now = EDTime.js_epoch_now() self.assertAlmostEqual(sample.updated/100.0, now/100.0, 1) self.assertEqual(sample.created, created) current = sample.alignment updated = sample.updated sample.alignment = current self.assertEquals(sample.alignment, current) self.assertEqual(sample.updated, updated) self.assertEqual(sample.created, created)
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 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 __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 __update_squadron_info(self, force_update=False): if self.server.is_anonymous(): return mark_twain_flag = int( (EDTime.js_epoch_now() - self.heartbeat_timestamp) / 1000) >= self._edr_heartbeat if self.heartbeat_timestamp else True if force_update or mark_twain_flag: info = self.server.heartbeat() if info: self.heartbeat_timestamp = info[ "heartbeat"] if "heartbeat" in info else EDTime.js_epoch_now( ) self._player.squadron_member( info) if "squadronId" in info else self._player.lone_wolf( ) else: self.heartbeat_timestamp = EDTime.js_epoch_now() self._player.lone_wolf()
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 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 __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}