From bd183efbd4dfa8365246952f04352403195102aa Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 15:41:15 +0100 Subject: [PATCH 01/14] EDDN: Just use `this.horizons` for CAPI data sending --- plugins/eddn.py | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 90f9d505..78932c45 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -442,14 +442,6 @@ Msg:\n{msg}''' """ modules, ships = self.safe_modules_and_ships(data) - # Horizons flag - will hit at least Int_PlanetApproachSuite other than at engineer bases ("Colony"), - # prison or rescue Megaships, or under Pirate Attack etc - horizons: bool = is_horizons( - data['lastStarport'].get('economies', {}), - modules, - ships - ) - to_search: Iterator[Mapping[str, Any]] = filter( lambda m: self.MODULE_RE.search(m['name']) and m.get('sku') in (None, HORIZ_SKU) and m['name'] != 'Int_PlanetApproachSuite', @@ -461,7 +453,7 @@ Msg:\n{msg}''' ) # Don't send empty modules list - schema won't allow it - if outfitting and this.outfitting != (horizons, outfitting): + if outfitting and this.outfitting != (this.horizons, outfitting): self.send(data['commander']['name'], { '$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -469,13 +461,13 @@ Msg:\n{msg}''' ('systemName', data['lastSystem']['name']), ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), - ('horizons', horizons), + ('horizons', this.horizons), ('modules', outfitting), ('odyssey', is_odyssey), ]), }) - this.outfitting = (horizons, outfitting) + this.outfitting = (this.horizons, outfitting) def export_shipyard(self, data: CAPIData, is_beta: bool, is_odyssey: bool) -> None: """ @@ -488,12 +480,6 @@ Msg:\n{msg}''' """ modules, ships = self.safe_modules_and_ships(data) - horizons: bool = is_horizons( - data['lastStarport'].get('economies', {}), - modules, - ships - ) - shipyard: List[Mapping[str, Any]] = sorted( itertools.chain( (ship['name'].lower() for ship in (ships['shipyard_list'] or {}).values()), @@ -501,7 +487,7 @@ Msg:\n{msg}''' ) ) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. - if shipyard and this.shipyard != (horizons, shipyard): + if shipyard and this.shipyard != (this.horizons, shipyard): self.send(data['commander']['name'], { '$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -509,13 +495,13 @@ Msg:\n{msg}''' ('systemName', data['lastSystem']['name']), ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), - ('horizons', horizons), + ('horizons', this.horizons), ('ships', shipyard), ('odyssey', is_odyssey), ]), }) - this.shipyard = (horizons, shipyard) + this.shipyard = (this.horizons, shipyard) def export_journal_commodities(self, cmdr: str, is_beta: bool, entry: Mapping[str, Any]) -> None: """ @@ -571,7 +557,6 @@ Msg:\n{msg}''' :param entry: The relevant journal entry """ modules: List[Mapping[str, Any]] = entry.get('Items', []) - horizons: bool = entry.get('Horizons', False) # outfitting = sorted([self.MODULE_RE.sub(lambda m: m.group(0).capitalize(), module['Name']) # for module in modules if module['Name'] != 'int_planetapproachsuite']) outfitting: List[str] = sorted( @@ -579,7 +564,7 @@ Msg:\n{msg}''' filter(lambda m: m['Name'] != 'int_planetapproachsuite', modules) ) # Don't send empty modules list - schema won't allow it - if outfitting and this.outfitting != (horizons, outfitting): + if outfitting and this.outfitting != (this.horizons, outfitting): self.send(cmdr, { '$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -587,13 +572,13 @@ Msg:\n{msg}''' ('systemName', entry['StarSystem']), ('stationName', entry['StationName']), ('marketId', entry['MarketID']), - ('horizons', horizons), + ('horizons', this.horizons), ('modules', outfitting), ('odyssey', entry['odyssey']) ]), }) - this.outfitting = (horizons, outfitting) + this.outfitting = (this.horizons, outfitting) def export_journal_shipyard(self, cmdr: str, is_beta: bool, entry: Mapping[str, Any]) -> None: """ @@ -606,10 +591,9 @@ Msg:\n{msg}''' :param entry: the relevant journal entry """ ships: List[Mapping[str, Any]] = entry.get('PriceList') or [] - horizons: bool = entry.get('Horizons', False) shipyard = sorted(ship['ShipType'] for ship in ships) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. - if shipyard and this.shipyard != (horizons, shipyard): + if shipyard and this.shipyard != (this.horizons, shipyard): self.send(cmdr, { '$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -617,13 +601,13 @@ Msg:\n{msg}''' ('systemName', entry['StarSystem']), ('stationName', entry['StationName']), ('marketId', entry['MarketID']), - ('horizons', horizons), + ('horizons', this.horizons), ('ships', shipyard), ('odyssey', entry['odyssey']) ]), }) - # this.shipyard = (horizons, shipyard) + # this.shipyard = (this.horizons, shipyard) def export_journal_entry(self, cmdr: str, entry: Mapping[str, Any], msg: Mapping[str, Any]) -> None: """ From 556ace5306bebbcf34c1a56a9023a822218a73f1 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 15:47:12 +0100 Subject: [PATCH 02/14] EDDN: Use `this.odyssey` rather than passing to functions --- plugins/eddn.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 78932c45..11d5100d 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -329,7 +329,7 @@ Msg:\n{msg}''' # LANG: EDDN returned some sort of HTTP error, one we didn't expect. {STATUS} contains a number return _('EDDN Error: Returned {STATUS} status code').format(status_code) - def export_commodities(self, data: Mapping[str, Any], is_beta: bool, is_odyssey: bool) -> None: # noqa: CCR001 + def export_commodities(self, data: Mapping[str, Any], is_beta: bool) -> None: # noqa: CCR001 """ Update EDDN with the commodities on the current (lastStarport) station. @@ -337,7 +337,6 @@ Msg:\n{msg}''' :param data: a dict containing the starport data :param is_beta: whether or not we're currently in beta mode - :param is_odyssey: whether the account shows as having Odyssey expansion. """ commodities: List[OrderedDictT[str, Any]] = [] for commodity in data['lastStarport'].get('commodities') or []: @@ -373,7 +372,7 @@ Msg:\n{msg}''' ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), ('commodities', commodities), - ('odyssey', is_odyssey), + ('odyssey', this.odyssey), ]) if 'economies' in data['lastStarport']: @@ -431,7 +430,7 @@ Msg:\n{msg}''' return modules, ships - def export_outfitting(self, data: CAPIData, is_beta: bool, is_odyssey: bool) -> None: + def export_outfitting(self, data: CAPIData, is_beta: bool) -> None: """ Update EDDN with the current (lastStarport) station's outfitting options, if any. @@ -463,13 +462,13 @@ Msg:\n{msg}''' ('marketId', data['lastStarport']['id']), ('horizons', this.horizons), ('modules', outfitting), - ('odyssey', is_odyssey), + ('odyssey', this.odyssey), ]), }) this.outfitting = (this.horizons, outfitting) - def export_shipyard(self, data: CAPIData, is_beta: bool, is_odyssey: bool) -> None: + def export_shipyard(self, data: CAPIData, is_beta: bool) -> None: """ Update EDDN with the current (lastStarport) station's outfitting options, if any. @@ -497,7 +496,7 @@ Msg:\n{msg}''' ('marketId', data['lastStarport']['id']), ('horizons', this.horizons), ('ships', shipyard), - ('odyssey', is_odyssey), + ('odyssey', this.odyssey), ]), }) @@ -1364,9 +1363,9 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 status['text'] = _('Sending data to EDDN...') # LANG: Status text shown while attempting to send data status.update_idletasks() - this.eddn.export_commodities(data, is_beta, this.odyssey) - this.eddn.export_outfitting(data, is_beta, this.odyssey) - this.eddn.export_shipyard(data, is_beta, this.odyssey) + this.eddn.export_commodities(data, is_beta) + this.eddn.export_outfitting(data, is_beta) + this.eddn.export_shipyard(data, is_beta) if not old_status: status['text'] = '' status.update_idletasks() From a32546b00163c6948f43a2478905b79a906efa73 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 16:14:35 +0100 Subject: [PATCH 03/14] EDDN: Set `horizons` on `commodity/3` messages as per schema --- plugins/eddn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/eddn.py b/plugins/eddn.py index 11d5100d..2ae0fac0 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -372,6 +372,7 @@ Msg:\n{msg}''' ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), ('commodities', commodities), + ('horizons', this.horizons), ('odyssey', this.odyssey), ]) From b3419ec548fff8a97a2c5284cc5198684ca06259 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 16:17:58 +0100 Subject: [PATCH 04/14] EDDN: Also set `commodity/3`->`horizons` for journal-sourced data --- plugins/eddn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 2ae0fac0..4f20aef0 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -540,7 +540,8 @@ Msg:\n{msg}''' ('stationName', entry['StationName']), ('marketId', entry['MarketID']), ('commodities', commodities), - ('odyssey', entry['odyssey']) + ('horizons', this.horizons), + ('odyssey', this.odyssey), ]), }) From 4fef4257bd00376f45e94a35db925c0fbb58b267 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 16:20:46 +0100 Subject: [PATCH 05/14] EDDN: use this.odyssey for Journal outfitting and shipyard For consistency with the horizons flag. They *are* placed *from* the `this` versions into `entry`, but we might as well go the direct route. They have to be set explicitly here as we process the `entry` to make a wholly new `message` rather than the `message` just being `entry` with some changes. --- plugins/eddn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 4f20aef0..8c5ed1d9 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -575,7 +575,7 @@ Msg:\n{msg}''' ('marketId', entry['MarketID']), ('horizons', this.horizons), ('modules', outfitting), - ('odyssey', entry['odyssey']) + ('odyssey', this.odyssey), ]), }) @@ -604,7 +604,7 @@ Msg:\n{msg}''' ('marketId', entry['MarketID']), ('horizons', this.horizons), ('ships', shipyard), - ('odyssey', entry['odyssey']) + ('odyssey', this.odyssey), ]), }) From 29b69745f3a8f2dc9e54d88f6dd889eb7c90fcd1 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 16:32:38 +0100 Subject: [PATCH 06/14] EDDN: document that some EDDN messages aren't retried --- plugins/eddn.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 8c5ed1d9..c2163509 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -335,6 +335,10 @@ Msg:\n{msg}''' Once the send is complete, this.commodities is updated with the new data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param data: a dict containing the starport data :param is_beta: whether or not we're currently in beta mode """ @@ -437,6 +441,10 @@ Msg:\n{msg}''' Once the send is complete, this.outfitting is updated with the given data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param data: dict containing the outfitting data :param is_beta: whether or not we're currently in beta mode """ @@ -475,6 +483,10 @@ Msg:\n{msg}''' Once the send is complete, this.shipyard is updated to the new data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param data: dict containing the shipyard data :param is_beta: whether or not we are in beta mode """ @@ -509,6 +521,10 @@ Msg:\n{msg}''' As a side effect, it also updates this.commodities with the data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param cmdr: The commander to send data under :param is_beta: whether or not we're in beta mode :param entry: the journal entry containing the commodities data @@ -553,6 +569,10 @@ Msg:\n{msg}''' As a side effect, it also updates this.outfitting with the data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param cmdr: The commander to send data under :param is_beta: Whether or not we're in beta mode :param entry: The relevant journal entry @@ -587,6 +607,10 @@ Msg:\n{msg}''' As a side effect, this.shipyard is updated with the data. + NB: This does *not* go through the replaylog, unlike most of the + Journal-sourced data. This kind of timely data is often rejected by + listeners if 'too old' anyway, so little point. + :param cmdr: the commander to send this update under :param is_beta: Whether or not we're in beta mode :param entry: the relevant journal entry @@ -614,7 +638,8 @@ Msg:\n{msg}''' """ Update EDDN with an event from the journal. - Additionally if additional lines are cached, it may send those as well. + Additionally if other lines have been saved for retry, it may send + those as well. :param cmdr: Commander name as passed in through `journal_entry()`. :param entry: The full journal event dictionary (due to checks in this function). From 98f215e6ade7cf14766467cd2cbd3466d86689b1 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sun, 17 Oct 2021 16:46:11 +0100 Subject: [PATCH 07/14] EDDN: Remove `horizons` flag from navroute messages As with `odyssey` this isn't currently in the not-yet-live schema. --- plugins/eddn.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index c2163509..07071a32 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -929,9 +929,14 @@ Msg:\n{msg}''' ####################################################################### # Elisions ####################################################################### - # WORKAROUND WIP EDDN schema | 2021-09-27: This will reject with the Odyssey flag present + # WORKAROUND WIP EDDN schema | 2021-10-17: This will reject with the Odyssey or Horizons flags present if 'odyssey' in entry: del entry['odyssey'] + + if 'horizons' in entry: + del entry['horizons'] + + # END WORKAROUND ####################################################################### ####################################################################### From e14819797158ddced315aa3456fc491d5a695763 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:08:32 +0100 Subject: [PATCH 08/14] Revert "EDDN: use this.odyssey for Journal outfitting and shipyard" This reverts commit 4fef4257bd00376f45e94a35db925c0fbb58b267. --- plugins/eddn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 07071a32..70657136 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -595,7 +595,7 @@ Msg:\n{msg}''' ('marketId', entry['MarketID']), ('horizons', this.horizons), ('modules', outfitting), - ('odyssey', this.odyssey), + ('odyssey', entry['odyssey']) ]), }) @@ -628,7 +628,7 @@ Msg:\n{msg}''' ('marketId', entry['MarketID']), ('horizons', this.horizons), ('ships', shipyard), - ('odyssey', this.odyssey), + ('odyssey', entry['odyssey']) ]), }) From 90aa2698cdb62c794b372b600c457288f8c1416b Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:09:55 +0100 Subject: [PATCH 09/14] Revert "EDDN: Just use `this.horizons` for CAPI data sending" This reverts commit bd183efbd4dfa8365246952f04352403195102aa. --- plugins/eddn.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 70657136..751e1085 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -450,6 +450,14 @@ Msg:\n{msg}''' """ modules, ships = self.safe_modules_and_ships(data) + # Horizons flag - will hit at least Int_PlanetApproachSuite other than at engineer bases ("Colony"), + # prison or rescue Megaships, or under Pirate Attack etc + horizons: bool = is_horizons( + data['lastStarport'].get('economies', {}), + modules, + ships + ) + to_search: Iterator[Mapping[str, Any]] = filter( lambda m: self.MODULE_RE.search(m['name']) and m.get('sku') in (None, HORIZ_SKU) and m['name'] != 'Int_PlanetApproachSuite', @@ -461,7 +469,7 @@ Msg:\n{msg}''' ) # Don't send empty modules list - schema won't allow it - if outfitting and this.outfitting != (this.horizons, outfitting): + if outfitting and this.outfitting != (horizons, outfitting): self.send(data['commander']['name'], { '$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -469,13 +477,13 @@ Msg:\n{msg}''' ('systemName', data['lastSystem']['name']), ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), - ('horizons', this.horizons), + ('horizons', horizons), ('modules', outfitting), ('odyssey', this.odyssey), ]), }) - this.outfitting = (this.horizons, outfitting) + this.outfitting = (horizons, outfitting) def export_shipyard(self, data: CAPIData, is_beta: bool) -> None: """ @@ -492,6 +500,12 @@ Msg:\n{msg}''' """ modules, ships = self.safe_modules_and_ships(data) + horizons: bool = is_horizons( + data['lastStarport'].get('economies', {}), + modules, + ships + ) + shipyard: List[Mapping[str, Any]] = sorted( itertools.chain( (ship['name'].lower() for ship in (ships['shipyard_list'] or {}).values()), @@ -499,7 +513,7 @@ Msg:\n{msg}''' ) ) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. - if shipyard and this.shipyard != (this.horizons, shipyard): + if shipyard and this.shipyard != (horizons, shipyard): self.send(data['commander']['name'], { '$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -507,13 +521,13 @@ Msg:\n{msg}''' ('systemName', data['lastSystem']['name']), ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), - ('horizons', this.horizons), + ('horizons', horizons), ('ships', shipyard), ('odyssey', this.odyssey), ]), }) - this.shipyard = (this.horizons, shipyard) + this.shipyard = (horizons, shipyard) def export_journal_commodities(self, cmdr: str, is_beta: bool, entry: Mapping[str, Any]) -> None: """ @@ -578,6 +592,7 @@ Msg:\n{msg}''' :param entry: The relevant journal entry """ modules: List[Mapping[str, Any]] = entry.get('Items', []) + horizons: bool = entry.get('Horizons', False) # outfitting = sorted([self.MODULE_RE.sub(lambda m: m.group(0).capitalize(), module['Name']) # for module in modules if module['Name'] != 'int_planetapproachsuite']) outfitting: List[str] = sorted( @@ -585,7 +600,7 @@ Msg:\n{msg}''' filter(lambda m: m['Name'] != 'int_planetapproachsuite', modules) ) # Don't send empty modules list - schema won't allow it - if outfitting and this.outfitting != (this.horizons, outfitting): + if outfitting and this.outfitting != (horizons, outfitting): self.send(cmdr, { '$schemaRef': f'https://eddn.edcd.io/schemas/outfitting/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -593,13 +608,13 @@ Msg:\n{msg}''' ('systemName', entry['StarSystem']), ('stationName', entry['StationName']), ('marketId', entry['MarketID']), - ('horizons', this.horizons), + ('horizons', horizons), ('modules', outfitting), ('odyssey', entry['odyssey']) ]), }) - this.outfitting = (this.horizons, outfitting) + this.outfitting = (horizons, outfitting) def export_journal_shipyard(self, cmdr: str, is_beta: bool, entry: Mapping[str, Any]) -> None: """ @@ -616,9 +631,10 @@ Msg:\n{msg}''' :param entry: the relevant journal entry """ ships: List[Mapping[str, Any]] = entry.get('PriceList') or [] + horizons: bool = entry.get('Horizons', False) shipyard = sorted(ship['ShipType'] for ship in ships) # Don't send empty ships list - shipyard data is only guaranteed present if user has visited the shipyard. - if shipyard and this.shipyard != (this.horizons, shipyard): + if shipyard and this.shipyard != (horizons, shipyard): self.send(cmdr, { '$schemaRef': f'https://eddn.edcd.io/schemas/shipyard/2{"/test" if is_beta else ""}', 'message': OrderedDict([ @@ -626,13 +642,13 @@ Msg:\n{msg}''' ('systemName', entry['StarSystem']), ('stationName', entry['StationName']), ('marketId', entry['MarketID']), - ('horizons', this.horizons), + ('horizons', horizons), ('ships', shipyard), ('odyssey', entry['odyssey']) ]), }) - # this.shipyard = (this.horizons, shipyard) + # this.shipyard = (horizons, shipyard) def export_journal_entry(self, cmdr: str, entry: Mapping[str, Any], msg: Mapping[str, Any]) -> None: """ From d8689e5b9b1f81178706777d4faa354b310629b2 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:10:09 +0100 Subject: [PATCH 10/14] Revert "EDDN: If `this.horizons` is true, use that in `is_horizons()` check" This reverts commit ca80edd34d88298a2c9d933f79f0da8e68d870eb. --- plugins/eddn.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 751e1085..6768d023 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -1441,22 +1441,6 @@ def is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_STR_ANY :param ships: Ships available at the docked station. :return: bool - True if the Cmdr has Horizons access. """ - # First check the Journal-sourced flag - # NB: This assumes game currently running, rather than "old - # journal file". `LoadGame` determines monitor.cmdr, which determines - # the account used for CAPI, so it *should* match. - # - # For this to be wrong, the user would have had to have, e.g.: - # - # 1. Logged into Cmdr in Horizons/Odyssey, then back out again. - # 2. Logged into Cmdr in base game, either on another machine, or - # have removed the Journal file after. - # 3. Re-run EDMC and triggered a manual CAPI update. - # - # This seems unlikely. - if this.horizons: - return True - economies_colony = False modules_horizons = False ship_horizons = False From 694321064d439a983ba08087b0b78d7951943686 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:20:06 +0100 Subject: [PATCH 11/14] EDDN: Rename is_horizons() and document that it's for CAPI data only OK, it has `data` passed in, so this should be obvious, but let's make it explicit both by name and in the docstring. The docstring now also emphasies that *this* check **MUST** be used for CAPI data, as it's dependent only on the availability of Horizons on the account, and not on the `LoadGame` flags. --- plugins/eddn.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 6768d023..31ab721c 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -452,7 +452,7 @@ Msg:\n{msg}''' # Horizons flag - will hit at least Int_PlanetApproachSuite other than at engineer bases ("Colony"), # prison or rescue Megaships, or under Pirate Attack etc - horizons: bool = is_horizons( + horizons: bool = capi_is_horizons( data['lastStarport'].get('economies', {}), modules, ships @@ -500,7 +500,7 @@ Msg:\n{msg}''' """ modules, ships = self.safe_modules_and_ships(data) - horizons: bool = is_horizons( + horizons: bool = capi_is_horizons( data['lastStarport'].get('economies', {}), modules, ships @@ -1432,10 +1432,19 @@ def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]: # noqa: CCR001 MAP_STR_ANY = Mapping[str, Any] -def is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_STR_ANY) -> bool: +def capi_is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_STR_ANY) -> bool: """ Indicate if the supplied data indicates a player has Horizons access. + This is to be used **only** for CAPI-sourced data and **MUST** be used + for CAPI data!!! + + If the account has Horizons access then CAPI `/shipyard` will always see + the Horizons-only modules/ships. You can**NOT** use the Journal horizons + flag for this! If logged in to the base game on an account with Horizons, + which is all of them now, CAPI `/shipyard` will *still* return all of the + Horizons-only modules and ships. + :param economies: Economies of where the Cmdr is docked. :param modules: Modules available at the docked station. :param ships: Ships available at the docked station. From c97b539ac3a1e96bb3a7591aa02f8a484e51e88a Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:25:35 +0100 Subject: [PATCH 12/14] EDDN: Revert to using capi_is_horizons() in export_commodities() --- plugins/eddn.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 31ab721c..71a93112 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -342,6 +342,12 @@ Msg:\n{msg}''' :param data: a dict containing the starport data :param is_beta: whether or not we're currently in beta mode """ + modules, ships = self.safe_modules_and_ships(data) + horizons: bool = capi_is_horizons( + data['lastStarport'].get('economies', {}), + modules, + ships + ) commodities: List[OrderedDictT[str, Any]] = [] for commodity in data['lastStarport'].get('commodities') or []: # Check 'marketable' and 'not prohibited' @@ -376,7 +382,7 @@ Msg:\n{msg}''' ('stationName', data['lastStarport']['name']), ('marketId', data['lastStarport']['id']), ('commodities', commodities), - ('horizons', this.horizons), + ('horizons', horizons), ('odyssey', this.odyssey), ]) From cf5806021ec8ccbcf2d9274797b9dd8ee5c343ba Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 12:33:11 +0100 Subject: [PATCH 13/14] PLUGINS.md: capi_is_horizons() now --- PLUGINS.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/PLUGINS.md b/PLUGINS.md index e8a27474..8a27efff 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -659,13 +659,12 @@ New in version 5.0.1: `Odyssey` boolean based on the presence of such a flag in the `LoadGame` event. Defaults to `False`, i.e. if no such key in the event. -The previously undocumented`Horizons` boolean is similarly from `LoadGame`, -but blindly retrieves the value rather than having a strict default. There's +The previously undocumented `Horizons` boolean is similarly from `LoadGame`, +but blindly retrieves the value rather than having a strict default. There'd be an exception if it wasn't there, and the value would be `None`. Note that this is **NOT** the same as the return from -[plugins/eddn.py:is_horizons()](./plugins/eddn.py). That function is necessary -because CAPI data doesn't (didn't always?) have an indication of Horizons or -not. +[plugins/eddn.py:capi_is_horizons()](./plugins/eddn.py). That function is +necessary because CAPI data doesn't have a simple indication of Horizons-ness. New in version 5.0.3: From 7dcb275e9b390108ca2aa038430fe96cb9b21759 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Mon, 18 Oct 2021 14:18:11 +0100 Subject: [PATCH 14/14] EDDN: Document HORIZONS_SKU, and to NOT use the others --- plugins/eddn.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/eddn.py b/plugins/eddn.py index 71a93112..7e72aa0f 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -91,7 +91,15 @@ class This: this = This() -HORIZ_SKU = 'ELITE_HORIZONS_V_PLANETARY_LANDINGS' +# This SKU is tagged on any module or ship that you must have Horizons for. +HORIZONS_SKU = 'ELITE_HORIZONS_V_PLANETARY_LANDINGS' +# ELITE_HORIZONS_V_COBRA_MK_IV_1000` is for the Cobra Mk IV, but +# is also available in the base game, if you have entitlement. +# `ELITE_HORIZONS_V_GUARDIAN_FSDBOOSTER` is for the Guardian FSD Boosters, +# which you need Horizons in order to unlock, but could be on sale even in the +# base game due to entitlement. +# Thus do **NOT** use either of these in addition to the PLANETARY_LANDINGS +# one. # TODO: a good few of these methods are static or could be classmethods. they should be created as such. @@ -465,8 +473,8 @@ Msg:\n{msg}''' ) to_search: Iterator[Mapping[str, Any]] = filter( - lambda m: self.MODULE_RE.search(m['name']) and m.get('sku') in (None, HORIZ_SKU) and - m['name'] != 'Int_PlanetApproachSuite', + lambda m: self.MODULE_RE.search(m['name']) and m.get('sku') in (None, HORIZONS_SKU) + and m['name'] != 'Int_PlanetApproachSuite', # noqa: E131 modules.values() ) @@ -1467,7 +1475,7 @@ def capi_is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_ST logger.error(f'economies type is {type(economies)}') if isinstance(modules, dict): - modules_horizons = any(module.get('sku') == HORIZ_SKU for module in modules.values()) + modules_horizons = any(module.get('sku') == HORIZONS_SKU for module in modules.values()) else: logger.error(f'modules type is {type(modules)}') @@ -1475,7 +1483,7 @@ def capi_is_horizons(economies: MAP_STR_ANY, modules: MAP_STR_ANY, ships: MAP_ST if isinstance(ships, dict): if ships.get('shipyard_list') is not None: if isinstance(ships.get('shipyard_list'), dict): - ship_horizons = any(ship.get('sku') == HORIZ_SKU for ship in ships['shipyard_list'].values()) + ship_horizons = any(ship.get('sku') == HORIZONS_SKU for ship in ships['shipyard_list'].values()) else: logger.debug('ships["shipyard_list"] is not dict - FC or Damaged Station?')