From 6d6f3b057fde87add79a006b32e554dcf0657fdd Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 12:02:42 +0000 Subject: [PATCH 01/30] typing: Use ` | None`, not `Optional[...]` --- monitor.py | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/monitor.py b/monitor.py index 126e04c7..bcac1351 100644 --- a/monitor.py +++ b/monitor.py @@ -14,7 +14,7 @@ from collections import OrderedDict, defaultdict from os import SEEK_END, SEEK_SET, listdir from os.path import basename, expanduser, getctime, isdir, join from time import gmtime, localtime, mktime, sleep, strftime, strptime, time -from typing import TYPE_CHECKING, Any, BinaryIO, Dict, List, MutableMapping, Optional +from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping from typing import OrderedDict as OrderedDictT from typing import Tuple @@ -91,11 +91,11 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # TODO(A_D): A bunch of these should be switched to default values (eg '' for strings) and no longer be Optional FileSystemEventHandler.__init__(self) # futureproofing - not need for current version of watchdog self.root: 'tkinter.Tk' = None # type: ignore # Don't use Optional[] - mypy thinks no methods - self.currentdir: Optional[str] = None # The actual logdir that we're monitoring - self.logfile: Optional[str] = None - self.observer: Optional['Observer'] = None + self.currentdir: str | None = None # The actual logdir that we're monitoring + self.logfile: str | None = None + self.observer: 'Observer' | None = None self.observed = None # a watchdog ObservedWatch, or None if polling - self.thread: Optional[threading.Thread] = None + self.thread: threading.Thread | None = None # For communicating journal entries back to main thread self.event_queue: queue.Queue = queue.Queue(maxsize=0) @@ -112,27 +112,27 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.game_was_running = False # For generation of the "ShutDown" event # Context for journal handling - self.version: Optional[str] = None - self.version_semantic: Optional[semantic_version.Version] = None + self.version: str | None = None + self.version_semantic: semantic_version.Version | None = None self.is_beta = False - self.mode: Optional[str] = None - self.group: Optional[str] = None - self.cmdr: Optional[str] = None - self.planet: Optional[str] = None - self.system: Optional[str] = None - self.station: Optional[str] = None - self.station_marketid: Optional[int] = None - self.stationtype: Optional[str] = None - self.coordinates: Optional[Tuple[float, float, float]] = None - self.systemaddress: Optional[int] = None - self.systempopulation: Optional[int] = None - self.started: Optional[int] = None # Timestamp of the LoadGame event + self.mode: str | None = None + self.group: str | None = None + self.cmdr: str | None = None + self.planet: str | None = None + self.system: str | None = None + self.station: str | None = None + self.station_marketid: int | None = None + self.stationtype: str | None = None + self.coordinates: Tuple[float, float, float] | None = None + self.systemaddress: int | None = None + self.systempopulation: int | None = None + self.started: int | None = None # Timestamp of the LoadGame event self._navroute_retries_remaining = 0 - self._last_navroute_journal_timestamp: Optional[float] = None + self._last_navroute_journal_timestamp: float | None = None self._fcmaterials_retries_remaining = 0 - self._last_fcmaterials_journal_timestamp: Optional[float] = None + self._last_fcmaterials_journal_timestamp: float | None = None # For determining Live versus Legacy galaxy. # The assumption is gameversion will parse via `coerce()` and always @@ -274,7 +274,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below logger.debug('Done.') return True - def journal_newest_filename(self, journals_dir) -> Optional[str]: + def journal_newest_filename(self, journals_dir) -> str | None: """ Determine the newest Journal file name. @@ -455,7 +455,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Check whether new log file started, e.g. client (re)started. if emitter and emitter.is_alive(): - new_journal_file: Optional[str] = self.logfile # updated by on_created watchdog callback + new_journal_file: str | None = self.logfile # updated by on_created watchdog callback else: # Poll @@ -1918,7 +1918,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below slotid = journal_loadoutid - 4293000000 return slotid - def canonicalise(self, item: Optional[str]) -> str: + def canonicalise(self, item: str | None) -> str: """ Produce canonical name for a ship module. @@ -1955,7 +1955,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return item.capitalize() - def get_entry(self) -> Optional[MutableMapping[str, Any]]: + def get_entry(self) -> MutableMapping[str, Any | None]: """ Pull the next Journal event from the event_queue. @@ -2051,7 +2051,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return False - def ship(self, timestamped=True) -> Optional[MutableMapping[str, Any]]: + def ship(self, timestamped=True) -> MutableMapping[str, Any | None]: """ Produce a subset of data for the current ship. @@ -2250,7 +2250,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return slots - def _parse_navroute_file(self) -> Optional[dict[str, Any]]: + def _parse_navroute_file(self) -> dict[str, Any | None]: """Read and parse NavRoute.json.""" if self.currentdir is None: raise ValueError('currentdir unset') @@ -2276,7 +2276,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return data - def _parse_fcmaterials_file(self) -> Optional[dict[str, Any]]: + def _parse_fcmaterials_file(self) -> dict[str, Any | None]: """Read and parse FCMaterials.json.""" if self.currentdir is None: raise ValueError('currentdir unset') @@ -2348,7 +2348,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self._last_navroute_journal_timestamp = None return True - def __fcmaterials_retry(self) -> Optional[Dict[str, Any]]: + def __fcmaterials_retry(self) -> Dict[str, Any | None]: """Retry reading FCMaterials files.""" if self._fcmaterials_retries_remaining == 0: return None From 6bd0b042b1e01cd918a1d14f15637a12254d0f93 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 12:05:45 +0000 Subject: [PATCH 02/30] monitor.py: typing: Don't use List or Dict --- monitor.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/monitor.py b/monitor.py index bcac1351..bd5d2d65 100644 --- a/monitor.py +++ b/monitor.py @@ -144,7 +144,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below def __init_state(self) -> None: # Cmdr state shared with EDSM and plugins # If you change anything here update PLUGINS.md documentation! - self.state: Dict = { + self.state: dict = { 'GameLanguage': None, # From `Fileheader 'GameVersion': None, # From `Fileheader 'GameBuild': None, # From `Fileheader @@ -1955,7 +1955,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return item.capitalize() - def get_entry(self) -> MutableMapping[str, Any | None]: + def get_entry(self) -> MutableMapping[str, Any] | None: """ Pull the next Journal event from the event_queue. @@ -2051,7 +2051,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return False - def ship(self, timestamped=True) -> MutableMapping[str, Any | None]: + def ship(self, timestamped=True) -> MutableMapping[str, Any] | None: """ Produce a subset of data for the current ship. @@ -2188,7 +2188,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below except OSError: logger.exception("OSError writing ship loadout to new filename with utf-8 encoding, aborting.") - def coalesce_cargo(self, raw_cargo: List[MutableMapping[str, Any]]) -> List[MutableMapping[str, Any]]: + def coalesce_cargo(self, raw_cargo: list[MutableMapping[str, Any]]) -> list[MutableMapping[str, Any]]: """ Coalesce multiple entries of the same cargo into one. @@ -2209,7 +2209,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below :return: Coalesced data """ # self.state['Cargo'].update({self.canonicalise(x['Name']): x['Count'] for x in entry['Inventory']}) - out: List[MutableMapping[str, Any]] = [] + out: list[MutableMapping[str, Any]] = [] for inventory_item in raw_cargo: if not any(self.canonicalise(x['Name']) == self.canonicalise(inventory_item['Name']) for x in out): out.append(dict(inventory_item)) @@ -2250,7 +2250,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return slots - def _parse_navroute_file(self) -> dict[str, Any | None]: + def _parse_navroute_file(self) -> dict[str, Any] | None: """Read and parse NavRoute.json.""" if self.currentdir is None: raise ValueError('currentdir unset') @@ -2276,7 +2276,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below return data - def _parse_fcmaterials_file(self) -> dict[str, Any | None]: + def _parse_fcmaterials_file(self) -> dict[str, Any] | None: """Read and parse FCMaterials.json.""" if self.currentdir is None: raise ValueError('currentdir unset') @@ -2348,7 +2348,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self._last_navroute_journal_timestamp = None return True - def __fcmaterials_retry(self) -> Dict[str, Any | None]: + def __fcmaterials_retry(self) -> dict[str, Any] | None: """Retry reading FCMaterials files.""" if self._fcmaterials_retries_remaining == 0: return None From 86b0aa45504ced2efa44af93056eceed8a0a1988 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 15:08:47 +0000 Subject: [PATCH 03/30] monitor: Track all System and Body state in monitor.state * Minor grammar edit only in PLUGINS.md (I was checking if it explicitly stated what data is expected in the synthetic 'StartUp' event, it doesn't). * First changes to move some monitor properties into the monitor.state dictionary. This is for system or body data. * Re-factored the generation of 'StartUp' event into `EDLogs.synthesize_startup_event()`. It's done in two places, so was anti-DRY. * In general any bulk setting of system & body data is now done in the same order for comparison clarity. * A little of the location tracking has been duplicated from plugins/eddn.py. This is with a view to switching *it* to using the state version. --- PLUGINS.md | 2 +- monitor.py | 181 ++++++++++++++++++++++++++---------------------- plugins/eddn.py | 9 +++ 3 files changed, 108 insertions(+), 84 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index cd0d47bc..0378ef96 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -771,7 +771,7 @@ ___ A special "StartUp" entry is sent if EDMarketConnector is started while the game is already running. In this case you won't receive initial events such as -"LoadGame", "Rank", "Location", etc. However the `state` dictionary will +"LoadGame", "Rank", "Location", etc. However, the `state` dictionary will reflect the cumulative effect of these missed events. **NB: Any of the values in this might be `None` if the Cmdr has loaded into diff --git a/monitor.py b/monitor.py index bd5d2d65..57beb124 100644 --- a/monitor.py +++ b/monitor.py @@ -14,9 +14,7 @@ from collections import OrderedDict, defaultdict from os import SEEK_END, SEEK_SET, listdir from os.path import basename, expanduser, getctime, isdir, join from time import gmtime, localtime, mktime, sleep, strftime, strptime, time -from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping -from typing import OrderedDict as OrderedDictT -from typing import Tuple +from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping, Tuple if TYPE_CHECKING: import tkinter @@ -118,14 +116,14 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.planet: str | None = None self.system: str | None = None + self.systemaddress: int | None = None + self.coordinates: Tuple[float, float, float] | None = None + self.systempopulation: int | None = None + self.planet: str | None = None self.station: str | None = None self.station_marketid: int | None = None self.stationtype: str | None = None - self.coordinates: Tuple[float, float, float] | None = None - self.systemaddress: int | None = None - self.systempopulation: int | None = None self.started: int | None = None # Timestamp of the LoadGame event self._navroute_retries_remaining = 0 @@ -195,7 +193,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'Taxi': None, # True whenever we are _in_ a taxi. ie, this is reset on Disembark etc. 'Dropship': None, # Best effort as to whether or not the above taxi is a dropship. 'StarPos': None, # Best effort current system's galaxy position. + 'SystemAddress': None, 'Body': None, + 'BodyID': None, 'BodyType': None, 'NavRoute': None, @@ -306,19 +306,19 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = None self.group = None self.cmdr = None - self.planet = None self.system = None + self.state['SystemAddress'] = self.systemaddress = None + self.coordinates = None + self.planet = self.state['Body'] = None + self.state['BodyID'] = None + self.state['BodyType'] = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None - self.coordinates = None - self.systemaddress = None self.is_beta = False self.state['OnFoot'] = False self.state['IsDocked'] = False - self.state['Body'] = None - self.state['BodyType'] = None if self.observed: logger.debug('self.observed: Calling unschedule_all()') @@ -416,24 +416,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if self.live: if self.game_was_running: # Game is running locally - entry: OrderedDictT[str, Any] = OrderedDict([ - ('timestamp', strftime('%Y-%m-%dT%H:%M:%SZ', gmtime())), - ('event', 'StartUp'), - ('StarSystem', self.system), - ('StarPos', self.coordinates), - ('SystemAddress', self.systemaddress), - ('Population', self.systempopulation), - ]) - - if self.planet: - entry['Body'] = self.planet - - entry['Docked'] = bool(self.station) - - if self.station: - entry['StationName'] = self.station - entry['StationType'] = self.stationtype - entry['MarketID'] = self.station_marketid + entry = self.synthesize_startup_event() self.event_queue.put(json.dumps(entry, separators=(', ', ':'))) @@ -534,6 +517,41 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below logger.debug('Done.') + def synthesize_startup_event(self) -> dict[str, Any]: + """ + Synthesize a 'StartUp' event to notify plugins of initial state. + + May be called, e.g. after 'catch up' loading of current latest + journal file on startup, or when a new journal file is detected without + the game running locally. + + :return: Synthesized event as a dict + """ + entry: dict[str, Any] = { + 'timestamp': strftime('%Y-%m-%dT%H:%M:%SZ', gmtime()), + 'event': 'StartUp', + 'StarSystem': self.system, + 'StarPos': self.coordinates, + 'SystemAddress': self.systemaddress, + 'Population': self.systempopulation, + } + + if self.planet: + entry['Body'] = self.planet + entry['BodyID'] = self.state['BodyID'] + entry['BodyType'] = self.state['BodyType'] + + if self.station: + entry['Docked'] = True + entry['MarketID'] = self.station_marketid + entry['StationName'] = self.station + entry['StationType'] = self.stationtype + + else: + entry['Docked'] = False + + return entry + def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, CCR001 """ Parse a Journal JSON line. @@ -563,14 +581,15 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.cmdr = None self.mode = None self.group = None - self.planet = None self.system = None + self.state['SystemAddress'] = self.systemaddress = None + self.state['StarPos'] = self.coordinates = None + self.state['Body'] = self.planet = None + self.state['BodyID'] = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None - self.coordinates = None - self.systemaddress = None self.started = None self.__init_state() @@ -599,34 +618,34 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = entry.get('GameMode') self.group = entry.get('Group') - self.planet = None self.system = None + self.state['SystemAddress'] = self.systemaddress = None + self.state['StarPos'] = self.coordinates = None + self.status['Body'] = self.planet = None + self.status['BodyID'] = None + self.status['BodyType'] = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None - self.coordinates = None - self.systemaddress = None self.started = timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')) # Don't set Ship, ShipID etc since this will reflect Fighter or SRV if starting in those self.state.update({ - 'Captain': None, - 'Credits': entry['Credits'], - 'FID': entry.get('FID'), # From 3.3 - 'Horizons': entry['Horizons'], # From 3.0 - 'Odyssey': entry.get('Odyssey', False), # From 4.0 Odyssey - 'Loan': entry['Loan'], + 'Captain': None, + 'Credits': entry['Credits'], + 'FID': entry.get('FID'), # From 3.3 + 'Horizons': entry['Horizons'], # From 3.0 + 'Odyssey': entry.get('Odyssey', False), # From 4.0 Odyssey + 'Loan': entry['Loan'], # For Odyssey, by 4.0.0.100, and at least from Horizons 3.8.0.201 the order of events changed # to LoadGame being after some 'status' events. - # 'Engineers': {}, # 'EngineerProgress' event now before 'LoadGame' - # 'Rank': {}, # 'Rank'/'Progress' events now before 'LoadGame' - # 'Reputation': {}, # 'Reputation' event now before 'LoadGame' - 'Statistics': {}, # Still after 'LoadGame' in 4.0.0.903 - 'Role': None, - 'Taxi': None, - 'Dropship': None, - 'Body': None, - 'BodyType': None, + # 'Engineers': {}, # 'EngineerProgress' event now before 'LoadGame' + # 'Rank': {}, # 'Rank'/'Progress' events now before 'LoadGame' + # 'Reputation': {}, # 'Reputation' event now before 'LoadGame' + 'Statistics': {}, # Still after 'LoadGame' in 4.0.0.903 + 'Role': None, + 'Taxi': None, + 'Dropship': None, }) if entry.get('Ship') is not None and self._RE_SHIP_ONFOOT.search(entry['Ship']): self.state['OnFoot'] = True @@ -808,6 +827,18 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Taxi'] = False self.state['Dropship'] = False + elif event_type == 'supercruiseexit': + # For any orbital station we have no way of determining the body + # it orbits: + # + # In-ship Status.json doesn't specify this. + # On-foot Status.json lists the station itself as Body. + # Location for stations (on-foot or in-ship) has station as Body. + # SupercruiseExit (own ship or taxi) lists the station as the Body. + if entry['BodyType'] == 'Station': + self.state['Body'] = None + self.state['BodyID'] = None + elif event_type == 'docked': self.state['IsDocked'] = True self.station = entry.get('StationName') # May be None @@ -828,6 +859,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if event_type in ('location', 'carrierjump'): self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None self.state['Body'] = entry.get('Body') + self.state['BodyID'] = entry.get('BodyID') self.state['BodyType'] = entry.get('BodyType') if event_type == 'location': @@ -838,13 +870,14 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'fsdjump': self.planet = None self.state['Body'] = None + self.state['BodyID'] = None self.state['BodyType'] = None if 'StarPos' in entry: # Plugins need this as well, so copy in state self.state['StarPos'] = self.coordinates = tuple(entry['StarPos']) # type: ignore - self.systemaddress = entry.get('SystemAddress') + self.state['SystemAddress'] = self.systemaddress = entry.get('SystemAddress') self.systempopulation = entry.get('Population') @@ -872,11 +905,16 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'approachbody': self.planet = entry['Body'] self.state['Body'] = entry['Body'] + self.state['BodyID'] = entry.get('BodyID') self.state['BodyType'] = 'Planet' # Best guess. Journal says always planet. elif event_type in ('leavebody', 'supercruiseentry'): + # FIXME: In the plugins/eddn.py version of this tracking we + # explicitly do NOT clear this information for `supercruiseentry', + # but it is also doing some Status.jon checking. self.planet = None self.state['Body'] = None + self.state['BodyID'] = None self.state['BodyType'] = None elif event_type in ('rank', 'promotion'): @@ -1562,14 +1600,15 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'joinacrew': self.state['Captain'] = entry['Captain'] self.state['Role'] = 'Idle' - self.planet = None + self.state['Body'] = self.planet = None + self.state['BodyID'] = None self.system = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None self.coordinates = None - self.systemaddress = None + self.state['SystemAddress'] = self.systemaddress = None self.state['OnFoot'] = False self.state['Body'] = None @@ -1581,17 +1620,17 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'quitacrew': self.state['Captain'] = None self.state['Role'] = None - self.planet = None + self.state['Body'] = self.planet = None + self.state['BodyID'] = None + self.state['BodyType'] = None self.system = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None self.coordinates = None - self.systemaddress = None + self.state['SystemAddress'] = self.systemaddress = None - self.state['Body'] = None - self.state['BodyType'] = None # TODO: on_foot: Will we get an event after this to know ? elif event_type == 'friends': @@ -1979,31 +2018,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if not self.live and entry['event'] not in (None, 'Fileheader'): # Game not running locally, but Journal has been updated self.live = True - if self.station: - entry = OrderedDict([ - ('timestamp', strftime('%Y-%m-%dT%H:%M:%SZ', gmtime())), - ('event', 'StartUp'), - ('Docked', True), - ('MarketID', self.station_marketid), - ('StationName', self.station), - ('StationType', self.stationtype), - ('StarSystem', self.system), - ('StarPos', self.coordinates), - ('SystemAddress', self.systemaddress), - ]) - - else: - entry = OrderedDict([ - ('timestamp', strftime('%Y-%m-%dT%H:%M:%SZ', gmtime())), - ('event', 'StartUp'), - ('Docked', False), - ('StarSystem', self.system), - ('StarPos', self.coordinates), - ('SystemAddress', self.systemaddress), - ]) - - if entry['event'] == 'Location': - logger.trace_if('journal.locations', 'Appending "Location" event to event_queue') + entry = self.synthesize_startup_event() self.event_queue.put(json.dumps(entry, separators=(', ', ':'))) diff --git a/plugins/eddn.py b/plugins/eddn.py index 13bdf108..45773cd2 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2208,6 +2208,14 @@ def journal_entry( # noqa: C901, CCR001 entry ) + # TODO - uncomment this, i.e. use monitor.py tracking, not also here + # Copy some state into module-held variables because we might need it + # outside of this function. + # this.body_name = state['Body'] + # this.body_id = state['BodyID'] + # this.coordinates = state['StarPos'] + # this.systemaddress = state['SystemAddress'] + # Track location if event_name == 'supercruiseexit': # For any orbital station we have no way of determining the body @@ -2360,6 +2368,7 @@ def journal_entry( # noqa: C901, CCR001 # add planet to Docked event for planetary stations if known if event_name == 'docked' and this.body_name: + # FIXME - Is this correct if using monitor.py tracking ? entry['Body'] = this.body_name entry['BodyType'] = 'Planet' From 9ccd0c3b7d623350c86ca8594bd2eb661a3b1a0e Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 15:15:02 +0000 Subject: [PATCH 04/30] monitor: Remove EDLogs.systemaddress in favour of .state version This was literally only used within this file. --- monitor.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/monitor.py b/monitor.py index 57beb124..ff872db3 100644 --- a/monitor.py +++ b/monitor.py @@ -117,7 +117,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group: str | None = None self.cmdr: str | None = None self.system: str | None = None - self.systemaddress: int | None = None self.coordinates: Tuple[float, float, float] | None = None self.systempopulation: int | None = None self.planet: str | None = None @@ -307,7 +306,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group = None self.cmdr = None self.system = None - self.state['SystemAddress'] = self.systemaddress = None + self.state['SystemAddress'] = None self.coordinates = None self.planet = self.state['Body'] = None self.state['BodyID'] = None @@ -532,7 +531,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'event': 'StartUp', 'StarSystem': self.system, 'StarPos': self.coordinates, - 'SystemAddress': self.systemaddress, + 'SystemAddress': self.state['SystemAddress'], 'Population': self.systempopulation, } @@ -582,7 +581,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = None self.group = None self.system = None - self.state['SystemAddress'] = self.systemaddress = None + self.state['SystemAddress'] = None self.state['StarPos'] = self.coordinates = None self.state['Body'] = self.planet = None self.state['BodyID'] = None @@ -619,7 +618,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group = entry.get('Group') self.system = None - self.state['SystemAddress'] = self.systemaddress = None + self.state['SystemAddress'] = None self.state['StarPos'] = self.coordinates = None self.status['Body'] = self.planet = None self.status['BodyID'] = None @@ -877,7 +876,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Plugins need this as well, so copy in state self.state['StarPos'] = self.coordinates = tuple(entry['StarPos']) # type: ignore - self.state['SystemAddress'] = self.systemaddress = entry.get('SystemAddress') + self.state['SystemAddress'] = entry.get('SystemAddress') self.systempopulation = entry.get('Population') @@ -1608,7 +1607,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.stationtype = None self.stationservices = None self.coordinates = None - self.state['SystemAddress'] = self.systemaddress = None + self.state['SystemAddress'] = None self.state['OnFoot'] = False self.state['Body'] = None @@ -1629,7 +1628,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.stationtype = None self.stationservices = None self.coordinates = None - self.state['SystemAddress'] = self.systemaddress = None + self.state['SystemAddress'] = None # TODO: on_foot: Will we get an event after this to know ? From 0177fc4d699ec966f16358c09231ea8fafb7641f Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 15:28:48 +0000 Subject: [PATCH 05/30] monitor: Remove .planet in favour of state['Body'] This had mostly been done already, now it's complete. *If* any plugin is, still, using `monitor.planet` then they get to keep the broken pieces because it's not included in PLUGINS.md#Available-imports. --- monitor.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/monitor.py b/monitor.py index ff872db3..bab1d244 100644 --- a/monitor.py +++ b/monitor.py @@ -119,7 +119,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.system: str | None = None self.coordinates: Tuple[float, float, float] | None = None self.systempopulation: int | None = None - self.planet: str | None = None self.station: str | None = None self.station_marketid: int | None = None self.stationtype: str | None = None @@ -308,7 +307,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.system = None self.state['SystemAddress'] = None self.coordinates = None - self.planet = self.state['Body'] = None + self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None self.station = None @@ -535,8 +534,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'Population': self.systempopulation, } - if self.planet: - entry['Body'] = self.planet + if self.state['Body']: + entry['Body'] = self.state['Body'] entry['BodyID'] = self.state['BodyID'] entry['BodyType'] = self.state['BodyType'] @@ -583,7 +582,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.system = None self.state['SystemAddress'] = None self.state['StarPos'] = self.coordinates = None - self.state['Body'] = self.planet = None + self.state['Body'] = None self.state['BodyID'] = None self.station = None self.station_marketid = None @@ -620,7 +619,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.system = None self.state['SystemAddress'] = None self.state['StarPos'] = self.coordinates = None - self.status['Body'] = self.planet = None + self.status['Body'] = None self.status['BodyID'] = None self.status['BodyType'] = None self.station = None @@ -856,7 +855,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # • InSRV: bool # • OnFoot: bool if event_type in ('location', 'carrierjump'): - self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None + # We're not guaranteeing this is a planet, rather than a + # station. self.state['Body'] = entry.get('Body') self.state['BodyID'] = entry.get('BodyID') self.state['BodyType'] = entry.get('BodyType') @@ -867,7 +867,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['IsDocked'] = True elif event_type == 'fsdjump': - self.planet = None self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None @@ -902,7 +901,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Dropship'] = None elif event_type == 'approachbody': - self.planet = entry['Body'] self.state['Body'] = entry['Body'] self.state['BodyID'] = entry.get('BodyID') self.state['BodyType'] = 'Planet' # Best guess. Journal says always planet. @@ -911,7 +909,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # FIXME: In the plugins/eddn.py version of this tracking we # explicitly do NOT clear this information for `supercruiseentry', # but it is also doing some Status.jon checking. - self.planet = None self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None @@ -1599,7 +1596,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'joinacrew': self.state['Captain'] = entry['Captain'] self.state['Role'] = 'Idle' - self.state['Body'] = self.planet = None + self.state['Body'] = None self.state['BodyID'] = None self.system = None self.station = None @@ -1619,7 +1616,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'quitacrew': self.state['Captain'] = None self.state['Role'] = None - self.state['Body'] = self.planet = None + self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None self.system = None @@ -1714,11 +1711,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # There should be a `Backpack` event as you 'come to' in the # new location, so no need to zero out BackPack here. - # HACK (not game related / 2021-06-2): self.planet is moved into a more general self.state['Body']. - # This exists to help plugins doing what they SHOULDN'T BE cope. It will be removed at some point. - if self.state['Body'] is None or self.state['BodyType'] == 'Planet': - self.planet = self.state['Body'] - return entry except Exception as ex: From e3254aec3104d831af0996aa28f0b54ad7835dc2 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 15:34:11 +0000 Subject: [PATCH 06/30] monitor: Minor cleanup on 'Location'->'Docked' handling * All my recent Location events *have* the 'Docked' flag. * If any don't, then just use a default on .get() to set it False. --- monitor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/monitor.py b/monitor.py index bab1d244..541cd03b 100644 --- a/monitor.py +++ b/monitor.py @@ -863,8 +863,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if event_type == 'location': logger.trace_if('journal.locations', '"Location" event') - if entry.get('Docked'): - self.state['IsDocked'] = True + self.state['IsDocked'] = entry.get('Docked', False) elif event_type == 'fsdjump': self.state['Body'] = None From 232e91ebfcf3fada650aa8c582a4d1d4f02abac3 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 16:34:56 +0000 Subject: [PATCH 07/30] monitor/Body: Tweak & comment, and remove defunct tracking from eddn.py * Typod '.status' instead of 'state'. * Bring in some sanity-checks and comments from eddn.py to monitor.py. * Have a 'pass' elif for 'supercruiseentry' so as to comment why we do NOT use this to blank out body state. * Bring in the 'if we exit to main menu, blank body state' from eddn.py. * Remove checks from eddn.py that are now in monitor.py. * Have a disctinct 'docked' event check in eddn.py for triggering the "Now we're docked, so the Delay sending until docked is satisfied" sending of messages. --- monitor.py | 41 +++++++++++++++++++++++++++++--------- plugins/eddn.py | 53 ++++++++++--------------------------------------- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/monitor.py b/monitor.py index 541cd03b..d416b100 100644 --- a/monitor.py +++ b/monitor.py @@ -619,9 +619,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.system = None self.state['SystemAddress'] = None self.state['StarPos'] = self.coordinates = None - self.status['Body'] = None - self.status['BodyID'] = None - self.status['BodyType'] = None + self.state['Body'] = None + self.state['BodyID'] = None + self.state['BodyType'] = None self.station = None self.station_marketid = None self.stationtype = None @@ -874,7 +874,14 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Plugins need this as well, so copy in state self.state['StarPos'] = self.coordinates = tuple(entry['StarPos']) # type: ignore - self.state['SystemAddress'] = entry.get('SystemAddress') + if 'SystemAddress' not in entry: + logger.warning(f'"location" event without SystemAddress !!!:\n{entry}\n') + + # But we'll still *use* the value, because if a 'location' event doesn't + # have this we've still moved and now don't know where and MUST NOT + # continue to use any old value. + # Yes, explicitly state `None` here, so it's crystal clear. + self.state['SystemAddress'] = entry.get('SystemAddress', None) self.systempopulation = entry.get('Population') @@ -902,16 +909,32 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'approachbody': self.state['Body'] = entry['Body'] self.state['BodyID'] = entry.get('BodyID') - self.state['BodyType'] = 'Planet' # Best guess. Journal says always planet. + # This isn't in the event, but Journal doc for ApproachBody says: + # when in Supercruise, and distance from planet drops to within the 'Orbital Cruise' zone + self.state['BodyType'] = 'Planet' - elif event_type in ('leavebody', 'supercruiseentry'): - # FIXME: In the plugins/eddn.py version of this tracking we - # explicitly do NOT clear this information for `supercruiseentry', - # but it is also doing some Status.jon checking. + elif event_type == 'leavebody': + # Triggered when ship goes above Orbital Cruise altitude, such + # that a new 'ApproachBody' would get triggered if the ship + # went back down. self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None + elif event_type == 'supercruiseentry': + # NB: Do **NOT** clear Body state, because we won't get a fresh + # ApproachBody if we don't leave Orbital Cruise but land + # again. + pass + + elif event_type == 'music': + if entry['MusicTrack'] == 'MainMenu': + # We'll get new Body state when the player logs back into + # the game. + self.state['Body'] = None + self.state['BodyID'] = None + self.state['BodyType'] = None + elif event_type in ('rank', 'promotion'): payload = dict(entry) payload.pop('event') diff --git a/plugins/eddn.py b/plugins/eddn.py index 45773cd2..f1a5c162 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -1279,6 +1279,8 @@ class EDDN: logger.warning(f'this.status_body_name was not set properly:' f' "{this.status_body_name}" ({type(this.status_body_name)})') + # this.status_body_name is available for cross-checks, so try to set + # BodyName and ID. else: # In case Frontier add it in if 'BodyName' not in entry: @@ -2208,40 +2210,14 @@ def journal_entry( # noqa: C901, CCR001 entry ) - # TODO - uncomment this, i.e. use monitor.py tracking, not also here # Copy some state into module-held variables because we might need it # outside of this function. - # this.body_name = state['Body'] - # this.body_id = state['BodyID'] - # this.coordinates = state['StarPos'] - # this.systemaddress = state['SystemAddress'] - - # Track location - if event_name == 'supercruiseexit': - # For any orbital station we have no way of determining the body - # it orbits: - # - # In-ship Status.json doesn't specify this. - # On-foot Status.json lists the station itself as Body. - # Location for stations (on-foot or in-ship) has station as Body. - # SupercruiseExit (own ship or taxi) lists the station as the Body. - if entry['BodyType'] == 'Station': - this.body_name = None - this.body_id = None - - elif event_name in ('location', 'fsdjump', 'docked', 'carrierjump'): - if event_name in ('location', 'carrierjump'): - if entry.get('BodyType') == 'Planet': - this.body_name = entry.get('Body') - this.body_id = entry.get('BodyID') - - else: - this.body_name = None - - elif event_name == 'fsdjump': - this.body_name = None - this.body_id = None + this.body_name = state['Body'] + this.body_id = state['BodyID'] + this.coordinates = state['StarPos'] + this.systemaddress = state['SystemAddress'] + if event_name in ('location', 'fsdjump', 'docked', 'carrierjump'): if 'StarPos' in entry: this.coordinates = tuple(entry['StarPos']) @@ -2251,18 +2227,9 @@ def journal_entry( # noqa: C901, CCR001 if 'SystemAddress' not in entry: logger.warning(f'"location" event without SystemAddress !!!:\n{entry}\n') - # But we'll still *use* the value, because if a 'location' event doesn't - # have this we've still moved and now don't know where and MUST NOT - # continue to use any old value. - # Yes, explicitly state `None` here, so it's crystal clear. - this.systemaddress = entry.get('SystemAddress', None) # type: ignore - - if event_name == 'docked': - this.eddn.parent.after(this.eddn.REPLAY_DELAY, this.eddn.sender.queue_check_and_send, False) - - elif event_name == 'approachbody': - this.body_name = entry['Body'] - this.body_id = entry.get('BodyID') + if event_name == 'docked': + # Trigger a send/retry of pending EDDN messages + this.eddn.parent.after(this.eddn.REPLAY_DELAY, this.eddn.sender.queue_check_and_send, False) elif event_name == 'leavebody': # NB: **NOT** SupercruiseEntry, because we won't get a fresh From e6abc137cebd15f94638a822e5ab8a0255b3014b Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 18:49:27 +0000 Subject: [PATCH 08/30] monitor/tracking: Shift .coordinates to state['StarPos'] * Some additional commenting for future clarity. * Remove the old eddn.py tracking. --- monitor.py | 79 +++++++++++++++++++++++++++++-------------------- plugins/eddn.py | 10 ------- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/monitor.py b/monitor.py index d416b100..f34c41da 100644 --- a/monitor.py +++ b/monitor.py @@ -117,7 +117,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group: str | None = None self.cmdr: str | None = None self.system: str | None = None - self.coordinates: Tuple[float, float, float] | None = None self.systempopulation: int | None = None self.station: str | None = None self.station_marketid: int | None = None @@ -306,7 +305,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.cmdr = None self.system = None self.state['SystemAddress'] = None - self.coordinates = None + self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None @@ -529,7 +528,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'timestamp': strftime('%Y-%m-%dT%H:%M:%SZ', gmtime()), 'event': 'StartUp', 'StarSystem': self.system, - 'StarPos': self.coordinates, + 'StarPos': self.state['StarPos'], 'SystemAddress': self.state['SystemAddress'], 'Population': self.systempopulation, } @@ -581,7 +580,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group = None self.system = None self.state['SystemAddress'] = None - self.state['StarPos'] = self.coordinates = None + self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None self.station = None @@ -618,7 +617,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group = entry.get('Group') self.system = None self.state['SystemAddress'] = None - self.state['StarPos'] = self.coordinates = None + self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None @@ -839,21 +838,18 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'docked': self.state['IsDocked'] = True - self.station = entry.get('StationName') # May be None - self.station_marketid = entry.get('MarketID') # May be None - self.stationtype = entry.get('StationType') # May be None + self.station = entry.get('StationName') # It may be None + self.station_marketid = entry.get('MarketID') # It may be None + self.stationtype = entry.get('StationType') # It may be None self.stationservices = entry.get('StationServices') # None under E:D < 2.4 - # No need to set self.state['Taxi'] or Dropship here, if its those, the next event is a Disembark anyway + # No need to set self.state['Taxi'] or Dropship here, if it's + # those, the next event is a Disembark anyway elif event_type in ('location', 'fsdjump', 'carrierjump'): - # alpha4 - any changes ? - # Location: - # New in Odyssey: - # • Taxi: bool - # • Multicrew: bool - # • InSRV: bool - # • OnFoot: bool + ############################################################### + # Track: Body + ############################################################### if event_type in ('location', 'carrierjump'): # We're not guaranteeing this is a planet, rather than a # station. @@ -861,21 +857,32 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = entry.get('BodyID') self.state['BodyType'] = entry.get('BodyType') - if event_type == 'location': - logger.trace_if('journal.locations', '"Location" event') - self.state['IsDocked'] = entry.get('Docked', False) - elif event_type == 'fsdjump': self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None + ############################################################### + ############################################################### + # Track: IsDocked + ############################################################### + if event_type == 'location': + logger.trace_if('journal.locations', '"Location" event') + self.state['IsDocked'] = entry.get('Docked', False) + ############################################################### + + ############################################################### + # Track: Current System + ############################################################### if 'StarPos' in entry: # Plugins need this as well, so copy in state - self.state['StarPos'] = self.coordinates = tuple(entry['StarPos']) # type: ignore + self.state['StarPos'] = tuple(entry['StarPos']) # type: ignore + + else: + logger.warning(f"'{event_type}' event without 'StarPos' !!!:\n{entry}\n") if 'SystemAddress' not in entry: - logger.warning(f'"location" event without SystemAddress !!!:\n{entry}\n') + logger.warning(f"{event_type} event without SystemAddress !!!:\n{entry}\n") # But we'll still *use* the value, because if a 'location' event doesn't # have this we've still moved and now don't know where and MUST NOT @@ -890,8 +897,12 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below else: self.system = entry['StarSystem'] + ############################################################### - self.station = entry.get('StationName') # May be None + ############################################################### + # Track: Current station, if applicable + ############################################################### + self.station = entry.get('StationName') # It may be None # If on foot in-station 'Docked' is false, but we have a # 'BodyType' of 'Station', and the 'Body' is the station name # NB: No MarketID @@ -901,10 +912,15 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.station_marketid = entry.get('MarketID') # May be None self.stationtype = entry.get('StationType') # May be None self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location' + ############################################################### + ############################################################### + # Track: Whether in a Taxi/Dropship + ############################################################### self.state['Taxi'] = entry.get('Taxi', None) if not self.state['Taxi']: self.state['Dropship'] = None + ############################################################### elif event_type == 'approachbody': self.state['Body'] = entry['Body'] @@ -1618,36 +1634,35 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'joinacrew': self.state['Captain'] = entry['Captain'] self.state['Role'] = 'Idle' + self.state['StarPos'] = None + self.system = None + self.state['SystemAddress'] = None + self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None - self.system = None + self.state['BodyType'] = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None - self.coordinates = None - self.state['SystemAddress'] = None self.state['OnFoot'] = False - self.state['Body'] = None - self.state['BodyType'] = None - elif event_type == 'changecrewrole': self.state['Role'] = entry['Role'] elif event_type == 'quitacrew': self.state['Captain'] = None self.state['Role'] = None + self.system = None + self.state['SystemAddress'] = None + self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None - self.system = None self.station = None self.station_marketid = None self.stationtype = None self.stationservices = None - self.coordinates = None - self.state['SystemAddress'] = None # TODO: on_foot: Will we get an event after this to know ? diff --git a/plugins/eddn.py b/plugins/eddn.py index f1a5c162..dac4e303 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2217,16 +2217,6 @@ def journal_entry( # noqa: C901, CCR001 this.coordinates = state['StarPos'] this.systemaddress = state['SystemAddress'] - if event_name in ('location', 'fsdjump', 'docked', 'carrierjump'): - if 'StarPos' in entry: - this.coordinates = tuple(entry['StarPos']) - - elif this.systemaddress != entry.get('SystemAddress'): - this.coordinates = None # Docked event doesn't include coordinates - - if 'SystemAddress' not in entry: - logger.warning(f'"location" event without SystemAddress !!!:\n{entry}\n') - if event_name == 'docked': # Trigger a send/retry of pending EDDN messages this.eddn.parent.after(this.eddn.REPLAY_DELAY, this.eddn.sender.queue_check_and_send, False) From 6f3967fb7fa13fa48bc457114c7e2e8ad24cdd3a Mon Sep 17 00:00:00 2001 From: Athanasius Date: Tue, 3 Jan 2023 18:55:42 +0000 Subject: [PATCH 09/30] eddn/tracking: Tweak commenting about coordinates * `entry_augment_system_data()` will now always be passed starpos based on state['StarPos']. * Removed TODO about deprecating in-plugin tracking. --- plugins/eddn.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index dac4e303..5366f73e 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -1123,11 +1123,10 @@ class EDDN: entry['SystemAddress'] = this.systemaddress if 'StarPos' not in entry: - # Prefer the passed-in, probably monitor.state version + # Prefer the passed-in version if system_coordinates is not None: entry['StarPos'] = system_coordinates - # TODO: Deprecate in-plugin tracking elif this.coordinates is not None: entry['StarPos'] = list(this.coordinates) From 386ea1636e7943c4e1bbec9f28102a5d5bc20424 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 11:26:35 +0000 Subject: [PATCH 10/30] eddn: For 'docked' only set entry Body(Type) if latter is 'Planet' We explicitly must not set this for other BodyType, e.g. 'Station'. --- plugins/eddn.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 5366f73e..0a20bdfc 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2323,10 +2323,10 @@ def journal_entry( # noqa: C901, CCR001 ] # add planet to Docked event for planetary stations if known - if event_name == 'docked' and this.body_name: - # FIXME - Is this correct if using monitor.py tracking ? - entry['Body'] = this.body_name - entry['BodyType'] = 'Planet' + if event_name == 'docked' and state['Body'] is not None: + if state['BodyType'] == 'Planet': + entry['Body'] = state['Body'] + entry['BodyType'] = state['BodyType'] # The generic journal schema is for events: # Docked, FSDJump, Scan, Location, SAASignalsFound, CarrierJump From edc23081b15023237a11eff302a6be84514bdc7f Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 11:29:46 +0000 Subject: [PATCH 11/30] monitor: Extend 'approachbody' comment to call out use in plugins/eddn.py We're setting `self.state['BodyType']` specifically so plugins/eddn.py's 'docked' handling can use it as a check. --- monitor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monitor.py b/monitor.py index f34c41da..61e03759 100644 --- a/monitor.py +++ b/monitor.py @@ -927,6 +927,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = entry.get('BodyID') # This isn't in the event, but Journal doc for ApproachBody says: # when in Supercruise, and distance from planet drops to within the 'Orbital Cruise' zone + # Used in plugins/eddn.py for setting entry Body/BodyType + # on 'docked' events when Planetary. self.state['BodyType'] = 'Planet' elif event_type == 'leavebody': From 427a238dee5ddf957b0fc8b683e67e98e03c2235 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 11:34:58 +0000 Subject: [PATCH 12/30] eddn: Remove un-necessary 'leavebody' state clearing This is now handled in monitor.py, and *this* code explicitly sets the 'this' values to those in `state` as passed in. --- plugins/eddn.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 0a20bdfc..f76274a8 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2220,14 +2220,6 @@ def journal_entry( # noqa: C901, CCR001 # Trigger a send/retry of pending EDDN messages this.eddn.parent.after(this.eddn.REPLAY_DELAY, this.eddn.sender.queue_check_and_send, False) - elif event_name == 'leavebody': - # NB: **NOT** SupercruiseEntry, because we won't get a fresh - # ApproachBody if we don't leave Orbital Cruise and land again. - # *This* is triggered when you go above Orbital Cruise altitude. - # Status.json BodyName clears when the OC/Glide HUD is deactivated. - this.body_name = None - this.body_id = None - elif event_name == 'music': if entry['MusicTrack'] == 'MainMenu': this.body_name = None From fafe9a5f7b940a4dc90c0ac38caabf2a895a237a Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 11:37:13 +0000 Subject: [PATCH 13/30] eddn: Remove un-necessary 'music'/'MainMenu' body tracking clearance monitor.py does this for `state` passed in, which *this* code then uses to set `this` values. --- plugins/eddn.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index f76274a8..cd29d215 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2222,8 +2222,6 @@ def journal_entry( # noqa: C901, CCR001 elif event_name == 'music': if entry['MusicTrack'] == 'MainMenu': - this.body_name = None - this.body_id = None this.status_body_name = None # Events with their own EDDN schema From b1308e4f28f4cc126b496e199d65a68aef7988ac Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 12:18:13 +0000 Subject: [PATCH 14/30] PLUGINS.md: Document addition of Bodt(ID|Type) and the caveats about use --- PLUGINS.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index 0378ef96..279f6b5b 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -653,8 +653,9 @@ Content of `state` (updated to the current journal entry): | `SuitLoadouts` | `dict`[2] | CAPI-returned data of all Suit Loadouts. NB: May be `None` if no data. | | `Taxi` | `Optional[bool]` | Whether or not we're currently in a taxi. NB: This is best effort with what the journals provide. | | `Dropship` | `Optional[bool]` | Whether or not the above taxi is a Dropship | -| `Body` | `Optional[str]` | The body we're currently on / in the SOI of | -| `BodyType` | `Optional[str]` | The type of body that `Body` refers to | +| `Body`[3] | `Optional[str]` | Name of the body we're currently on / in the SOI of | +| `BodyID`[3] | `Optional[int]` | ID of the body we're currently on / in the SOI of | +| `BodyType`[3] | `Optional[str]` | The type of body that `Body` refers to | [1] - Contents of `NavRoute` not changed if a `NavRouteClear` event is seen, but plugins will see the `NavRouteClear` event. @@ -676,6 +677,28 @@ least one member is missing, so the indices are not contiguous). We choose to always convert to the integer-keyed `dict` form so that code utilising the data is simpler. +[3] - There are some caveats with the Body data. Firstly the name and ID +can be for the orbital station or fleet carrier the player is docked at. +Check 'BodyType' before using the values. + +Secondly there is an issue with close-orbiting binary bodies. If the player: + +1. Enters Orbital Cruise around a Body an 'ApproachBody' event is emitted + and the tracking will update to reflect this. +2. If the player then flies *in Orbital Cruise without entering Supercruise + proper* to the close-orbiting binary partner of the Body then *there is no + new 'ApproachBody' event to indicate the new Body's details*. **Thus this + tracking will incorrectly indicate the first Body still**. + +So, before making use of any of this Body state a plugin should: + +1. Have a `dashboard_entry()` method and track the Body name present in its + data. +2. Cross-check that Body name with `state['Body']` before making use of any + of `state'`s Body data. + +See `plugins/eddn.py` for an example of this in `export_journal_codexentry()`. + New in version 4.1.6: `CargoJSON` contains the raw data from the last read of `Cargo.json` passed @@ -765,6 +788,12 @@ re-start EDMarketConnector. That will be present when plugins are invoked with the synthetic `StartUp` event. NB: Might just be a `NavRouteClear` event if that's what was in the file. +New in version 5.8.0: +`BodyID` and `BodyType` have been added to the `state` dictionary. These +now track in the same manner as prior core EDDN plugin code. Check the +documentation above for some caveats. Do not just blindly use this data, or +the 'Body' name value. + ___ ##### Synthetic Events From d533919790c3909db40802a77162c44fa02f1a61 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 12:18:41 +0000 Subject: [PATCH 15/30] monitor: Add some documentation about the player location tracking caveats --- monitor.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/monitor.py b/monitor.py index 61e03759..97d6bca5 100644 --- a/monitor.py +++ b/monitor.py @@ -837,6 +837,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None elif event_type == 'docked': + ############################################################### + # Track: Station + ############################################################### self.state['IsDocked'] = True self.station = entry.get('StationName') # It may be None self.station_marketid = entry.get('MarketID') # It may be None @@ -845,8 +848,51 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # No need to set self.state['Taxi'] or Dropship here, if it's # those, the next event is a Disembark anyway + ############################################################### elif event_type in ('location', 'fsdjump', 'carrierjump'): + """ + Notes on tracking of a player's location. + + Body + --- + There are some caveats about tracking Body name, ID and type, + mostly due to close-orbiting binary planets/moons. + + Presence on or near a Body is indicated in several scenarios: + + 1. When the player logs in. + 2. When the player's location changes due to being docked + on a Fleet Carrier when it jumps. + 3. When the player flies within Orbital Cruise range of a + Body. + + For the first case this will always be a 'Location' event. + If landed on a Body, or docked at a surface port then this + will be indicated. However, if docked at an orbital station + the 'Body' is the name of that station, with 'BodyType' having + 'Station' as its value. + + In the second case although it *should* be a 'CarrierJump' + event, for a while now it's actually been a 'Location' event. + This should follow the same rules as being docked at an + orbital station. + + For the last case there are some caveats to do with close + orbiting binary bodies: + + 1. 'ApproachBody' indicates presence near the Body in question. + 2. 'LeaveBody' indicates the player is no longer considered + to be near the Body. This is specifically when no longer + in Orbital Cruise around the Body such that the HUD for that + has been switched out for the normal SuperCruise one. + 3. 'SupercruiseExit' does not indicate any change of presence + near a Body. + 4. 'SupercruiseEntry' *also* **DOES NOT** indicate that the + player is no longer near the Body. They can easily utilise + Orbital Cruise to rapidly travel around the Body and then + land on it again **without a fresh 'ApproachBody'** event. + """ ############################################################### # Track: Body ############################################################### From dab69367e2f627fe42ec689e03b08a2721cb8017 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 12:23:09 +0000 Subject: [PATCH 16/30] monitor: Cite the Status.json body workaround for Body data caveat --- monitor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monitor.py b/monitor.py index 97d6bca5..d7eefe88 100644 --- a/monitor.py +++ b/monitor.py @@ -892,6 +892,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below player is no longer near the Body. They can easily utilise Orbital Cruise to rapidly travel around the Body and then land on it again **without a fresh 'ApproachBody'** event. + + The only way to check for this is to utilise the Body (name) + present in `Status.json` data, as this *will* correctly + reflect the second Body. """ ############################################################### # Track: Body From fa1c072d9e8a84cef8db5c0683b0327524a62917 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 15:05:29 +0000 Subject: [PATCH 17/30] monitor: Change .system to state['SystemName'] 1. EDDB plugin needs to track the system name, but we're moving all of that into monitor.py. 2. monitor.py was tracking this in monitor.system, but it needs to be in monitor.state['SystemName'] in order for plugins to access it. So, move monitor.system to monitor.state['SystemName'] and update all uses. --- EDMC.py | 11 ++++++----- EDMarketConnector.py | 43 +++++++++++++++++++++++++++---------------- monitor.py | 17 ++++++++--------- plugins/eddb.py | 2 ++ 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/EDMC.py b/EDMC.py index 2a7d7cd4..b3cce61d 100755 --- a/EDMC.py +++ b/EDMC.py @@ -326,7 +326,7 @@ sys.path: {sys.path}''' raise companion.CmdrError() elif ( - data['lastSystem']['name'] != monitor.system or + data['lastSystem']['name'] != monitor.state['SystemName'] or ((data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.station) or data['ship']['id'] != monitor.state['ShipID'] or data['ship']['name'].lower() != monitor.state['ShipType'] @@ -431,10 +431,11 @@ sys.path: {sys.path}''' new_data = capi_response.capi_data # might have undocked while we were waiting for retry in which case station data is unreliable - if new_data['commander'].get('docked') and \ - deep_get(new_data, 'lastSystem', 'name') == monitor.system and \ - deep_get(new_data, 'lastStarport', 'name') == monitor.station: - + if ( + new_data['commander'].get('docked') + and deep_get(new_data, 'lastSystem', 'name') == monitor.state['SystemName'] + and deep_get(new_data, 'lastStarport', 'name') == monitor.station + ): data = new_data if args.s: diff --git a/EDMarketConnector.py b/EDMarketConnector.py index fe31304d..8ac7e938 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1089,7 +1089,7 @@ class AppWindow(object): self.status['text'] = _('CAPI query aborted: GameVersion unknown') return - if not monitor.system: + if not monitor.state['SystemName']: logger.trace_if('capi.worker', 'Aborting Query: Current star system unknown') # LANG: CAPI queries aborted because current star system name unknown self.status['text'] = _('CAPI query aborted: Current system unknown') @@ -1272,9 +1272,10 @@ class AppWindow(object): f"not {capi_response.capi_data['commander'].get('docked')!r}") raise companion.ServerLagging() - elif capi_response.capi_data['lastSystem']['name'] != monitor.system: + elif capi_response.capi_data['lastSystem']['name'] != monitor.state['SystemName']: # CAPI system must match last journal one - logger.warning(f"{capi_response.capi_data['lastSystem']['name']!r} != {monitor.system!r}") + logger.warning(f"{capi_response.capi_data['lastSystem']['name']!r} != " + f"{monitor.state['SystemName']!r}") raise companion.ServerLagging() elif capi_response.capi_data['lastStarport']['name'] != monitor.station: @@ -1526,7 +1527,7 @@ class AppWindow(object): self.update_suit_text() self.suit_show_if_set() - self.edit_menu.entryconfigure(0, state=monitor.system and tk.NORMAL or tk.DISABLED) # Copy + self.edit_menu.entryconfigure(0, state=monitor.state['SystemName'] and tk.NORMAL or tk.DISABLED) # Copy if entry['event'] in ( 'Undocked', @@ -1589,7 +1590,7 @@ class AppWindow(object): err = plug.notify_journal_entry( monitor.cmdr, monitor.is_beta, - monitor.system, + monitor.state['SystemName'], monitor.station, entry, monitor.state @@ -1728,11 +1729,16 @@ class AppWindow(object): def system_url(self, system: str) -> str | None: """Despatch a system URL to the configured handler.""" - return plug.invoke(config.get_str('system_provider'), 'EDSM', 'system_url', monitor.system) + return plug.invoke( + config.get_str('system_provider'), 'EDSM', 'system_url', monitor.state['SystemName'] + ) def station_url(self, station: str) -> str | None: """Despatch a station URL to the configured handler.""" - return plug.invoke(config.get_str('station_provider'), 'eddb', 'station_url', monitor.system, monitor.station) + return plug.invoke( + config.get_str('station_provider'), 'eddb', 'station_url', + monitor.state['SystemName'], monitor.station + ) def cooldown(self) -> None: """Display and update the cooldown timer for 'Update' button.""" @@ -1746,12 +1752,14 @@ class AppWindow(object): else: self.button['text'] = self.theme_button['text'] = _('Update') # LANG: Update button in main window - self.button['state'] = self.theme_button['state'] = (monitor.cmdr and - monitor.mode and - monitor.mode != 'CQC' and - not monitor.state['Captain'] and - monitor.system and - tk.NORMAL or tk.DISABLED) + self.button['state'] = self.theme_button['state'] = ( + monitor.cmdr and + monitor.mode and + monitor.mode != 'CQC' and + not monitor.state['Captain'] and + monitor.state['SystemName'] and + tk.NORMAL or tk.DISABLED + ) if sys.platform == 'win32': def ontop_changed(self, event=None) -> None: @@ -1761,9 +1769,12 @@ class AppWindow(object): def copy(self, event=None) -> None: """Copy system, and possible station, name to clipboard.""" - if monitor.system: + if monitor.state['SystemName']: self.w.clipboard_clear() - self.w.clipboard_append(monitor.station and f'{monitor.system},{monitor.station}' or monitor.system) + self.w.clipboard_append( + f"{monitor.state['SystemName']},{monitor.station}" if monitor.station + else monitor.state['SystemName'] + ) def help_general(self, event=None) -> None: """Open Wiki Help page in browser.""" @@ -1898,7 +1909,7 @@ class AppWindow(object): defaultextension=default_extension, filetypes=[('JSON', '.json'), ('All Files', '*')], initialdir=config.get_str('outdir'), - initialfile=f'{monitor.system}.{monitor.station}.{timestamp}' + initialfile=f"{monitor.state['SystemName']}.{monitor.station}.{timestamp}" ) if not f: return diff --git a/monitor.py b/monitor.py index d7eefe88..a1a9ff63 100644 --- a/monitor.py +++ b/monitor.py @@ -116,7 +116,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.system: str | None = None self.systempopulation: int | None = None self.station: str | None = None self.station_marketid: int | None = None @@ -191,6 +190,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'Dropship': None, # Best effort as to whether or not the above taxi is a dropship. 'StarPos': None, # Best effort current system's galaxy position. 'SystemAddress': None, + 'SystemName': None, 'Body': None, 'BodyID': None, 'BodyType': None, @@ -303,7 +303,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = None self.group = None self.cmdr = None - self.system = None self.state['SystemAddress'] = None self.state['StarPos'] = None self.state['Body'] = None @@ -527,7 +526,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below entry: dict[str, Any] = { 'timestamp': strftime('%Y-%m-%dT%H:%M:%SZ', gmtime()), 'event': 'StartUp', - 'StarSystem': self.system, + 'StarSystem': self.state['SystemName'], 'StarPos': self.state['StarPos'], 'SystemAddress': self.state['SystemAddress'], 'Population': self.systempopulation, @@ -578,7 +577,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.cmdr = None self.mode = None self.group = None - self.system = None + self.state['SystemName'] = None self.state['SystemAddress'] = None self.state['StarPos'] = None self.state['Body'] = None @@ -615,7 +614,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = entry.get('GameMode') self.group = entry.get('Group') - self.system = None + self.state['SystemName'] = None self.state['SystemAddress'] = None self.state['StarPos'] = None self.state['Body'] = None @@ -943,10 +942,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.systempopulation = entry.get('Population') if entry['StarSystem'] == 'ProvingGround': - self.system = 'CQC' + self.state['SystemName'] = 'CQC' else: - self.system = entry['StarSystem'] + self.state['SystemName'] = entry['StarSystem'] ############################################################### ############################################################### @@ -1687,7 +1686,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Captain'] = entry['Captain'] self.state['Role'] = 'Idle' self.state['StarPos'] = None - self.system = None + self.state['SystemName'] = None self.state['SystemAddress'] = None self.state['StarPos'] = None self.state['Body'] = None @@ -1705,7 +1704,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'quitacrew': self.state['Captain'] = None self.state['Role'] = None - self.system = None + self.state['SystemName'] = None self.state['SystemAddress'] = None self.state['StarPos'] = None self.state['Body'] = None diff --git a/plugins/eddb.py b/plugins/eddb.py index a5d0593a..2dd2d787 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -184,6 +184,8 @@ def journal_entry( # noqa: CCR001 return this.on_foot = state['OnFoot'] + this.system_address = state['SystemAddress'] + # Always update our system address even if we're not currently the provider for system or station, but dont update # on events that contain "future" data, such as FSDTarget if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): From 86e81adb3d96ba365aaa55f9cab3f38d9327618e Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 15:17:39 +0000 Subject: [PATCH 18/30] EDDB: Rename this.system to this.system_name --- plugins/eddb.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/plugins/eddb.py b/plugins/eddb.py index 2dd2d787..1c53ae5b 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -42,7 +42,7 @@ # ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# # ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# ! $# import tkinter -from typing import TYPE_CHECKING, Any, Mapping, Optional +from typing import TYPE_CHECKING, Any, Mapping import requests @@ -69,12 +69,12 @@ class This: def __init__(self) -> None: # Main window clicks self.system_link: tkinter.Widget - self.system: Optional[str] = None - self.system_address: Optional[str] = None - self.system_population: Optional[int] = None + self.system_name: str | None = None + self.system_address: str | None = None + self.system_population: int | None = None self.station_link: tkinter.Widget - self.station: Optional[str] = None - self.station_marketid: Optional[int] = None + self.station: str | None = None + self.station_marketid: int | None = None self.on_foot = False @@ -133,7 +133,7 @@ def plugin_app(parent: 'Tk'): """ # system label in main window this.system_link = parent.nametowidget(f".{appname.lower()}.system") - this.system = None + this.system_name = None this.system_address = None this.station = None this.station_marketid = None # Frontier MarketID @@ -185,12 +185,13 @@ def journal_entry( # noqa: CCR001 this.on_foot = state['OnFoot'] this.system_address = state['SystemAddress'] + this.system_name = state['SystemName'] # Always update our system address even if we're not currently the provider for system or station, but dont update # on events that contain "future" data, such as FSDTarget if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): this.system_address = entry.get('SystemAddress') or this.system_address - this.system = entry.get('StarSystem') or this.system + this.system_name = entry.get('StarSystem') or this.system_name # We need pop == 0 to set the value so as to clear 'x' in systems with # no stations. @@ -217,7 +218,7 @@ def journal_entry( # noqa: CCR001 # Only actually change URLs if we are current provider. if config.get_str('system_provider') == 'eddb': - this.system_link['text'] = this.system + this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() @@ -238,7 +239,7 @@ def journal_entry( # noqa: CCR001 this.station_link.update_idletasks() -def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: +def cmdr_data(data: CAPIData, is_beta: bool) -> str | None: """ Process new CAPI data. @@ -251,15 +252,15 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: this.station_marketid = data['lastStarport']['id'] # Only trust CAPI if these aren't yet set - if not this.system: - this.system = data['lastSystem']['name'] + if not this.system_name: + this.system_name = data['lastSystem']['name'] if not this.station and data['commander']['docked']: this.station = data['lastStarport']['name'] # Override standard URL functions if config.get_str('system_provider') == 'eddb': - this.system_link['text'] = this.system + this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() From dbad45cf3b1d7eab6d7880ac46ed0bd4a2842dfe Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 15:20:21 +0000 Subject: [PATCH 19/30] EDDB: Use only state['SystemName'] for this.system_name tracking --- plugins/eddb.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/eddb.py b/plugins/eddb.py index 1c53ae5b..51291c37 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -187,12 +187,6 @@ def journal_entry( # noqa: CCR001 this.system_address = state['SystemAddress'] this.system_name = state['SystemName'] - # Always update our system address even if we're not currently the provider for system or station, but dont update - # on events that contain "future" data, such as FSDTarget - if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): - this.system_address = entry.get('SystemAddress') or this.system_address - this.system_name = entry.get('StarSystem') or this.system_name - # We need pop == 0 to set the value so as to clear 'x' in systems with # no stations. pop = entry.get('Population') From df5eb5b27045eb9cfdb5e530ed54c5178edc55d6 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 15:37:07 +0000 Subject: [PATCH 20/30] monitor/tracking: Switch .systempopulation to state['SystemPopulation'] 1. EDDB plugin tracked this for keeping the Station link text up to date. * So moved it to monitor.state['SystemPopulation']. * PLUGINS.md updated to cite this. * PLUGINS.md also updated to note state entries that are set to None if remote multi-crew is detected. --- PLUGINS.md | 26 +++++++++++++++++++------- monitor.py | 16 +++++++++++----- plugins/eddb.py | 7 +------ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index 279f6b5b..8d30a140 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -607,11 +607,11 @@ This gets called when EDMarketConnector sees a new entry in the game's journal. Content of `state` (updated to the current journal entry): | Field | Type | Description | -| :------------------- | :-------------------------: |:----------------------------------------------------------------------------------------------------------------| +|:---------------------|:---------------------------:|:----------------------------------------------------------------------------------------------------------------| | `GameLanguage` | `Optional[str]` | `language` value from `Fileheader` event. | | `GameVersion` | `Optional[str]` | `version` value from `Fileheader` event. | | `GameBuild` | `Optional[str]` | `build` value from `Fileheader` event. | -| `Captain` | `Optional[str]` | Name of the commander who's crew you're on, if any | +| `Captain`[3] | `Optional[str]` | Name of the commander who's crew you're on, if any | | `Cargo` | `dict` | Current cargo. Note that this will be totals, and any mission specific duplicates will be counted together | | `CargoJSON` | `dict` | content of cargo.json as of last read. | | `Credits` | `int` | Current credits balance | @@ -639,7 +639,7 @@ Content of `state` (updated to the current journal entry): | `NavRoute` | `dict` | Last plotted multi-hop route[1] | | `ModuleInfo` | `dict` | Last loaded ModulesInfo.json data | | `IsDocked` | `bool` | Whether the Cmdr is currently docked *in their own ship*. | -| `OnFoot` | `bool` | Whether the Cmdr is on foot | +| `OnFoot`[3] | `bool` | Whether the Cmdr is on foot | | `Component` | `dict` | 'Component' MicroResources in Odyssey, `int` count each. | | `Item` | `dict` | 'Item' MicroResources in Odyssey, `int` count each. | | `Consumable` | `dict` | 'Consumable' MicroResources in Odyssey, `int` count each. | @@ -653,9 +653,13 @@ Content of `state` (updated to the current journal entry): | `SuitLoadouts` | `dict`[2] | CAPI-returned data of all Suit Loadouts. NB: May be `None` if no data. | | `Taxi` | `Optional[bool]` | Whether or not we're currently in a taxi. NB: This is best effort with what the journals provide. | | `Dropship` | `Optional[bool]` | Whether or not the above taxi is a Dropship | -| `Body`[3] | `Optional[str]` | Name of the body we're currently on / in the SOI of | -| `BodyID`[3] | `Optional[int]` | ID of the body we're currently on / in the SOI of | -| `BodyType`[3] | `Optional[str]` | The type of body that `Body` refers to | +| `SystemAddress`[3] | `Optional[int]` | Unique [ID64](http://disc.thargoid.space/ID64) of the star system we're currently in | +| `SystemName`[3] | `Optional[str]` | Name of the star system we're currently in | +| `SystemPopulation`[3]| `Optional[int]` | Population of the star system we're currently in | +| `StarPos`[3] | `Optional[tuple[float]]` | Galaxy co-ordinates of the system we're currently in | +| `Body`[3][4] | `Optional[str]` | Name of the body we're currently on / in the SOI of | +| `BodyID`[3][4] | `Optional[int]` | ID of the body we're currently on / in the SOI of | +| `BodyType`[3][4] | `Optional[str]` | The type of body that `Body` refers to | [1] - Contents of `NavRoute` not changed if a `NavRouteClear` event is seen, but plugins will see the `NavRouteClear` event. @@ -677,7 +681,10 @@ least one member is missing, so the indices are not contiguous). We choose to always convert to the integer-keyed `dict` form so that code utilising the data is simpler. -[3] - There are some caveats with the Body data. Firstly the name and ID +[3] - Forced to `None` if the player joins another player's ship in remote +multi-crew. + +[4] - There are some caveats with the Body data. Firstly the name and ID can be for the orbital station or fleet carrier the player is docked at. Check 'BodyType' before using the values. @@ -789,6 +796,11 @@ with the synthetic `StartUp` event. NB: Might just be a `NavRouteClear` event if that's what was in the file. New in version 5.8.0: + +`StarPos`, `SystemAddress`, `SystemName` and `SystemPopulation` have been +added to the `state` dictionary. Best efforts data pertaining to the star +system the player is in. + `BodyID` and `BodyType` have been added to the `state` dictionary. These now track in the same manner as prior core EDDN plugin code. Check the documentation above for some caveats. Do not just blindly use this data, or diff --git a/monitor.py b/monitor.py index a1a9ff63..3df19170 100644 --- a/monitor.py +++ b/monitor.py @@ -116,7 +116,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.systempopulation: int | None = None self.station: str | None = None self.station_marketid: int | None = None self.stationtype: str | None = None @@ -191,6 +190,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'StarPos': None, # Best effort current system's galaxy position. 'SystemAddress': None, 'SystemName': None, + 'SystemPopulation': None, 'Body': None, 'BodyID': None, 'BodyType': None, @@ -304,6 +304,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.group = None self.cmdr = None self.state['SystemAddress'] = None + self.state['SystemName'] = None + self.state['SystemPopulation'] = None self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None @@ -529,7 +531,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'StarSystem': self.state['SystemName'], 'StarPos': self.state['StarPos'], 'SystemAddress': self.state['SystemAddress'], - 'Population': self.systempopulation, + 'Population': self.state['SystemPopulation'], } if self.state['Body']: @@ -577,8 +579,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.cmdr = None self.mode = None self.group = None - self.state['SystemName'] = None self.state['SystemAddress'] = None + self.state['SystemName'] = None + self.state['SystemPopulation'] = None self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None @@ -614,8 +617,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode = entry.get('GameMode') self.group = entry.get('Group') - self.state['SystemName'] = None self.state['SystemAddress'] = None + self.state['SystemName'] = None + self.state['SystemPopulation'] = None self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None @@ -939,7 +943,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Yes, explicitly state `None` here, so it's crystal clear. self.state['SystemAddress'] = entry.get('SystemAddress', None) - self.systempopulation = entry.get('Population') + self.state['SystemPopulation'] = entry.get('Population') if entry['StarSystem'] == 'ProvingGround': self.state['SystemName'] = 'CQC' @@ -1688,6 +1692,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['StarPos'] = None self.state['SystemName'] = None self.state['SystemAddress'] = None + self.state['SystemPopulation'] = None self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None @@ -1706,6 +1711,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Role'] = None self.state['SystemName'] = None self.state['SystemAddress'] = None + self.state['SystemPopulation'] = None self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None diff --git a/plugins/eddb.py b/plugins/eddb.py index 51291c37..41a32fd7 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -186,12 +186,7 @@ def journal_entry( # noqa: CCR001 this.on_foot = state['OnFoot'] this.system_address = state['SystemAddress'] this.system_name = state['SystemName'] - - # We need pop == 0 to set the value so as to clear 'x' in systems with - # no stations. - pop = entry.get('Population') - if pop is not None: - this.system_population = pop + this.system_population = state['SystemPopulation'] this.station = entry.get('StationName') or this.station # on_foot station detection From dde0cf876c02ba061318eff2f9c9e7cc4c0efc95 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 16:14:19 +0000 Subject: [PATCH 21/30] monitor/tracking: Move .station to state['StationName'] 1. EDDB tracks this. * So move monitor.station to monitor.state['StationName']. * PLUGINS.md updated to cite this. --- EDMC.py | 12 +++++---- EDMarketConnector.py | 23 ++++++++--------- PLUGINS.md | 3 +++ monitor.py | 59 +++++++++++++++++++++++++++----------------- plugins/eddb.py | 30 +++++++++------------- plugins/eddn.py | 2 +- 6 files changed, 71 insertions(+), 58 deletions(-) diff --git a/EDMC.py b/EDMC.py index b3cce61d..f56f7ead 100755 --- a/EDMC.py +++ b/EDMC.py @@ -326,10 +326,12 @@ sys.path: {sys.path}''' raise companion.CmdrError() elif ( - data['lastSystem']['name'] != monitor.state['SystemName'] or - ((data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.station) or - data['ship']['id'] != monitor.state['ShipID'] or - data['ship']['name'].lower() != monitor.state['ShipType'] + data['lastSystem']['name'] != monitor.state['SystemName'] + or ( + (data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.state['StationName'] + ) + or data['ship']['id'] != monitor.state['ShipID'] + or data['ship']['name'].lower() != monitor.state['ShipType'] ): raise companion.ServerLagging() @@ -434,7 +436,7 @@ sys.path: {sys.path}''' if ( new_data['commander'].get('docked') and deep_get(new_data, 'lastSystem', 'name') == monitor.state['SystemName'] - and deep_get(new_data, 'lastStarport', 'name') == monitor.station + and deep_get(new_data, 'lastStarport', 'name') == monitor.state['StationName'] ): data = new_data diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 8ac7e938..57f56982 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1278,18 +1278,19 @@ class AppWindow(object): f"{monitor.state['SystemName']!r}") raise companion.ServerLagging() - elif capi_response.capi_data['lastStarport']['name'] != monitor.station: - if monitor.state['OnFoot'] and monitor.station: - logger.warning(f"({capi_response.capi_data['lastStarport']['name']!r} != {monitor.station!r}) AND " - f"{monitor.state['OnFoot']!r} and {monitor.station!r}") + elif capi_response.capi_data['lastStarport']['name'] != monitor.state['StationName']: + if monitor.state['OnFoot'] and monitor.state['StationName']: + logger.warning(f"({capi_response.capi_data['lastStarport']['name']!r} != " + f"{monitor.state['StationName']!r}) AND " + f"{monitor.state['OnFoot']!r} and {monitor.state['StationName']!r}") raise companion.ServerLagging() - elif capi_response.capi_data['commander']['docked'] and monitor.station is None: + elif capi_response.capi_data['commander']['docked'] and monitor.state['StationName'] is None: # Likely (re-)Embarked on ship docked at an EDO settlement. # Both Disembark and Embark have `"Onstation": false` in Journal. # So there's nothing to tell us which settlement we're (still, # or now, if we came here in Apex and then recalled ship) docked at. - logger.debug("docked AND monitor.station is None - so EDO settlement?") + logger.debug("docked AND monitor.state['StationName'] is None - so EDO settlement?") raise companion.NoMonitorStation() self.capi_query_holdoff_time = capi_response.query_time + companion.capi_query_cooldown @@ -1591,7 +1592,7 @@ class AppWindow(object): monitor.cmdr, monitor.is_beta, monitor.state['SystemName'], - monitor.station, + monitor.state['StationName'], entry, monitor.state ) @@ -1607,7 +1608,7 @@ class AppWindow(object): # Only if configured to do so if (not config.get_int('output') & config.OUT_MKT_MANUAL and config.get_int('output') & config.OUT_STATION_ANY): - if entry['event'] in ('StartUp', 'Location', 'Docked') and monitor.station: + if entry['event'] in ('StartUp', 'Location', 'Docked') and monitor.state['StationName']: # TODO: Can you log out in a docked Taxi and then back in to # the taxi, so 'Location' should be covered here too ? if entry['event'] == 'Docked' and entry.get('Taxi'): @@ -1737,7 +1738,7 @@ class AppWindow(object): """Despatch a station URL to the configured handler.""" return plug.invoke( config.get_str('station_provider'), 'eddb', 'station_url', - monitor.state['SystemName'], monitor.station + monitor.state['SystemName'], monitor.state['StationName'] ) def cooldown(self) -> None: @@ -1772,7 +1773,7 @@ class AppWindow(object): if monitor.state['SystemName']: self.w.clipboard_clear() self.w.clipboard_append( - f"{monitor.state['SystemName']},{monitor.station}" if monitor.station + f"{monitor.state['SystemName']},{monitor.state['StationName']}" if monitor.state['StationName'] else monitor.state['SystemName'] ) @@ -1909,7 +1910,7 @@ class AppWindow(object): defaultextension=default_extension, filetypes=[('JSON', '.json'), ('All Files', '*')], initialdir=config.get_str('outdir'), - initialfile=f"{monitor.state['SystemName']}.{monitor.station}.{timestamp}" + initialfile=f"{monitor.state['SystemName']}.{monitor.state['StationName']}.{timestamp}" ) if not f: return diff --git a/PLUGINS.md b/PLUGINS.md index 8d30a140..36beef9d 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -660,6 +660,7 @@ Content of `state` (updated to the current journal entry): | `Body`[3][4] | `Optional[str]` | Name of the body we're currently on / in the SOI of | | `BodyID`[3][4] | `Optional[int]` | ID of the body we're currently on / in the SOI of | | `BodyType`[3][4] | `Optional[str]` | The type of body that `Body` refers to | +| `StationName` | `Optional[str]` | Name of the station we're docked at, if applicable | [1] - Contents of `NavRoute` not changed if a `NavRouteClear` event is seen, but plugins will see the `NavRouteClear` event. @@ -806,6 +807,8 @@ now track in the same manner as prior core EDDN plugin code. Check the documentation above for some caveats. Do not just blindly use this data, or the 'Body' name value. +`StationName` added to the `state` dictionary. + ___ ##### Synthetic Events diff --git a/monitor.py b/monitor.py index 3df19170..19b57983 100644 --- a/monitor.py +++ b/monitor.py @@ -116,7 +116,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.station: str | None = None self.station_marketid: int | None = None self.stationtype: str | None = None self.started: int | None = None # Timestamp of the LoadGame event @@ -194,6 +193,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below 'Body': None, 'BodyID': None, 'BodyType': None, + 'StationName': None, 'NavRoute': None, } @@ -310,7 +310,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None @@ -585,7 +585,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['StarPos'] = None self.state['Body'] = None self.state['BodyID'] = None - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None @@ -624,7 +624,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None @@ -757,7 +757,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below modules.pop(from_slot, None) elif event_type == 'undocked': - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None @@ -779,9 +779,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # • StationName (if at a station) # • StationType # • MarketID - self.station = None + self.state['StationName'] = None if entry.get('OnStation'): - self.station = entry.get('StationName', '') + self.state['StationName'] = entry.get('StationName', '') self.state['OnFoot'] = False self.state['Taxi'] = entry['Taxi'] @@ -809,10 +809,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # • MarketID if entry.get('OnStation', False): - self.station = entry.get('StationName', '') + self.state['StationName'] = entry.get('StationName', '') else: - self.station = None + self.state['StationName'] = None self.state['OnFoot'] = True if self.state['Taxi'] is not None and self.state['Taxi'] != entry.get('Taxi', False): @@ -844,7 +844,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Track: Station ############################################################### self.state['IsDocked'] = True - self.station = entry.get('StationName') # It may be None + self.state['StationName'] = entry.get('StationName') # It may be None self.station_marketid = entry.get('MarketID') # It may be None self.stationtype = entry.get('StationType') # It may be None self.stationservices = entry.get('StationServices') # None under E:D < 2.4 @@ -955,16 +955,23 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below ############################################################### # Track: Current station, if applicable ############################################################### - self.station = entry.get('StationName') # It may be None - # If on foot in-station 'Docked' is false, but we have a - # 'BodyType' of 'Station', and the 'Body' is the station name - # NB: No MarketID - if entry.get('BodyType') and entry['BodyType'] == 'Station': - self.station = entry.get('Body') + if event_type == 'fsdjump': + self.state['StationName'] = None + self.station_marketid = None + self.stationtype = None + self.stationservices = None - self.station_marketid = entry.get('MarketID') # May be None - self.stationtype = entry.get('StationType') # May be None - self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location' + else: + self.state['StationName'] = entry.get('StationName') # It may be None + # If on foot in-station 'Docked' is false, but we have a + # 'BodyType' of 'Station', and the 'Body' is the station name + # NB: No MarketID + if entry.get('BodyType') and entry['BodyType'] == 'Station': + self.state['StationName'] = entry.get('Body') + + self.station_marketid = entry.get('MarketID') # May be None + self.stationtype = entry.get('StationType') # May be None + self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location' ############################################################### ############################################################### @@ -996,7 +1003,15 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # NB: Do **NOT** clear Body state, because we won't get a fresh # ApproachBody if we don't leave Orbital Cruise but land # again. - pass + + ############################################################### + # Track: Current station, if applicable + ############################################################### + self.state['StationName'] = None + self.station_marketid = None + self.stationtype = None + self.stationservices = None + ############################################################### elif event_type == 'music': if entry['MusicTrack'] == 'MainMenu': @@ -1697,7 +1712,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None @@ -1716,7 +1731,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Body'] = None self.state['BodyID'] = None self.state['BodyType'] = None - self.station = None + self.state['StationName'] = None self.station_marketid = None self.stationtype = None self.stationservices = None diff --git a/plugins/eddb.py b/plugins/eddb.py index 41a32fd7..dc6c7b63 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -73,7 +73,7 @@ class This: self.system_address: str | None = None self.system_population: int | None = None self.station_link: tkinter.Widget - self.station: str | None = None + self.station_name: str | None = None self.station_marketid: int | None = None self.on_foot = False @@ -135,7 +135,7 @@ def plugin_app(parent: 'Tk'): this.system_link = parent.nametowidget(f".{appname.lower()}.system") this.system_name = None this.system_address = None - this.station = None + this.station_name = None this.station_marketid = None # Frontier MarketID # station label in main window this.station_link = parent.nametowidget(f".{appname.lower()}.station") @@ -154,7 +154,7 @@ def prefs_changed(cmdr: str, is_beta: bool) -> None: pass -def journal_entry( # noqa: CCR001 +def journal_entry( cmdr: str, is_beta: bool, system: str, station: str, entry: dict[str, Any], state: Mapping[str, Any] @@ -187,22 +187,16 @@ def journal_entry( # noqa: CCR001 this.system_address = state['SystemAddress'] this.system_name = state['SystemName'] this.system_population = state['SystemPopulation'] - - this.station = entry.get('StationName') or this.station - # on_foot station detection - if entry['event'] == 'Location' and entry['BodyType'] == 'Station': - this.station = entry['Body'] + this.station_name = state['StationName'] this.station_marketid = entry.get('MarketID') or this.station_marketid # We might pick up StationName in DockingRequested, make sure we clear it if leaving if entry['event'] in ('Undocked', 'FSDJump', 'SupercruiseEntry'): - this.station = None this.station_marketid = None if entry['event'] == 'Embark' and not entry.get('OnStation'): # If we're embarking OnStation to a Taxi/Dropship we'll also get an # Undocked event. - this.station = None this.station_marketid = None # Only actually change URLs if we are current provider. @@ -214,15 +208,13 @@ def journal_entry( # noqa: CCR001 # But only actually change the URL if we are current station provider. if config.get_str('station_provider') == 'eddb': - text = this.station - if not text: + if not this.station_name: if this.system_population is not None and this.system_population > 0: - text = this.STATION_UNDOCKED + this.station_link['text'] = this.STATION_UNDOCKED else: - text = '' + this.station_link['text'] = '' - this.station_link['text'] = text # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.station_link.update_idletasks() @@ -244,8 +236,8 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> str | None: if not this.system_name: this.system_name = data['lastSystem']['name'] - if not this.station and data['commander']['docked']: - this.station = data['lastStarport']['name'] + if not this.station_name and data['commander']['docked']: + this.station_name = data['lastStarport']['name'] # Override standard URL functions if config.get_str('system_provider') == 'eddb': @@ -255,8 +247,8 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> str | None: this.system_link.update_idletasks() if config.get_str('station_provider') == 'eddb': - if data['commander']['docked'] or this.on_foot and this.station: - this.station_link['text'] = this.station + if data['commander']['docked'] or this.on_foot and this.station_name: + this.station_link['text'] = this.station_name elif data['lastStarport']['name'] and data['lastStarport']['name'] != "": this.station_link['text'] = this.STATION_UNDOCKED diff --git a/plugins/eddn.py b/plugins/eddn.py index cd29d215..ab7d2fa3 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2449,7 +2449,7 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 ): this.cmdr_name = cmdr_name - if (data['commander'].get('docked') or (this.on_foot and monitor.station) + if (data['commander'].get('docked') or (this.on_foot and monitor.state['StationName']) and config.get_int('output') & config.OUT_EDDN_SEND_STATION_DATA): try: if this.marketId != data['lastStarport']['id']: From 2a8dd14e24aaec8c73d5cbb5f3ef12beaf59d868 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 16:28:26 +0000 Subject: [PATCH 22/30] tracking/stationname; Minor fixups * Missed a some `self.station` in monitor.py * Fixed EDDB system *and* station link setting. Brainfart had mixed them together in last commit. --- monitor.py | 4 ++-- plugins/eddb.py | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/monitor.py b/monitor.py index 19b57983..ab7ce21e 100644 --- a/monitor.py +++ b/monitor.py @@ -539,10 +539,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below entry['BodyID'] = self.state['BodyID'] entry['BodyType'] = self.state['BodyType'] - if self.station: + if self.state['StationName']: entry['Docked'] = True entry['MarketID'] = self.station_marketid - entry['StationName'] = self.station + entry['StationName'] = self.state['StationName'] entry['StationType'] = self.stationtype else: diff --git a/plugins/eddb.py b/plugins/eddb.py index dc6c7b63..d7a0f431 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -199,16 +199,17 @@ def journal_entry( # Undocked event. this.station_marketid = None - # Only actually change URLs if we are current provider. - if config.get_str('system_provider') == 'eddb': + # Only change URL text if we are current provider. + if config.get_str('station_provider') == 'eddb': this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() - # But only actually change the URL if we are current station provider. - if config.get_str('station_provider') == 'eddb': - if not this.station_name: + if this.station_name: + this.station_link['text'] = this.station_name + + else: if this.system_population is not None and this.system_population > 0: this.station_link['text'] = this.STATION_UNDOCKED From 31e8d0372d5dfc2a58b6cedf1c3b8c6e7cf9f343 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 16:55:04 +0000 Subject: [PATCH 23/30] monitor/tracking: Move .station_marketid to state['MarketID'] 1. plugins/eddb.py uses this for MarketID-based station URLs. * So do the 'rename'. * Remove EDDB tracking in favour of this. * Update PLUGINS.md --- EDMarketConnector.py | 4 +- PLUGINS.md | 113 ++++++++++++++++++++++--------------------- monitor.py | 25 +++++----- plugins/eddb.py | 11 +---- 4 files changed, 73 insertions(+), 80 deletions(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 57f56982..f413b05d 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -1295,9 +1295,9 @@ class AppWindow(object): self.capi_query_holdoff_time = capi_response.query_time + companion.capi_query_cooldown - elif capi_response.capi_data['lastStarport']['id'] != monitor.station_marketid: + elif capi_response.capi_data['lastStarport']['id'] != monitor.state['MarketID']: logger.warning(f"MarketID mis-match: {capi_response.capi_data['lastStarport']['id']!r} !=" - f" {monitor.station_marketid!r}") + f" {monitor.state['MarketID']!r}") raise companion.ServerLagging() elif not monitor.state['OnFoot'] and capi_response.capi_data['ship']['id'] != monitor.state['ShipID']: diff --git a/PLUGINS.md b/PLUGINS.md index 36beef9d..d8236650 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -606,61 +606,62 @@ This gets called when EDMarketConnector sees a new entry in the game's journal. Content of `state` (updated to the current journal entry): -| Field | Type | Description | -|:---------------------|:---------------------------:|:----------------------------------------------------------------------------------------------------------------| -| `GameLanguage` | `Optional[str]` | `language` value from `Fileheader` event. | -| `GameVersion` | `Optional[str]` | `version` value from `Fileheader` event. | -| `GameBuild` | `Optional[str]` | `build` value from `Fileheader` event. | -| `Captain`[3] | `Optional[str]` | Name of the commander who's crew you're on, if any | -| `Cargo` | `dict` | Current cargo. Note that this will be totals, and any mission specific duplicates will be counted together | -| `CargoJSON` | `dict` | content of cargo.json as of last read. | -| `Credits` | `int` | Current credits balance | -| `FID` | `str` | Frontier commander ID | -| `Horizons` | `bool` | From `LoadGame` event. | -| `Odyssey` | `bool` | From `LoadGame` event. `False` if not present, else the event value. | -| `Loan` | `Optional[int]` | Current loan amount, if any | -| `Raw` | `dict` | Current raw engineering materials | -| `Manufactured` | `dict` | Current manufactured engineering materials | -| `Encoded` | `dict` | Current encoded engineering materials | -| `Component` | `dict` | Current component materials | -| `Engineers` | `dict` | Current Raw engineering materials | -| `Rank` | `Dict[str, Tuple[int, int]` | Current ranks, each entry is a tuple of the current rank, and age | -| `Statistics` | `dict` | Contents of a Journal Statistics event, ie, data shown in the stats panel. See the Journal manual for more info | -| `Role` | `Optional[str]` | Current role if in multi-crew, one of `Idle`, `FireCon`, `FighterCon` | -| `Friends` | `set` | Currently online friend | -| `ShipID` | `int` | Frontier ID of current ship | -| `ShipIdent` | `str` | Current user-set ship ID | -| `ShipName` | `str` | Current user-set ship name | -| `ShipType` | `str` | Internal name for the current ship type | -| `HullValue` | `int` | Current ship value, excluding modules | -| `ModulesValue` | `int` | Value of the current ship's modules | -| `Rebuy` | `int` | Current ship's rebuy cost | -| `Modules` | `dict` | Currently fitted modules | -| `NavRoute` | `dict` | Last plotted multi-hop route[1] | -| `ModuleInfo` | `dict` | Last loaded ModulesInfo.json data | -| `IsDocked` | `bool` | Whether the Cmdr is currently docked *in their own ship*. | -| `OnFoot`[3] | `bool` | Whether the Cmdr is on foot | -| `Component` | `dict` | 'Component' MicroResources in Odyssey, `int` count each. | -| `Item` | `dict` | 'Item' MicroResources in Odyssey, `int` count each. | -| `Consumable` | `dict` | 'Consumable' MicroResources in Odyssey, `int` count each. | -| `Data` | `dict` | 'Data' MicroResources in Odyssey, `int` count each. | -| `BackPack` | `dict` | `dict` of Odyssey MicroResources in backpack. | -| `BackpackJSON` | `dict` | Content of Backpack.json as of last read. | -| `ShipLockerJSON` | `dict` | Content of ShipLocker.json as of last read. | -| `SuitCurrent` | `dict` | CAPI-returned data of currently worn suit. NB: May be `None` if no data. | -| `Suits` | `dict`[2] | CAPI-returned data of owned suits. NB: May be `None` if no data. | -| `SuitLoadoutCurrent` | `dict` | CAPI-returned data of current Suit Loadout. NB: May be `None` if no data. | -| `SuitLoadouts` | `dict`[2] | CAPI-returned data of all Suit Loadouts. NB: May be `None` if no data. | -| `Taxi` | `Optional[bool]` | Whether or not we're currently in a taxi. NB: This is best effort with what the journals provide. | -| `Dropship` | `Optional[bool]` | Whether or not the above taxi is a Dropship | -| `SystemAddress`[3] | `Optional[int]` | Unique [ID64](http://disc.thargoid.space/ID64) of the star system we're currently in | -| `SystemName`[3] | `Optional[str]` | Name of the star system we're currently in | -| `SystemPopulation`[3]| `Optional[int]` | Population of the star system we're currently in | -| `StarPos`[3] | `Optional[tuple[float]]` | Galaxy co-ordinates of the system we're currently in | -| `Body`[3][4] | `Optional[str]` | Name of the body we're currently on / in the SOI of | -| `BodyID`[3][4] | `Optional[int]` | ID of the body we're currently on / in the SOI of | -| `BodyType`[3][4] | `Optional[str]` | The type of body that `Body` refers to | -| `StationName` | `Optional[str]` | Name of the station we're docked at, if applicable | +| Field | Type | Description | +|:----------------------|:---------------------------:|:----------------------------------------------------------------------------------------------------------------| +| `GameLanguage` | `Optional[str]` | `language` value from `Fileheader` event. | +| `GameVersion` | `Optional[str]` | `version` value from `Fileheader` event. | +| `GameBuild` | `Optional[str]` | `build` value from `Fileheader` event. | +| `Captain`[3] | `Optional[str]` | Name of the commander who's crew you're on, if any | +| `Cargo` | `dict` | Current cargo. Note that this will be totals, and any mission specific duplicates will be counted together | +| `CargoJSON` | `dict` | content of cargo.json as of last read. | +| `Credits` | `int` | Current credits balance | +| `FID` | `str` | Frontier commander ID | +| `Horizons` | `bool` | From `LoadGame` event. | +| `Odyssey` | `bool` | From `LoadGame` event. `False` if not present, else the event value. | +| `Loan` | `Optional[int]` | Current loan amount, if any | +| `Raw` | `dict` | Current raw engineering materials | +| `Manufactured` | `dict` | Current manufactured engineering materials | +| `Encoded` | `dict` | Current encoded engineering materials | +| `Component` | `dict` | Current component materials | +| `Engineers` | `dict` | Current Raw engineering materials | +| `Rank` | `Dict[str, Tuple[int, int]` | Current ranks, each entry is a tuple of the current rank, and age | +| `Statistics` | `dict` | Contents of a Journal Statistics event, ie, data shown in the stats panel. See the Journal manual for more info | +| `Role` | `Optional[str]` | Current role if in multi-crew, one of `Idle`, `FireCon`, `FighterCon` | +| `Friends` | `set` | Currently online friend | +| `ShipID` | `int` | Frontier ID of current ship | +| `ShipIdent` | `str` | Current user-set ship ID | +| `ShipName` | `str` | Current user-set ship name | +| `ShipType` | `str` | Internal name for the current ship type | +| `HullValue` | `int` | Current ship value, excluding modules | +| `ModulesValue` | `int` | Value of the current ship's modules | +| `Rebuy` | `int` | Current ship's rebuy cost | +| `Modules` | `dict` | Currently fitted modules | +| `NavRoute` | `dict` | Last plotted multi-hop route[1] | +| `ModuleInfo` | `dict` | Last loaded ModulesInfo.json data | +| `IsDocked` | `bool` | Whether the Cmdr is currently docked *in their own ship*. | +| `OnFoot`[3] | `bool` | Whether the Cmdr is on foot | +| `Component` | `dict` | 'Component' MicroResources in Odyssey, `int` count each. | +| `Item` | `dict` | 'Item' MicroResources in Odyssey, `int` count each. | +| `Consumable` | `dict` | 'Consumable' MicroResources in Odyssey, `int` count each. | +| `Data` | `dict` | 'Data' MicroResources in Odyssey, `int` count each. | +| `BackPack` | `dict` | `dict` of Odyssey MicroResources in backpack. | +| `BackpackJSON` | `dict` | Content of Backpack.json as of last read. | +| `ShipLockerJSON` | `dict` | Content of ShipLocker.json as of last read. | +| `SuitCurrent` | `dict` | CAPI-returned data of currently worn suit. NB: May be `None` if no data. | +| `Suits` | `dict`[2] | CAPI-returned data of owned suits. NB: May be `None` if no data. | +| `SuitLoadoutCurrent` | `dict` | CAPI-returned data of current Suit Loadout. NB: May be `None` if no data. | +| `SuitLoadouts` | `dict`[2] | CAPI-returned data of all Suit Loadouts. NB: May be `None` if no data. | +| `Taxi` | `Optional[bool]` | Whether or not we're currently in a taxi. NB: This is best effort with what the journals provide. | +| `Dropship` | `Optional[bool]` | Whether or not the above taxi is a Dropship | +| `SystemAddress`[3] | `Optional[int]` | Unique [ID64](http://disc.thargoid.space/ID64) of the star system we're currently in | +| `SystemName`[3] | `Optional[str]` | Name of the star system we're currently in | +| `SystemPopulation`[3] | `Optional[int]` | Population of the star system we're currently in | +| `StarPos`[3] | `Optional[tuple[float]]` | Galaxy co-ordinates of the system we're currently in | +| `Body`[3][4] | `Optional[str]` | Name of the body we're currently on / in the SOI of | +| `BodyID`[3][4] | `Optional[int]` | ID of the body we're currently on / in the SOI of | +| `BodyType`[3][4] | `Optional[str]` | The type of body that `Body` refers to | +| `StationName`[3] | `Optional[str]` | Name of the station we're docked at, if applicable | +| `MarketID`[3] | `Optional[str]` | MarketID of the station we're docked at, if applicable | [1] - Contents of `NavRoute` not changed if a `NavRouteClear` event is seen, but plugins will see the `NavRouteClear` event. @@ -807,7 +808,7 @@ now track in the same manner as prior core EDDN plugin code. Check the documentation above for some caveats. Do not just blindly use this data, or the 'Body' name value. -`StationName` added to the `state` dictionary. +`StationName` and `MarketID` added to the `state` dictionary. ___ diff --git a/monitor.py b/monitor.py index ab7ce21e..d225c98c 100644 --- a/monitor.py +++ b/monitor.py @@ -116,7 +116,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.station_marketid: int | None = None self.stationtype: str | None = None self.started: int | None = None # Timestamp of the LoadGame event @@ -311,7 +310,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None self.state['BodyType'] = None self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None self.is_beta = False @@ -541,7 +540,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if self.state['StationName']: entry['Docked'] = True - entry['MarketID'] = self.station_marketid + entry['MarketID'] = self.state['MarketID'] entry['StationName'] = self.state['StationName'] entry['StationType'] = self.stationtype @@ -586,7 +585,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['Body'] = None self.state['BodyID'] = None self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None self.started = None @@ -625,7 +624,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None self.state['BodyType'] = None self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None self.started = timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')) @@ -758,7 +757,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'undocked': self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None self.state['IsDocked'] = False @@ -780,8 +779,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # • StationType # • MarketID self.state['StationName'] = None + self.state['MarketID'] = None if entry.get('OnStation'): self.state['StationName'] = entry.get('StationName', '') + self.state['MarketID'] = entry.get('MarketID', '') self.state['OnFoot'] = False self.state['Taxi'] = entry['Taxi'] @@ -845,7 +846,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below ############################################################### self.state['IsDocked'] = True self.state['StationName'] = entry.get('StationName') # It may be None - self.station_marketid = entry.get('MarketID') # It may be None + self.state['MarketID'] = entry.get('MarketID') # It may be None self.stationtype = entry.get('StationType') # It may be None self.stationservices = entry.get('StationServices') # None under E:D < 2.4 @@ -957,7 +958,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below ############################################################### if event_type == 'fsdjump': self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None @@ -969,7 +970,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if entry.get('BodyType') and entry['BodyType'] == 'Station': self.state['StationName'] = entry.get('Body') - self.station_marketid = entry.get('MarketID') # May be None + self.state['MarketID'] = entry.get('MarketID') # May be None self.stationtype = entry.get('StationType') # May be None self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location' ############################################################### @@ -1008,7 +1009,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below # Track: Current station, if applicable ############################################################### self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None ############################################################### @@ -1713,7 +1714,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None self.state['BodyType'] = None self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None self.state['OnFoot'] = False @@ -1732,7 +1733,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None self.state['BodyType'] = None self.state['StationName'] = None - self.station_marketid = None + self.state['MarketID'] = None self.stationtype = None self.stationservices = None diff --git a/plugins/eddb.py b/plugins/eddb.py index d7a0f431..5638ddb4 100644 --- a/plugins/eddb.py +++ b/plugins/eddb.py @@ -188,16 +188,7 @@ def journal_entry( this.system_name = state['SystemName'] this.system_population = state['SystemPopulation'] this.station_name = state['StationName'] - - this.station_marketid = entry.get('MarketID') or this.station_marketid - # We might pick up StationName in DockingRequested, make sure we clear it if leaving - if entry['event'] in ('Undocked', 'FSDJump', 'SupercruiseEntry'): - this.station_marketid = None - - if entry['event'] == 'Embark' and not entry.get('OnStation'): - # If we're embarking OnStation to a Taxi/Dropship we'll also get an - # Undocked event. - this.station_marketid = None + this.station_marketid = state['MarketID'] # Only change URL text if we are current provider. if config.get_str('station_provider') == 'eddb': From ef1642181ad8254fc70c5fb69b455e712103f3db Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 17:00:31 +0000 Subject: [PATCH 24/30] monitor/tracking: Move .stationtype to state['StationType'] * Nothing outside of monitor.py uses this, but it's of the same nature as StationName and MarketID, so do this for consistency. For now we'll leave monitor.stationservices as-is. --- PLUGINS.md | 3 ++- monitor.py | 23 +++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index d8236650..5cabd8b6 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -662,6 +662,7 @@ Content of `state` (updated to the current journal entry): | `BodyType`[3][4] | `Optional[str]` | The type of body that `Body` refers to | | `StationName`[3] | `Optional[str]` | Name of the station we're docked at, if applicable | | `MarketID`[3] | `Optional[str]` | MarketID of the station we're docked at, if applicable | +| `StationType`[3] | `Optional[str]` | Type of the station we're docked at, if applicable | [1] - Contents of `NavRoute` not changed if a `NavRouteClear` event is seen, but plugins will see the `NavRouteClear` event. @@ -808,7 +809,7 @@ now track in the same manner as prior core EDDN plugin code. Check the documentation above for some caveats. Do not just blindly use this data, or the 'Body' name value. -`StationName` and `MarketID` added to the `state` dictionary. +`StationName`, `MarketID`, and `StationType` added to the `state` dictionary. ___ diff --git a/monitor.py b/monitor.py index d225c98c..c65aef5c 100644 --- a/monitor.py +++ b/monitor.py @@ -116,7 +116,6 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.mode: str | None = None self.group: str | None = None self.cmdr: str | None = None - self.stationtype: str | None = None self.started: int | None = None # Timestamp of the LoadGame event self._navroute_retries_remaining = 0 @@ -311,7 +310,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyType'] = None self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None self.is_beta = False self.state['OnFoot'] = False @@ -542,7 +541,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below entry['Docked'] = True entry['MarketID'] = self.state['MarketID'] entry['StationName'] = self.state['StationName'] - entry['StationType'] = self.stationtype + entry['StationType'] = self.state['StationType'] else: entry['Docked'] = False @@ -586,7 +585,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyID'] = None self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None self.started = None self.__init_state() @@ -625,7 +624,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyType'] = None self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None self.started = timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')) # Don't set Ship, ShipID etc since this will reflect Fighter or SRV if starting in those @@ -758,7 +757,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below elif event_type == 'undocked': self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None self.state['IsDocked'] = False @@ -847,7 +846,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['IsDocked'] = True self.state['StationName'] = entry.get('StationName') # It may be None self.state['MarketID'] = entry.get('MarketID') # It may be None - self.stationtype = entry.get('StationType') # It may be None + self.state['StationType'] = entry.get('StationType') # It may be None self.stationservices = entry.get('StationServices') # None under E:D < 2.4 # No need to set self.state['Taxi'] or Dropship here, if it's @@ -959,7 +958,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below if event_type == 'fsdjump': self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None else: @@ -971,7 +970,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['StationName'] = entry.get('Body') self.state['MarketID'] = entry.get('MarketID') # May be None - self.stationtype = entry.get('StationType') # May be None + self.state['StationType'] = entry.get('StationType') # May be None self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location' ############################################################### @@ -1010,7 +1009,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below ############################################################### self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None ############################################################### @@ -1715,7 +1714,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyType'] = None self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None self.state['OnFoot'] = False @@ -1734,7 +1733,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyType'] = None self.state['StationName'] = None self.state['MarketID'] = None - self.stationtype = None + self.state['StationType'] = None self.stationservices = None # TODO: on_foot: Will we get an event after this to know ? From c396a253f8dc4ae8b5688a9bfefacbf7f14ca3f1 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 17:07:47 +0000 Subject: [PATCH 25/30] plugins/edsm: Use state[...] values for system/station * Also renamed system -> system_name and station -> station_name --- plugins/edsm.py | 61 +++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/plugins/edsm.py b/plugins/edsm.py index 8975ff13..d68a3491 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -94,11 +94,11 @@ class This: self.newgame_docked: bool = False # starting up while docked self.navbeaconscan: int = 0 # batch up burst of Scan events after NavBeaconScan self.system_link: tk.Widget | None = None - self.system: tk.Tk | None = None + self.system_name: tk.Tk | None = None self.system_address: int | None = None # Frontier SystemAddress self.system_population: int | None = None self.station_link: tk.Widget | None = None - self.station: str | None = None + self.station_name: str | None = None self.station_marketid: int | None = None # Frontier MarketID self.on_foot = False @@ -186,9 +186,9 @@ def station_url(system_name: str, station_name: str) -> str: ) # monitor state might think these are gone, but we don't yet - if this.system and this.station: + if this.system_name and this.station_name: return requests.utils.requote_uri( - f'https://www.edsm.net/en/system?systemName={this.system}&stationName={this.station}' + f'https://www.edsm.net/en/system?systemName={this.system_name}&stationName={this.station_name}' ) if system_name: @@ -525,6 +525,11 @@ def journal_entry( # noqa: C901, CCR001 this.game_version = state['GameVersion'] this.game_build = state['GameBuild'] + this.system_address = state['SystemAddress'] + this.system_name = state['SystemName'] + this.system_population = state['SystemPopulation'] + this.station_name = state['StationName'] + this.station_marketid = state['MarketID'] entry = new_entry @@ -538,38 +543,10 @@ Station: {station} state: {state!r} entry: {entry!r}''' ) - # Always update our system address even if we're not currently the provider for system or station, but dont update - # on events that contain "future" data, such as FSDTarget - if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): - this.system_address = entry.get('SystemAddress', this.system_address) - this.system = entry.get('StarSystem', this.system) - - # We need pop == 0 to set the value so as to clear 'x' in systems with - # no stations. - pop = entry.get('Population') - if pop is not None: - this.system_population = pop - - this.station = entry.get('StationName', this.station) - # on_foot station detection - if entry['event'] == 'Location' and entry['BodyType'] == 'Station': - this.station = entry['Body'] - - this.station_marketid = entry.get('MarketID', this.station_marketid) - # We might pick up StationName in DockingRequested, make sure we clear it if leaving - if entry['event'] in ('Undocked', 'FSDJump', 'SupercruiseEntry'): - this.station = None - this.station_marketid = None - - if entry['event'] == 'Embark' and not entry.get('OnStation'): - # If we're embarking OnStation to a Taxi/Dropship we'll also get an - # Undocked event. - this.station = None - this.station_marketid = None if config.get_str('station_provider') == 'EDSM': - to_set = this.station - if not this.station: + to_set = this.station_name + if not this.station_name: if this.system_population and this.system_population > 0: to_set = STATION_UNDOCKED @@ -578,7 +555,7 @@ entry: {entry!r}''' if this.station_link: this.station_link['text'] = to_set - this.station_link['url'] = station_url(str(this.system), str(this.station)) + this.station_link['url'] = station_url(str(this.system_name), str(this.station_name)) this.station_link.update_idletasks() # Update display of 'EDSM Status' image @@ -685,25 +662,25 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 this.station_marketid = data['lastStarport']['id'] # Only trust CAPI if these aren't yet set - if not this.system: - this.system = data['lastSystem']['name'] + if not this.system_name: + this.system_name = data['lastSystem']['name'] - if not this.station and data['commander']['docked']: - this.station = data['lastStarport']['name'] + if not this.station_name and data['commander']['docked']: + this.station_name = data['lastStarport']['name'] # TODO: Fire off the EDSM API call to trigger the callback for the icons if config.get_str('system_provider') == 'EDSM': if this.system_link: - this.system_link['text'] = this.system + this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() if config.get_str('station_provider') == 'EDSM': if this.station_link: - if data['commander']['docked'] or this.on_foot and this.station: - this.station_link['text'] = this.station + if data['commander']['docked'] or this.on_foot and this.station_name: + this.station_link['text'] = this.station_name elif data['lastStarport']['name'] and data['lastStarport']['name'] != "": this.station_link['text'] = STATION_UNDOCKED From 7b62fa1125c2e43012508f3634c7cea439c394f6 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 9 Jan 2023 17:19:49 +0000 Subject: [PATCH 26/30] plugins/inara: Use state[...] values for system/station * Also renamed system -> system_name & station -> station_name --- plugins/inara.py | 97 +++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/plugins/inara.py b/plugins/inara.py index ff87c881..326b963b 100644 --- a/plugins/inara.py +++ b/plugins/inara.py @@ -119,7 +119,7 @@ class This: # Main window clicks self.system_link: tk.Widget = None # type: ignore - self.system: Optional[str] = None # type: ignore + self.system_name: Optional[str] = None # type: ignore self.system_address: Optional[str] = None # type: ignore self.system_population: Optional[int] = None self.station_link: tk.Widget = None # type: ignore @@ -169,10 +169,12 @@ if DEBUG: def system_url(system_name: str) -> str: """Get a URL for the current system.""" if this.system_address: - return requests.utils.requote_uri(f'https://inara.cz/galaxy-starsystem/?search={this.system_address}') + return requests.utils.requote_uri(f'https://inara.cz/galaxy-starsystem/' + f'?search={this.system_address}') elif system_name: - return requests.utils.requote_uri(f'https://inara.cz/galaxy-starsystem/?search={system_name}') + return requests.utils.requote_uri(f'https://inara.cz/galaxy-starsystem/' + f'?search={system_name}') return '' @@ -188,11 +190,13 @@ def station_url(system_name: str, station_name: str) -> str: :return: A URL to inara for the given system and station """ if system_name and station_name: - return requests.utils.requote_uri(f'https://inara.cz/galaxy-station/?search={system_name}%20[{station_name}]') + return requests.utils.requote_uri(f'https://inara.cz/galaxy-station/' + f'?search={system_name}%20[{station_name}]') # monitor state might think these are gone, but we don't yet - if this.system and this.station: - return requests.utils.requote_uri(f'https://inara.cz/galaxy-station/?search={this.system}%20[{this.station}]') + if this.system_name and this.station: + return requests.utils.requote_uri(f'https://inara.cz/galaxy-station/' + f'?search={this.system_name}%20[{this.station}]') if system_name: return system_url(system_name) @@ -371,6 +375,31 @@ def journal_entry( # noqa: C901, CCR001 :return: str - empty if no error, else error string. """ + # This overall killswitch check is first in case, e.g. an EDMC bug is + # causing users to spam Inara with 'URL provider' queries, and we want to + # stop that. + should_return: bool + new_entry: Dict[str, Any] = {} + + should_return, new_entry = killswitch.check_killswitch('plugins.inara.journal', entry, logger) + if should_return: + plug.show_error(_('Inara disabled. See Log.')) # LANG: INARA support disabled via killswitch + logger.trace('returning due to killswitch match') + return '' + + # But then we update all the tracking copies before any other checks, + # because they're relevant for URL providing even if *sending* isn't + # appropriate. + this.on_foot = state['OnFoot'] + event_name: str = entry['event'] + this.cmdr = cmdr + this.FID = state['FID'] + this.multicrew = bool(state['Role']) + this.system_name = state['SystemName'] + this.system_address = state['SystemAddress'] + this.station = state['StationName'] + this.station_marketid = state['MarketID'] + if not monitor.is_live_galaxy(): # Since Update 14 on 2022-11-29 Inara only accepts Live data. if ( @@ -387,15 +416,6 @@ def journal_entry( # noqa: C901, CCR001 return '' - should_return: bool - new_entry: Dict[str, Any] = {} - - should_return, new_entry = killswitch.check_killswitch('plugins.inara.journal', entry, logger) - if should_return: - plug.show_error(_('Inara disabled. See Log.')) # LANG: INARA support disabled via killswitch - logger.trace('returning due to killswitch match') - return '' - should_return, new_entry = killswitch.check_killswitch( f'plugins.inara.journal.event.{entry["event"]}', new_entry, logger ) @@ -405,12 +425,6 @@ def journal_entry( # noqa: C901, CCR001 return '' entry = new_entry - this.on_foot = state['OnFoot'] - event_name: str = entry['event'] - this.cmdr = cmdr - this.FID = state['FID'] - this.multicrew = bool(state['Role']) - if event_name == 'LoadGame' or this.newuser: # clear cached state if event_name == 'LoadGame': @@ -431,10 +445,6 @@ def journal_entry( # noqa: C901, CCR001 this.loadout = None this.fleet = None this.shipswap = False - this.system = None - this.system_address = None - this.station = None - this.station_marketid = None elif event_name in ('Resurrect', 'ShipyardBuy', 'ShipyardSell', 'SellShipOnRebuy'): # Events that mean a significant change in credits, so we should send credits after next "Update" @@ -443,35 +453,6 @@ def journal_entry( # noqa: C901, CCR001 elif event_name in ('ShipyardNew', 'ShipyardSwap') or (event_name == 'Location' and entry['Docked']): this.suppress_docked = True - # Always update our system address even if we're not currently the provider for system or station, but dont update - # on events that contain "future" data, such as FSDTarget - if entry['event'] in ('Location', 'Docked', 'CarrierJump', 'FSDJump'): - this.system_address = entry.get('SystemAddress') or this.system_address - this.system = entry.get('StarSystem') or this.system - - # We need pop == 0 to set the value so as to clear 'x' in systems with - # no stations. - pop: Optional[int] = entry.get('Population') - if pop is not None: - this.system_population = pop - - this.station = entry.get('StationName', this.station) - # on_foot station detection - if entry['event'] == 'Location' and entry['BodyType'] == 'Station': - this.station = entry['Body'] - - this.station_marketid = entry.get('MarketID', this.station_marketid) or this.station_marketid - # We might pick up StationName in DockingRequested, make sure we clear it if leaving - if event_name in ('Undocked', 'FSDJump', 'SupercruiseEntry'): - this.station = None - this.station_marketid = None - - if entry['event'] == 'Embark' and not entry.get('OnStation'): - # If we're embarking OnStation to a Taxi/Dropship we'll also get an - # Undocked event. - this.station = None - this.station_marketid = None - if config.get_int('inara_out') and not is_beta and not this.multicrew and credentials(cmdr): current_credentials = Credentials(this.cmdr, this.FID, str(credentials(this.cmdr))) try: @@ -1158,7 +1139,7 @@ def journal_entry( # noqa: C901, CCR001 to_send_data: Optional[Dict[str, Any]] = {} # This is a glorified sentinel until lower down. # On Horizons, neither of these exist on TouchDown - star_system_name = entry.get('StarSystem', this.system) + star_system_name = entry.get('StarSystem', this.system_name) body_name = entry.get('Body', state['Body'] if state['BodyType'] == 'Planet' else None) if star_system_name is None: @@ -1377,7 +1358,7 @@ def journal_entry( # noqa: C901, CCR001 # Only actually change URLs if we are current provider. if config.get_str('system_provider') == 'Inara': - this.system_link['text'] = this.system + this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() @@ -1407,14 +1388,14 @@ def cmdr_data(data: CAPIData, is_beta): # noqa: CCR001 this.station_marketid = data['commander']['docked'] and data['lastStarport']['id'] # Only trust CAPI if these aren't yet set - this.system = this.system if this.system else data['lastSystem']['name'] + this.system_name = this.system_name if this.system_name else data['lastSystem']['name'] if not this.station and data['commander']['docked']: this.station = data['lastStarport']['name'] # Override standard URL functions if config.get_str('system_provider') == 'Inara': - this.system_link['text'] = this.system + this.system_link['text'] = this.system_name # Do *NOT* set 'url' here, as it's set to a function that will call # through correctly. We don't want a static string. this.system_link.update_idletasks() From b5bb9657d87f475cba16f51c5da0c9526d31230f Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 15 Jan 2023 21:54:02 +0000 Subject: [PATCH 27/30] eddn: Move `tracking_ui_update()` nearer top of `journal_entry()` With the tracking now being in monitor.py this needs to be ASAP after the local copies of the tracking have been updated. Below the possible `this.status_body_name` blanking, in case that's hit. --- plugins/eddn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index ab7d2fa3..ace4f27f 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -2224,6 +2224,8 @@ def journal_entry( # noqa: C901, CCR001 if entry['MusicTrack'] == 'MainMenu': this.status_body_name = None + tracking_ui_update() + # Events with their own EDDN schema if config.get_int('output') & config.OUT_EDDN_SEND_NON_STATION and not state['Captain']: @@ -2409,8 +2411,6 @@ def journal_entry( # noqa: C901, CCR001 logger.debug(f'Failed exporting {entry["event"]}', exc_info=e) return str(e) - tracking_ui_update() - return None From 46fd129d3e6a0677b36340c794a5883931573cf1 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 16 Jan 2023 18:10:57 +0000 Subject: [PATCH 28/30] eddn: Expand the tracking UI for all system, body & station location data * Also renamed This.systemaddress to this.system_address, which impacted misc. other lines of code. --- plugins/eddn.py | 115 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index ace4f27f..07209758 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -82,10 +82,14 @@ class This: self.odyssey = False # Track location to add to Journal events - self.systemaddress: Optional[str] = None + self.system_address: Optional[str] = None + self.system_name: Optional[str] = None self.coordinates: Optional[Tuple] = None self.body_name: Optional[str] = None self.body_id: Optional[int] = None + self.station_name: str | None = None + self.station_type: str | None = None + self.station_marketid: str | None = None # Track Status.json data self.status_body_name: Optional[str] = None @@ -117,9 +121,14 @@ class This: # Tracking UI self.ui: tk.Frame + self.ui_system_name: tk.Label + self.ui_system_address: tk.Label self.ui_j_body_name: tk.Label self.ui_j_body_id: tk.Label self.ui_s_body_name: tk.Label + self.ui_station_name: tk.Label + self.ui_station_type: tk.Label + self.ui_station_marketid: tk.Label this = This() @@ -1116,11 +1125,11 @@ class EDDN: entry['StarSystem'] = system_name if 'SystemAddress' not in entry: - if this.systemaddress is None: + if this.system_address is None: logger.warning("this.systemaddress is None, can't add SystemAddress") return "this.systemaddress is None, can't add SystemAddress" - entry['SystemAddress'] = this.systemaddress + entry['SystemAddress'] = this.system_address if 'StarPos' not in entry: # Prefer the passed-in version @@ -1159,7 +1168,7 @@ class EDDN: ####################################################################### # In this case should add StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1201,7 +1210,7 @@ class EDDN: ####################################################################### # In this case should add StarSystem and StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1263,7 +1272,7 @@ class EDDN: ####################################################################### # In this case should add StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1357,7 +1366,7 @@ class EDDN: ####################################################################### # In this case should add StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1652,7 +1661,7 @@ class EDDN: ####################################################################### # In this case should add SystemName and StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1702,7 +1711,7 @@ class EDDN: ####################################################################### # In this case should add StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1758,7 +1767,7 @@ class EDDN: ####################################################################### # In this case should add SystemName and StarPos, but only if the # SystemAddress of where we think we are matches. - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning("SystemAddress isn't current location! Can't add augmentations!") return 'Wrong System! Missed jump ?' @@ -1816,11 +1825,11 @@ class EDDN: else: # Horizons order, so use tracked data for cross-check - if this.systemaddress is None or system_name is None or system_starpos is None: - logger.error(f'Location tracking failure: {this.systemaddress=}, {system_name=}, {system_starpos=}') + if this.system_address is None or system_name is None or system_starpos is None: + logger.error(f'Location tracking failure: {this.system_address=}, {system_name=}, {system_starpos=}') return 'Current location not tracked properly, started after game?' - aug_systemaddress = this.systemaddress + aug_systemaddress = this.system_address aug_starsystem = system_name aug_starpos = system_starpos @@ -1964,23 +1973,69 @@ def plugin_app(parent: tk.Tk) -> Optional[tk.Frame]: this.ui = tk.Frame(parent) row = this.ui.grid_size()[1] + + ####################################################################### + # System + ####################################################################### + # SystemName + system_name_label = tk.Label(this.ui, text="S:Name:") + system_name_label.grid(row=row, column=0, sticky=tk.W) + this.ui_system_name = tk.Label(this.ui, name='eddn_track_system_name', anchor=tk.W) + this.ui_system_name.grid(row=row, column=1, sticky=tk.E) + row += 1 + # SystemAddress + system_address_label = tk.Label(this.ui, text="S:Address:") + system_address_label.grid(row=row, column=0, sticky=tk.W) + this.ui_system_address = tk.Label(this.ui, name='eddn_track_system_address', anchor=tk.W) + this.ui_system_address.grid(row=row, column=1, sticky=tk.E) + row += 1 + ####################################################################### + + ####################################################################### + # Body + ####################################################################### + # Body Name from Journal journal_body_name_label = tk.Label(this.ui, text="J:BodyName:") journal_body_name_label.grid(row=row, column=0, sticky=tk.W) this.ui_j_body_name = tk.Label(this.ui, name='eddn_track_j_body_name', anchor=tk.W) this.ui_j_body_name.grid(row=row, column=1, sticky=tk.E) row += 1 - + # Body ID from Journal journal_body_id_label = tk.Label(this.ui, text="J:BodyID:") journal_body_id_label.grid(row=row, column=0, sticky=tk.W) this.ui_j_body_id = tk.Label(this.ui, name='eddn_track_j_body_id', anchor=tk.W) this.ui_j_body_id.grid(row=row, column=1, sticky=tk.E) row += 1 - + # Body Name from Status.json status_body_name_label = tk.Label(this.ui, text="S:BodyName:") status_body_name_label.grid(row=row, column=0, sticky=tk.W) this.ui_s_body_name = tk.Label(this.ui, name='eddn_track_s_body_name', anchor=tk.W) this.ui_s_body_name.grid(row=row, column=1, sticky=tk.E) row += 1 + ####################################################################### + + ####################################################################### + # Station + ####################################################################### + # Name + status_station_name_label = tk.Label(this.ui, text="J:StationName:") + status_station_name_label.grid(row=row, column=0, sticky=tk.W) + this.ui_station_name = tk.Label(this.ui, name='eddn_track_station_name', anchor=tk.W) + this.ui_station_name.grid(row=row, column=1, sticky=tk.E) + row += 1 + # Type + status_station_type_label = tk.Label(this.ui, text="J:StationType:") + status_station_type_label.grid(row=row, column=0, sticky=tk.W) + this.ui_station_type = tk.Label(this.ui, name='eddn_track_station_type', anchor=tk.W) + this.ui_station_type.grid(row=row, column=1, sticky=tk.E) + row += 1 + # MarketID + status_station_marketid_label = tk.Label(this.ui, text="J:StationID:") + status_station_marketid_label.grid(row=row, column=0, sticky=tk.W) + this.ui_station_marketid = tk.Label(this.ui, name='eddn_track_station_id', anchor=tk.W) + this.ui_station_marketid.grid(row=row, column=1, sticky=tk.E) + row += 1 + ####################################################################### return this.ui @@ -1992,6 +2047,14 @@ def tracking_ui_update() -> None: if not config.eddn_tracking_ui: return + this.ui_system_name['text'] = '≪None≫' + if this.ui_system_name is not None: + this.ui_system_name['text'] = this.system_name + + this.ui_system_address['text'] = '≪None≫' + if this.ui_system_address is not None: + this.ui_system_address['text'] = this.system_address + this.ui_j_body_name['text'] = '≪None≫' if this.body_name is not None: this.ui_j_body_name['text'] = this.body_name @@ -2004,6 +2067,18 @@ def tracking_ui_update() -> None: if this.status_body_name is not None: this.ui_s_body_name['text'] = this.status_body_name + this.ui_station_name['text'] = '≪None≫' + if this.station_name is not None: + this.ui_station_name['text'] = this.station_name + + this.ui_station_type['text'] = '≪None≫' + if this.station_type is not None: + this.ui_station_type['text'] = this.station_type + + this.ui_station_marketid['text'] = '≪None≫' + if this.station_marketid is not None: + this.ui_station_marketid['text'] = this.station_marketid + this.ui.update_idletasks() @@ -2214,7 +2289,11 @@ def journal_entry( # noqa: C901, CCR001 this.body_name = state['Body'] this.body_id = state['BodyID'] this.coordinates = state['StarPos'] - this.systemaddress = state['SystemAddress'] + this.system_address = state['SystemAddress'] + this.system_name = state['SystemName'] + this.station_name = state['StationName'] + this.station_type = state['StationType'] + this.station_marketid = state['MarketID'] if event_name == 'docked': # Trigger a send/retry of pending EDDN messages @@ -2339,7 +2418,7 @@ def journal_entry( # noqa: C901, CCR001 # add mandatory StarSystem and StarPos properties to events if 'StarSystem' not in entry: - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning(f"event({entry['event']}) has no StarSystem, but SystemAddress isn't current location") return "Wrong System! Delayed Scan event?" @@ -2356,7 +2435,7 @@ def journal_entry( # noqa: C901, CCR001 # Gazelle[TD] reported seeing a lagged Scan event with incorrect # augmented StarPos: - if this.systemaddress is None or this.systemaddress != entry['SystemAddress']: + if this.system_address is None or this.system_address != entry['SystemAddress']: logger.warning(f"event({entry['event']}) has no StarPos, but SystemAddress isn't current location") return "Wrong System! Delayed Scan event?" From 2f2ee885c8a4fae17403ca2ee1cd65e25c1d2386 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 16 Jan 2023 19:30:02 +0000 Subject: [PATCH 29/30] monitor/tracking: *Do* clear supercruisentry/body state if Station type --- monitor.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/monitor.py b/monitor.py index c65aef5c..bd82fe8e 100644 --- a/monitor.py +++ b/monitor.py @@ -1000,9 +1000,13 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below self.state['BodyType'] = None elif event_type == 'supercruiseentry': - # NB: Do **NOT** clear Body state, because we won't get a fresh - # ApproachBody if we don't leave Orbital Cruise but land - # again. + # We only clear Body state if the Type is Station. This is + # because we won't get a fresh ApproachBody if we don't leave + # Orbital Cruise but land again. + if self.state['BodyType'] == 'Station': + self.state['Body'] = None + self.state['BodyID'] = None + self.state['BodyType'] = None ############################################################### # Track: Current station, if applicable From dbb471f2c281a1f1e49ae5fa0743d409362e8e52 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 16 Jan 2023 19:32:44 +0000 Subject: [PATCH 30/30] eddn/tracking: Add BodyType to tracking UI This helps demonstrate that a 'spurious' Station BodyName/ID is actually OK, because BodyType makes it clear. --- plugins/eddn.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 07209758..4577aba5 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -87,6 +87,7 @@ class This: self.coordinates: Optional[Tuple] = None self.body_name: Optional[str] = None self.body_id: Optional[int] = None + self.body_type: Optional[int] = None self.station_name: str | None = None self.station_type: str | None = None self.station_marketid: str | None = None @@ -125,6 +126,7 @@ class This: self.ui_system_address: tk.Label self.ui_j_body_name: tk.Label self.ui_j_body_id: tk.Label + self.ui_j_body_type: tk.Label self.ui_s_body_name: tk.Label self.ui_station_name: tk.Label self.ui_station_type: tk.Label @@ -1978,13 +1980,13 @@ def plugin_app(parent: tk.Tk) -> Optional[tk.Frame]: # System ####################################################################### # SystemName - system_name_label = tk.Label(this.ui, text="S:Name:") + system_name_label = tk.Label(this.ui, text="J:SystemName:") system_name_label.grid(row=row, column=0, sticky=tk.W) this.ui_system_name = tk.Label(this.ui, name='eddn_track_system_name', anchor=tk.W) this.ui_system_name.grid(row=row, column=1, sticky=tk.E) row += 1 # SystemAddress - system_address_label = tk.Label(this.ui, text="S:Address:") + system_address_label = tk.Label(this.ui, text="J:SystemAddress:") system_address_label.grid(row=row, column=0, sticky=tk.W) this.ui_system_address = tk.Label(this.ui, name='eddn_track_system_address', anchor=tk.W) this.ui_system_address.grid(row=row, column=1, sticky=tk.E) @@ -2006,6 +2008,12 @@ def plugin_app(parent: tk.Tk) -> Optional[tk.Frame]: this.ui_j_body_id = tk.Label(this.ui, name='eddn_track_j_body_id', anchor=tk.W) this.ui_j_body_id.grid(row=row, column=1, sticky=tk.E) row += 1 + # Body Type from Journal + journal_body_type_label = tk.Label(this.ui, text="J:BodyType:") + journal_body_type_label.grid(row=row, column=0, sticky=tk.W) + this.ui_j_body_type = tk.Label(this.ui, name='eddn_track_j_body_type', anchor=tk.W) + this.ui_j_body_type.grid(row=row, column=1, sticky=tk.E) + row += 1 # Body Name from Status.json status_body_name_label = tk.Label(this.ui, text="S:BodyName:") status_body_name_label.grid(row=row, column=0, sticky=tk.W) @@ -2063,6 +2071,10 @@ def tracking_ui_update() -> None: if this.body_id is not None: this.ui_j_body_id['text'] = str(this.body_id) + this.ui_j_body_type['text'] = '≪None≫' + if this.body_type is not None: + this.ui_j_body_type['text'] = str(this.body_type) + this.ui_s_body_name['text'] = '≪None≫' if this.status_body_name is not None: this.ui_s_body_name['text'] = this.status_body_name @@ -2288,6 +2300,7 @@ def journal_entry( # noqa: C901, CCR001 # outside of this function. this.body_name = state['Body'] this.body_id = state['BodyID'] + this.body_type = state['BodyType'] this.coordinates = state['StarPos'] this.system_address = state['SystemAddress'] this.system_name = state['SystemName']