mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2026-10-27 01:16:06 +03:00
Merge pull request #1798 from EDCD/fix/1042/centralise-plugin-tracking
Move core plugin 'location' tracking into monitor.py
This commit is contained in:
8 files changed
+667
-506
No files matched your search
@@ -326,10 +326,12 @@ sys.path: {sys.path}'''
|
||||
raise companion.CmdrError()
|
||||
|
||||
elif (
|
||||
data['lastSystem']['name'] != monitor.system 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()
|
||||
|
||||
@@ -431,10 +433,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.state['StationName']
|
||||
):
|
||||
data = new_data
|
||||
|
||||
if args.s:
|
||||
|
||||
+38
-26
@@ -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,30 +1272,32 @@ 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:
|
||||
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
|
||||
|
||||
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']:
|
||||
@@ -1526,7 +1528,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,8 +1591,8 @@ class AppWindow(object):
|
||||
err = plug.notify_journal_entry(
|
||||
monitor.cmdr,
|
||||
monitor.is_beta,
|
||||
monitor.system,
|
||||
monitor.station,
|
||||
monitor.state['SystemName'],
|
||||
monitor.state['StationName'],
|
||||
entry,
|
||||
monitor.state
|
||||
)
|
||||
@@ -1606,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'):
|
||||
@@ -1728,11 +1730,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.state['StationName']
|
||||
)
|
||||
|
||||
def cooldown(self) -> None:
|
||||
"""Display and update the cooldown timer for 'Update' button."""
|
||||
@@ -1746,12 +1753,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 +1770,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.state['StationName']}" if monitor.state['StationName']
|
||||
else monitor.state['SystemName']
|
||||
)
|
||||
|
||||
def help_general(self, event=None) -> None:
|
||||
"""Open Wiki Help page in browser."""
|
||||
@@ -1898,7 +1910,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.state['StationName']}.{timestamp}"
|
||||
)
|
||||
if not f:
|
||||
return
|
||||
|
||||
+96
-50
@@ -606,55 +606,63 @@ 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 |
|
||||
| `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` | `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 |
|
||||
| `Body` | `Optional[str]` | The body we're currently on / in the SOI of |
|
||||
| `BodyType` | `Optional[str]` | The type of body that `Body` refers to |
|
||||
| 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 |
|
||||
| `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.
|
||||
@@ -676,6 +684,31 @@ 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] - 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.
|
||||
|
||||
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,13 +798,26 @@ 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:
|
||||
|
||||
`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
|
||||
the 'Body' name value.
|
||||
|
||||
`StationName`, `MarketID`, and `StationType` added to the `state` dictionary.
|
||||
|
||||
___
|
||||
|
||||
##### Synthetic Events
|
||||
|
||||
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
|
||||
|
||||
+305
-186
@@ -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, Dict, List, MutableMapping, Optional
|
||||
from typing import OrderedDict as OrderedDictT
|
||||
from typing import Tuple
|
||||
from typing import TYPE_CHECKING, Any, BinaryIO, MutableMapping, Tuple
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import tkinter
|
||||
@@ -91,11 +89,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 +110,19 @@ 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.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
|
||||
@@ -144,7 +134,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
|
||||
@@ -195,8 +185,13 @@ 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,
|
||||
'SystemName': None,
|
||||
'SystemPopulation': None,
|
||||
'Body': None,
|
||||
'BodyID': None,
|
||||
'BodyType': None,
|
||||
'StationName': None,
|
||||
|
||||
'NavRoute': None,
|
||||
}
|
||||
@@ -274,7 +269,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.
|
||||
|
||||
@@ -306,19 +301,20 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.mode = None
|
||||
self.group = None
|
||||
self.cmdr = None
|
||||
self.planet = None
|
||||
self.system = None
|
||||
self.station = None
|
||||
self.station_marketid = None
|
||||
self.stationtype = 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
|
||||
self.state['BodyType'] = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['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()')
|
||||
@@ -417,24 +413,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
if self.game_was_running:
|
||||
logger.info("Game is/was running, so synthesizing StartUp event for plugins")
|
||||
# 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=(', ', ':')))
|
||||
|
||||
@@ -456,7 +435,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
|
||||
@@ -535,6 +514,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.state['SystemName'],
|
||||
'StarPos': self.state['StarPos'],
|
||||
'SystemAddress': self.state['SystemAddress'],
|
||||
'Population': self.state['SystemPopulation'],
|
||||
}
|
||||
|
||||
if self.state['Body']:
|
||||
entry['Body'] = self.state['Body']
|
||||
entry['BodyID'] = self.state['BodyID']
|
||||
entry['BodyType'] = self.state['BodyType']
|
||||
|
||||
if self.state['StationName']:
|
||||
entry['Docked'] = True
|
||||
entry['MarketID'] = self.state['MarketID']
|
||||
entry['StationName'] = self.state['StationName']
|
||||
entry['StationType'] = self.state['StationType']
|
||||
|
||||
else:
|
||||
entry['Docked'] = False
|
||||
|
||||
return entry
|
||||
|
||||
def parse_entry(self, line: bytes) -> MutableMapping[str, Any]: # noqa: C901, CCR001
|
||||
"""
|
||||
Parse a Journal JSON line.
|
||||
@@ -564,14 +578,16 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.cmdr = None
|
||||
self.mode = None
|
||||
self.group = None
|
||||
self.planet = None
|
||||
self.system = None
|
||||
self.station = None
|
||||
self.station_marketid = None
|
||||
self.stationtype = 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
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
self.coordinates = None
|
||||
self.systemaddress = None
|
||||
self.started = None
|
||||
self.__init_state()
|
||||
|
||||
@@ -600,34 +616,35 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.mode = entry.get('GameMode')
|
||||
|
||||
self.group = entry.get('Group')
|
||||
self.planet = None
|
||||
self.system = None
|
||||
self.station = None
|
||||
self.station_marketid = None
|
||||
self.stationtype = 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
|
||||
self.state['BodyType'] = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['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
|
||||
@@ -739,9 +756,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
modules.pop(from_slot, None)
|
||||
|
||||
elif event_type == 'undocked':
|
||||
self.station = None
|
||||
self.station_marketid = None
|
||||
self.stationtype = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
self.state['IsDocked'] = False
|
||||
|
||||
@@ -761,9 +778,11 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
# • StationName (if at a station)
|
||||
# • StationType
|
||||
# • MarketID
|
||||
self.station = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
if entry.get('OnStation'):
|
||||
self.station = entry.get('StationName', '')
|
||||
self.state['StationName'] = entry.get('StationName', '')
|
||||
self.state['MarketID'] = entry.get('MarketID', '')
|
||||
|
||||
self.state['OnFoot'] = False
|
||||
self.state['Taxi'] = entry['Taxi']
|
||||
@@ -791,10 +810,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):
|
||||
@@ -809,77 +828,204 @@ 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':
|
||||
###############################################################
|
||||
# Track: Station
|
||||
###############################################################
|
||||
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.state['StationName'] = entry.get('StationName') # It may be None
|
||||
self.state['MarketID'] = entry.get('MarketID') # 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 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
|
||||
"""
|
||||
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.
|
||||
|
||||
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
|
||||
###############################################################
|
||||
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')
|
||||
|
||||
if event_type == 'location':
|
||||
logger.trace_if('journal.locations', '"Location" event')
|
||||
if entry.get('Docked'):
|
||||
self.state['IsDocked'] = True
|
||||
|
||||
elif event_type == 'fsdjump':
|
||||
self.planet = None
|
||||
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.systemaddress = entry.get('SystemAddress')
|
||||
|
||||
self.systempopulation = entry.get('Population')
|
||||
|
||||
if entry['StarSystem'] == 'ProvingGround':
|
||||
self.system = 'CQC'
|
||||
self.state['StarPos'] = tuple(entry['StarPos']) # type: ignore
|
||||
|
||||
else:
|
||||
self.system = entry['StarSystem']
|
||||
logger.warning(f"'{event_type}' event without 'StarPos' !!!:\n{entry}\n")
|
||||
|
||||
self.station = entry.get('StationName') # 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 'SystemAddress' not in entry:
|
||||
logger.warning(f"{event_type} event without SystemAddress !!!:\n{entry}\n")
|
||||
|
||||
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'
|
||||
# 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.state['SystemPopulation'] = entry.get('Population')
|
||||
|
||||
if entry['StarSystem'] == 'ProvingGround':
|
||||
self.state['SystemName'] = 'CQC'
|
||||
|
||||
else:
|
||||
self.state['SystemName'] = entry['StarSystem']
|
||||
###############################################################
|
||||
|
||||
###############################################################
|
||||
# Track: Current station, if applicable
|
||||
###############################################################
|
||||
if event_type == 'fsdjump':
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
|
||||
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.state['MarketID'] = entry.get('MarketID') # May be None
|
||||
self.state['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.planet = entry['Body']
|
||||
self.state['Body'] = entry['Body']
|
||||
self.state['BodyType'] = 'Planet' # Best guess. Journal says always planet.
|
||||
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 in ('leavebody', 'supercruiseentry'):
|
||||
self.planet = None
|
||||
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':
|
||||
# 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
|
||||
###############################################################
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
###############################################################
|
||||
|
||||
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')
|
||||
@@ -1563,18 +1709,19 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
elif event_type == 'joinacrew':
|
||||
self.state['Captain'] = entry['Captain']
|
||||
self.state['Role'] = 'Idle'
|
||||
self.planet = 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['OnFoot'] = False
|
||||
|
||||
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
|
||||
self.state['BodyType'] = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
self.state['OnFoot'] = False
|
||||
|
||||
elif event_type == 'changecrewrole':
|
||||
self.state['Role'] = entry['Role']
|
||||
@@ -1582,17 +1729,18 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
elif event_type == 'quitacrew':
|
||||
self.state['Captain'] = None
|
||||
self.state['Role'] = None
|
||||
self.planet = 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['SystemName'] = None
|
||||
self.state['SystemAddress'] = None
|
||||
self.state['SystemPopulation'] = None
|
||||
self.state['StarPos'] = None
|
||||
self.state['Body'] = None
|
||||
self.state['BodyID'] = None
|
||||
self.state['BodyType'] = None
|
||||
self.state['StationName'] = None
|
||||
self.state['MarketID'] = None
|
||||
self.state['StationType'] = None
|
||||
self.stationservices = None
|
||||
|
||||
# TODO: on_foot: Will we get an event after this to know ?
|
||||
|
||||
elif event_type == 'friends':
|
||||
@@ -1677,11 +1825,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:
|
||||
@@ -1919,7 +2062,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.
|
||||
|
||||
@@ -1956,7 +2099,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.
|
||||
|
||||
@@ -1980,31 +2123,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=(', ', ':')))
|
||||
|
||||
@@ -2052,7 +2171,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.
|
||||
|
||||
@@ -2189,7 +2308,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.
|
||||
|
||||
@@ -2210,7 +2329,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))
|
||||
@@ -2251,7 +2370,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')
|
||||
@@ -2277,7 +2396,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')
|
||||
@@ -2349,7 +2468,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
|
||||
|
||||
+31
-55
@@ -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_name: str | None = None
|
||||
self.station_marketid: int | None = None
|
||||
self.on_foot = False
|
||||
|
||||
|
||||
@@ -133,9 +133,9 @@ 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_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]
|
||||
@@ -184,59 +184,35 @@ def journal_entry( # noqa: CCR001
|
||||
return
|
||||
|
||||
this.on_foot = state['OnFoot']
|
||||
# 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_address = state['SystemAddress']
|
||||
this.system_name = state['SystemName']
|
||||
this.system_population = state['SystemPopulation']
|
||||
this.station_name = state['StationName']
|
||||
this.station_marketid = state['MarketID']
|
||||
|
||||
# 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') or this.station
|
||||
# on_foot station detection
|
||||
if entry['event'] == 'Location' and entry['BodyType'] == 'Station':
|
||||
this.station = entry['Body']
|
||||
|
||||
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.
|
||||
if config.get_str('system_provider') == 'eddb':
|
||||
this.system_link['text'] = this.system
|
||||
# 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':
|
||||
text = this.station
|
||||
if not text:
|
||||
if this.station_name:
|
||||
this.station_link['text'] = this.station_name
|
||||
|
||||
else:
|
||||
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()
|
||||
|
||||
|
||||
def cmdr_data(data: CAPIData, is_beta: bool) -> Optional[str]:
|
||||
def cmdr_data(data: CAPIData, is_beta: bool) -> str | None:
|
||||
"""
|
||||
Process new CAPI data.
|
||||
|
||||
@@ -249,22 +225,22 @@ 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']
|
||||
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':
|
||||
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') == '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
|
||||
|
||||
+128
-81
@@ -82,10 +82,15 @@ 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.body_type: 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 +122,15 @@ 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_j_body_type: 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,18 +1127,17 @@ 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, 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)
|
||||
|
||||
@@ -1160,7 +1170,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 ?'
|
||||
|
||||
@@ -1202,7 +1212,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 ?'
|
||||
|
||||
@@ -1264,7 +1274,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 ?'
|
||||
|
||||
@@ -1279,6 +1289,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:
|
||||
@@ -1356,7 +1368,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 ?'
|
||||
|
||||
@@ -1651,7 +1663,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 ?'
|
||||
|
||||
@@ -1701,7 +1713,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 ?'
|
||||
|
||||
@@ -1757,7 +1769,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 ?'
|
||||
|
||||
@@ -1815,11 +1827,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
|
||||
|
||||
@@ -1963,23 +1975,75 @@ 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="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="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)
|
||||
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 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)
|
||||
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
|
||||
|
||||
@@ -1991,6 +2055,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
|
||||
@@ -1999,10 +2071,26 @@ 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
|
||||
|
||||
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()
|
||||
|
||||
|
||||
@@ -2208,68 +2296,28 @@ def journal_entry( # noqa: C901, CCR001
|
||||
entry
|
||||
)
|
||||
|
||||
# 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
|
||||
# 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.body_type = state['BodyType']
|
||||
this.coordinates = state['StarPos']
|
||||
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']
|
||||
|
||||
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
|
||||
|
||||
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')
|
||||
|
||||
# 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')
|
||||
|
||||
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
|
||||
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 == 'music':
|
||||
if entry['MusicTrack'] == 'MainMenu':
|
||||
this.body_name = None
|
||||
this.body_id = None
|
||||
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']:
|
||||
|
||||
@@ -2359,9 +2407,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:
|
||||
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
|
||||
@@ -2382,7 +2431,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?"
|
||||
|
||||
@@ -2399,7 +2448,7 @@ def journal_entry( # noqa: C901, CCR001
|
||||
|
||||
# Gazelle[TD] reported seeing a lagged Scan event with incorrect
|
||||
# augmented StarPos: <https://github.com/EDCD/EDMarketConnector/issues/961>
|
||||
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?"
|
||||
|
||||
@@ -2454,8 +2503,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
|
||||
|
||||
|
||||
@@ -2494,7 +2541,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']:
|
||||
|
||||
+19
-42
@@ -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
|
||||
|
||||
+39
-58
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user