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']: