mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-21 11:27:38 +03:00
Merge branch 'release-5.6.1' into releases
This commit is contained in:
commit
c5a1bae906
78
ChangeLog.md
78
ChangeLog.md
@ -27,10 +27,84 @@ produce the Windows executables and installer.
|
||||
|
||||
---
|
||||
|
||||
Release 5.6.1
|
||||
===
|
||||
This release addresses some minor bugs and annoyances with v5.6.0, especially
|
||||
for Legacy galaxy players.
|
||||
|
||||
In general, at this early stage of the galaxy split, we prefer to continue to
|
||||
warn Legacy users who have 'send data' options active for sites that only
|
||||
accept Live data. In the future this might be reviewed and such warnings
|
||||
removed such that the functionality *fails silently*. This might be of use
|
||||
to users who actively play in both galaxies.
|
||||
|
||||
* CAPI queries will now **only be attempted for Live galaxy players** This is
|
||||
a stop-gap whilst the functionality is implemented for Legacy galaxy players.
|
||||
Doing so prevents using Live galaxy data whilst playing Legacy galaxy, which
|
||||
would be increasingly wrong and misleading.
|
||||
1. 'Automatic update on docking' will do nothing for Legacy players.
|
||||
2. Pressing the 'Update' button whilst playing Legacy will result in a status
|
||||
line message "CAPI for Legacy not yet supported", and otherwise achieve
|
||||
nothing. **The only function of this button is to query CAPI data and
|
||||
pass it to plugins, which does *not* include Inara and EDSM**.
|
||||
3. A Legacy player trying to use "File" > "Status" will get the message
|
||||
"Status: No CAPI data yet" due to depending on CAPI data.
|
||||
|
||||
It is hoped to implement CAPI data retrieval and use for Legacy players soon,
|
||||
although this will likely entail extending the plugins API to include a new
|
||||
function specifically for this. Thus only updated plugins would support
|
||||
this.
|
||||
* EDDN: Where data has been sourced from the CAPI this application now sends
|
||||
a header->gameversion in the format `"CAPI-(Live|Legacy)-<endpoint"` as per
|
||||
[the updated documentation](https://github.com/EDCD/EDDN/blob/live/docs/Developers.md#gameversions-and-gamebuild).
|
||||
1. As *this* version only queries CAPI for Live players that will only be
|
||||
`"CAPI-Live-<endpoint>"` for the time being.
|
||||
|
||||
2. If, somehow, the CAPI host queried matches neither the
|
||||
current Live host, the Legacy host, nor the past beta host, you will see
|
||||
`"CAPI-UNKNOWN-<endpoint>"`.
|
||||
|
||||
3. As that statement implies, this application will also signal 'Live' if
|
||||
`pts-companion.orerve.net` has been used, due to detecting an alpha or beta
|
||||
version of the game. However, in that case the `/test` schemas will be used.
|
||||
|
||||
Closes [#1734](https://github.com/EDCD/EDMarketConnector/issues/1734).
|
||||
* Inara: Only warn about Legacy data if sending is enabled in Settings > Inara.
|
||||
|
||||
Closes [#1730](https://github.com/EDCD/EDMarketConnector/issues/1730).
|
||||
* Inara: Handling of some events has had a sanity check added so that the
|
||||
Inara API doesn't complain about empty strings being sent. In these cases
|
||||
the event will simply not be sent.
|
||||
|
||||
Closes [#1732](https://github.com/EDCD/EDMarketConnector/issues/1732).
|
||||
|
||||
* EDSM: EDSM has decided to accept only Live data on its API. Thus, this
|
||||
application will only attempt to send data for Live galaxy players.
|
||||
|
||||
If a Legacy galaxy player has the Settings > EDSM > "Send flight log and
|
||||
Cmdr status to EDSM" option active then they will receive an error about
|
||||
this at most once every 5 minutes. Disabling that option will prevent the
|
||||
warning.
|
||||
|
||||
Plugin Developers
|
||||
---
|
||||
* PLUGINS.md has been updated to make it clear that the only use of imports
|
||||
from the `config` module are for setting/getting/removing a plugin's own
|
||||
configuration, or detecting application shutdown in progress.
|
||||
* PLUGINS.md has also been updated to add a note about how the `data` passed
|
||||
to a plugin `cmdr_data()` is, strictly speaking, an instance of `CAPIData`,
|
||||
which is an extension of `UserDict`. It has some extra properties on it,
|
||||
**but these are for internal use only and no plugin should rely on them**.
|
||||
* As noted above, implementing CAPI data for Legacy players will likely entail
|
||||
an additional function in the API provided to plugins. See
|
||||
[#1728](https://github.com/EDCD/EDMarketConnector/issues/1728) for discussion
|
||||
about this.
|
||||
|
||||
---
|
||||
|
||||
Release 5.6.0
|
||||
===
|
||||
|
||||
Tha major reason for this release is to address the Live versus Legacy galaxy
|
||||
The major reason for this release is to address the Live versus Legacy galaxy
|
||||
split [coming in Update 14 of the game](https://www.elitedangerous.com/news/elite-dangerous-update-14-and-beyond-live-and-legacy-modes).
|
||||
See the section "Update 14 and the Galaxy Split" below for how this might
|
||||
impact you.
|
||||
|
@ -944,7 +944,7 @@ class AppWindow(object):
|
||||
|
||||
return True
|
||||
|
||||
def capi_request_data(self, event=None) -> None:
|
||||
def capi_request_data(self, event=None) -> None: # noqa: CCR001
|
||||
"""
|
||||
Perform CAPI data retrieval and associated actions.
|
||||
|
||||
@ -969,6 +969,17 @@ class AppWindow(object):
|
||||
self.status['text'] = _('CAPI query aborted: Game mode unknown')
|
||||
return
|
||||
|
||||
if monitor.state['GameVersion'] is None:
|
||||
logger.trace_if('capi.worker', 'Aborting Query: GameVersion unknown')
|
||||
# LANG: CAPI queries aborted because GameVersion unknown
|
||||
self.status['text'] = _('CAPI query aborted: GameVersion unknown')
|
||||
return
|
||||
|
||||
if not monitor.is_live_galaxy():
|
||||
logger.warning("Dropping CAPI request because this is the Legacy galaxy, which is not yet supported")
|
||||
self.status['text'] = 'CAPI for Legacy not yet supported'
|
||||
return
|
||||
|
||||
if not monitor.system:
|
||||
logger.trace_if('capi.worker', 'Aborting Query: Current star system unknown')
|
||||
# LANG: CAPI queries aborted because current star system name unknown
|
||||
@ -1161,6 +1172,7 @@ class AppWindow(object):
|
||||
monitor.state['Loan'] = capi_response.capi_data['commander'].get('debt', 0)
|
||||
|
||||
# stuff we can do when not docked
|
||||
# TODO: Use plug.notify_capi_legacy if Legacy host
|
||||
err = plug.notify_newdata(capi_response.capi_data, monitor.is_beta)
|
||||
self.status['text'] = err and err or ''
|
||||
if err:
|
||||
|
2
FDevIDs
2
FDevIDs
@ -1 +1 @@
|
||||
Subproject commit b3c5d061e1e81b4927a74d267f2440e78029a6ba
|
||||
Subproject commit 345d388fbcf64fc99acd45f4c765d52b59dce03b
|
@ -214,6 +214,9 @@
|
||||
/* EDMarketConnector.py: CAPI queries aborted because game mode unknown; In files: EDMarketConnector.py:967; */
|
||||
"CAPI query aborted: Game mode unknown" = "CAPI query aborted: Game mode unknown";
|
||||
|
||||
/* EDMarketConnector.py: CAPI queries aborted because GameVersion unknown; In files: EDMarketConnector.py:974; */
|
||||
"CAPI query aborted: GameVersion unknown" = "CAPI query aborted: GameVersion unknown";
|
||||
|
||||
/* EDMarketConnector.py: CAPI queries aborted because current star system name unknown; In files: EDMarketConnector.py:973; */
|
||||
"CAPI query aborted: Current system unknown" = "CAPI query aborted: Current system unknown";
|
||||
|
||||
|
16
PLUGINS.md
16
PLUGINS.md
@ -83,7 +83,18 @@ breaking with future code changes.**
|
||||
match the main UI.
|
||||
|
||||
`from config import appname, applongname, appcmdname, appversion
|
||||
, copyright, config` - to access config.
|
||||
, copyright, config` - to access config. *Intended use of config classes
|
||||
and functions is **only** for managing a plugin's own configuration*.
|
||||
Explicitly you can expect to use:
|
||||
- `config.set()` - to store a plugin configuration value.
|
||||
- `config.get_list()`, `config.get_str()`, `config.get_bool()`,
|
||||
`config.get_int()` - To retrieve a plugin configuration value.
|
||||
- `config.delete()` - To remove a plugin configuration value.
|
||||
- `config.shutting_down` (NB: a property, not a function!) to detect if the application
|
||||
is currently shutting down.
|
||||
|
||||
Anything else from `import config` is not part of the stable plugin API and
|
||||
liable to change without notice.
|
||||
|
||||
`from prefs import prefsVersion` - to allow for versioned preferences.
|
||||
|
||||
@ -885,6 +896,9 @@ data from Frontier's servers.
|
||||
| :-------- | :--------------: | :------------------------------------------------------------------------------------------------------- |
|
||||
| `data` | `Dict[str, Any]` | `/profile` API response, with `/market` and `/shipyard` added under the keys `marketdata` and `shipdata` |
|
||||
| `is_beta` | `bool` | If the game is currently in beta |
|
||||
NB: Actually `data` is a custom type, based on `UserDict`, called `CAPIData`,
|
||||
and has some extra properties. However, these are for **internal use only**
|
||||
at this time, especially as there are some caveats about at least one of them.
|
||||
|
||||
---
|
||||
|
||||
|
75
companion.py
75
companion.py
@ -55,6 +55,7 @@ auth_timeout = 30 # timeout for initial auth
|
||||
FRONTIER_AUTH_SERVER = 'https://auth.frontierstore.net'
|
||||
|
||||
SERVER_LIVE = 'https://companion.orerve.net'
|
||||
SERVER_LEGACY = 'https://legacy-companion.orerve.net'
|
||||
SERVER_BETA = 'https://pts-companion.orerve.net'
|
||||
|
||||
commodity_map: Dict = {}
|
||||
@ -65,24 +66,29 @@ class CAPIData(UserDict):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
data: Union[str, Dict[str, Any], 'CAPIData', None] = None, source_endpoint: str = None
|
||||
data: Union[str, Dict[str, Any], 'CAPIData', None] = None,
|
||||
source_host: str = None,
|
||||
source_endpoint: str = None
|
||||
) -> None:
|
||||
if data is None:
|
||||
super().__init__()
|
||||
|
||||
elif isinstance(data, str):
|
||||
super().__init__(json.loads(data))
|
||||
|
||||
else:
|
||||
super().__init__(data)
|
||||
|
||||
self.original_data = self.data.copy() # Just in case
|
||||
|
||||
self.source_host = source_host
|
||||
self.source_endpoint = source_endpoint
|
||||
|
||||
if source_endpoint is None:
|
||||
return
|
||||
|
||||
if source_endpoint == Session.FRONTIER_CAPI_PATH_SHIPYARD and self.data.get('lastStarport'):
|
||||
# All the other endpoints may or may not have a lastStarport, but definitely wont have valid data
|
||||
# All the other endpoints may or may not have a lastStarport, but definitely won't have valid data
|
||||
# for this check, which means it'll just make noise for no reason while we're working on other things
|
||||
self.check_modules_ships()
|
||||
|
||||
@ -556,7 +562,8 @@ class EDMCCAPIRequest(EDMCCAPIReturn):
|
||||
REQUEST_WORKER_SHUTDOWN = '__EDMC_WORKER_SHUTDOWN'
|
||||
|
||||
def __init__(
|
||||
self, endpoint: str, query_time: int,
|
||||
self, capi_host: str, endpoint: str,
|
||||
query_time: int,
|
||||
tk_response_event: Optional[str] = None,
|
||||
play_sound: bool = False, auto_update: bool = False
|
||||
):
|
||||
@ -564,6 +571,7 @@ class EDMCCAPIRequest(EDMCCAPIReturn):
|
||||
query_time=query_time, tk_response_event=tk_response_event,
|
||||
play_sound=play_sound, auto_update=auto_update
|
||||
)
|
||||
self.capi_host: str = capi_host # The CAPI host to use.
|
||||
self.endpoint: str = endpoint # The CAPI query to perform.
|
||||
|
||||
|
||||
@ -605,7 +613,6 @@ class Session(object):
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.state = Session.STATE_INIT
|
||||
self.server: Optional[str] = None
|
||||
self.credentials: Optional[Dict[str, Any]] = None
|
||||
self.requests_session: Optional[requests.Session] = None
|
||||
self.auth: Optional[Auth] = None
|
||||
@ -679,7 +686,6 @@ class Session(object):
|
||||
self.close()
|
||||
self.credentials = credentials
|
||||
|
||||
self.server = self.credentials['beta'] and SERVER_BETA or SERVER_LIVE
|
||||
self.state = Session.STATE_INIT
|
||||
self.auth = Auth(self.credentials['cmdr'])
|
||||
|
||||
@ -743,17 +749,24 @@ class Session(object):
|
||||
"""Worker thread that performs actual CAPI queries."""
|
||||
logger.debug('CAPI worker thread starting')
|
||||
|
||||
def capi_single_query( # noqa: CCR001
|
||||
capi_endpoint: str, timeout: int = capi_default_requests_timeout
|
||||
def capi_single_query(
|
||||
capi_host: str,
|
||||
capi_endpoint: str,
|
||||
timeout: int = capi_default_requests_timeout
|
||||
) -> CAPIData:
|
||||
"""
|
||||
Perform a *single* CAPI endpoint query within the thread worker.
|
||||
|
||||
:param capi_host: CAPI host to query.
|
||||
:param capi_endpoint: An actual Frontier CAPI endpoint to query.
|
||||
:param timeout: requests query timeout to use.
|
||||
:return: The resulting CAPI data, of type CAPIData.
|
||||
"""
|
||||
capi_data: CAPIData
|
||||
if capi_host == SERVER_LEGACY:
|
||||
logger.warning("Dropping CAPI request because this is the Legacy galaxy")
|
||||
return capi_data
|
||||
|
||||
try:
|
||||
logger.trace_if('capi.worker', 'Sending HTTP request...')
|
||||
if conf_module.capi_pretend_down:
|
||||
@ -764,7 +777,7 @@ class Session(object):
|
||||
# This is one-shot
|
||||
conf_module.capi_debug_access_token = None
|
||||
|
||||
r = self.requests_session.get(self.server + capi_endpoint, timeout=timeout) # type: ignore
|
||||
r = self.requests_session.get(capi_host + capi_endpoint, timeout=timeout) # type: ignore
|
||||
|
||||
logger.trace_if('capi.worker', '... got result...')
|
||||
r.raise_for_status() # Typically 403 "Forbidden" on token expiry
|
||||
@ -772,7 +785,7 @@ class Session(object):
|
||||
# r.status_code = 401
|
||||
# raise requests.HTTPError
|
||||
capi_json = r.json()
|
||||
capi_data = CAPIData(capi_json, capi_endpoint)
|
||||
capi_data = CAPIData(capi_json, capi_host, capi_endpoint)
|
||||
self.capi_raw_data.record_endpoint(
|
||||
capi_endpoint, r.content.decode(encoding='utf-8'),
|
||||
datetime.datetime.utcnow()
|
||||
@ -818,7 +831,9 @@ class Session(object):
|
||||
|
||||
return capi_data
|
||||
|
||||
def capi_station_queries(timeout: int = capi_default_requests_timeout) -> CAPIData: # noqa: CCR001
|
||||
def capi_station_queries( # noqa: CCR001
|
||||
capi_host: str, timeout: int = capi_default_requests_timeout
|
||||
) -> CAPIData:
|
||||
"""
|
||||
Perform all 'station' queries for the caller.
|
||||
|
||||
@ -831,7 +846,7 @@ class Session(object):
|
||||
:param timeout: requests timeout to use.
|
||||
:return: CAPIData instance with what we retrieved.
|
||||
"""
|
||||
station_data = capi_single_query(self.FRONTIER_CAPI_PATH_PROFILE, timeout=timeout)
|
||||
station_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_PROFILE, timeout=timeout)
|
||||
|
||||
if not station_data['commander'].get('docked') and not monitor.state['OnFoot']:
|
||||
return station_data
|
||||
@ -872,7 +887,7 @@ class Session(object):
|
||||
last_starport_id = int(last_starport.get('id'))
|
||||
|
||||
if services.get('commodities'):
|
||||
market_data = capi_single_query(self.FRONTIER_CAPI_PATH_MARKET, timeout=timeout)
|
||||
market_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_MARKET, timeout=timeout)
|
||||
if last_starport_id != int(market_data['id']):
|
||||
logger.warning(f"{last_starport_id!r} != {int(market_data['id'])!r}")
|
||||
raise ServerLagging()
|
||||
@ -882,7 +897,7 @@ class Session(object):
|
||||
station_data['lastStarport'].update(market_data)
|
||||
|
||||
if services.get('outfitting') or services.get('shipyard'):
|
||||
shipyard_data = capi_single_query(self.FRONTIER_CAPI_PATH_SHIPYARD, timeout=timeout)
|
||||
shipyard_data = capi_single_query(capi_host, self.FRONTIER_CAPI_PATH_SHIPYARD, timeout=timeout)
|
||||
if last_starport_id != int(shipyard_data['id']):
|
||||
logger.warning(f"{last_starport_id!r} != {int(shipyard_data['id'])!r}")
|
||||
raise ServerLagging()
|
||||
@ -909,10 +924,10 @@ class Session(object):
|
||||
capi_data: CAPIData
|
||||
try:
|
||||
if query.endpoint == self._CAPI_PATH_STATION:
|
||||
capi_data = capi_station_queries()
|
||||
capi_data = capi_station_queries(query.capi_host)
|
||||
|
||||
else:
|
||||
capi_data = capi_single_query(self.FRONTIER_CAPI_PATH_PROFILE)
|
||||
capi_data = capi_single_query(query.capi_host, self.FRONTIER_CAPI_PATH_PROFILE)
|
||||
|
||||
except Exception as e:
|
||||
self.capi_response_queue.put(
|
||||
@ -936,7 +951,7 @@ class Session(object):
|
||||
)
|
||||
|
||||
# If the query came from EDMC.(py|exe) there's no tk to send an
|
||||
# event too, so assume it will be polling there response queue.
|
||||
# event too, so assume it will be polling the response queue.
|
||||
if query.tk_response_event is not None:
|
||||
logger.trace_if('capi.worker', 'Sending <<CAPIResponse>>')
|
||||
self.tk_master.event_generate('<<CAPIResponse>>')
|
||||
@ -947,6 +962,7 @@ class Session(object):
|
||||
"""Ask the CAPI query thread to finish."""
|
||||
self.capi_request_queue.put(
|
||||
EDMCCAPIRequest(
|
||||
capi_host='',
|
||||
endpoint=EDMCCAPIRequest.REQUEST_WORKER_SHUTDOWN,
|
||||
query_time=int(time.time())
|
||||
)
|
||||
@ -964,10 +980,15 @@ class Session(object):
|
||||
:param play_sound: Whether the app should play a sound on error.
|
||||
:param auto_update: Whether this request was triggered automatically.
|
||||
"""
|
||||
capi_host = self.capi_host_for_galaxy()
|
||||
if not capi_host:
|
||||
return
|
||||
|
||||
# Ask the thread worker to perform all three queries
|
||||
logger.trace_if('capi.worker', 'Enqueueing request')
|
||||
self.capi_request_queue.put(
|
||||
EDMCCAPIRequest(
|
||||
capi_host=capi_host,
|
||||
endpoint=self._CAPI_PATH_STATION,
|
||||
tk_response_event=tk_response_event,
|
||||
query_time=query_time,
|
||||
@ -1048,6 +1069,28 @@ class Session(object):
|
||||
indent=2,
|
||||
sort_keys=True,
|
||||
separators=(',', ': ')).encode('utf-8'))
|
||||
|
||||
def capi_host_for_galaxy(self) -> str:
|
||||
"""
|
||||
Determine the correct CAPI host.
|
||||
|
||||
This is based on the current state of beta and game galaxy.
|
||||
|
||||
:return: The required CAPI host.
|
||||
"""
|
||||
if self.credentials is None:
|
||||
# Can't tell if beta or not
|
||||
return ''
|
||||
|
||||
if self.credentials['beta']:
|
||||
return SERVER_BETA
|
||||
|
||||
if monitor.is_live_galaxy():
|
||||
return SERVER_LIVE
|
||||
|
||||
# return SERVER_LEGACY # Not Yet
|
||||
logger.warning("Dropping CAPI request because this is the Legacy galaxy, which is not yet supported")
|
||||
return ""
|
||||
######################################################################
|
||||
|
||||
|
||||
|
@ -52,7 +52,7 @@ appcmdname = 'EDMC'
|
||||
# <https://semver.org/#semantic-versioning-specification-semver>
|
||||
# Major.Minor.Patch(-prerelease)(+buildmetadata)
|
||||
# NB: Do *not* import this, use the functions appversion() and appversion_nobuild()
|
||||
_static_appversion = '5.6.0'
|
||||
_static_appversion = '5.6.1'
|
||||
_cached_version: Optional[semantic_version.Version] = None
|
||||
copyright = '© 2015-2019 Jonathan Harris, 2020-2022 EDCD'
|
||||
|
||||
|
@ -41,6 +41,7 @@ from typing import Tuple, Union
|
||||
|
||||
import requests
|
||||
|
||||
import companion
|
||||
import edmc_data
|
||||
import killswitch
|
||||
import myNotebook as nb # noqa: N813
|
||||
@ -610,7 +611,7 @@ class EDDN:
|
||||
|
||||
logger.debug('Done.')
|
||||
|
||||
def export_commodities(self, data: Mapping[str, Any], is_beta: bool) -> None: # noqa: CCR001
|
||||
def export_commodities(self, data: CAPIData, is_beta: bool) -> None: # noqa: CCR001
|
||||
"""
|
||||
Update EDDN with the commodities on the current (lastStarport) station.
|
||||
|
||||
@ -678,7 +679,12 @@ class EDDN:
|
||||
self.send_message(data['commander']['name'], {
|
||||
'$schemaRef': f'https://eddn.edcd.io/schemas/commodity/3{"/test" if is_beta else ""}',
|
||||
'message': message,
|
||||
'header': self.standard_header(game_version='CAPI-market', game_build=''),
|
||||
'header': self.standard_header(
|
||||
game_version=self.capi_gameversion_from_host_endpoint(
|
||||
data.source_host, companion.Session.FRONTIER_CAPI_PATH_MARKET
|
||||
),
|
||||
game_build=''
|
||||
),
|
||||
})
|
||||
|
||||
this.commodities = commodities
|
||||
@ -772,7 +778,12 @@ class EDDN:
|
||||
('modules', outfitting),
|
||||
('odyssey', this.odyssey),
|
||||
]),
|
||||
'header': self.standard_header(game_version='CAPI-shipyard', game_build=''),
|
||||
'header': self.standard_header(
|
||||
game_version=self.capi_gameversion_from_host_endpoint(
|
||||
data.source_host, companion.Session.FRONTIER_CAPI_PATH_SHIPYARD
|
||||
),
|
||||
game_build=''
|
||||
),
|
||||
})
|
||||
|
||||
this.outfitting = (horizons, outfitting)
|
||||
@ -817,7 +828,12 @@ class EDDN:
|
||||
('ships', shipyard),
|
||||
('odyssey', this.odyssey),
|
||||
]),
|
||||
'header': self.standard_header(game_version='CAPI-shipyard', game_build=''),
|
||||
'header': self.standard_header(
|
||||
game_version=self.capi_gameversion_from_host_endpoint(
|
||||
data.source_host, companion.Session.FRONTIER_CAPI_PATH_SHIPYARD
|
||||
),
|
||||
game_build=''
|
||||
),
|
||||
})
|
||||
|
||||
this.shipyard = (horizons, shipyard)
|
||||
@ -1467,7 +1483,7 @@ class EDDN:
|
||||
return None
|
||||
|
||||
def export_capi_fcmaterials(
|
||||
self, data: Mapping[str, Any], is_beta: bool, horizons: bool
|
||||
self, data: CAPIData, is_beta: bool, horizons: bool
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Send CAPI-sourced 'onfootmicroresources' data on `fcmaterials/1` schema.
|
||||
@ -1519,7 +1535,11 @@ class EDDN:
|
||||
msg = {
|
||||
'$schemaRef': f'https://eddn.edcd.io/schemas/fcmaterials_capi/1{"/test" if is_beta else ""}',
|
||||
'message': entry,
|
||||
'header': self.standard_header(game_version='CAPI-market', game_build=''),
|
||||
'header': self.standard_header(
|
||||
game_version=self.capi_gameversion_from_host_endpoint(
|
||||
data.source_host, companion.Session.FRONTIER_CAPI_PATH_MARKET
|
||||
), game_build=''
|
||||
),
|
||||
}
|
||||
|
||||
this.eddn.send_message(data['commander']['name'], msg)
|
||||
@ -1825,9 +1845,47 @@ class EDDN:
|
||||
match = self.CANONICALISE_RE.match(item)
|
||||
return match and match.group(1) or item
|
||||
|
||||
def capi_gameversion_from_host_endpoint(self, capi_host: str, capi_endpoint: str) -> str:
|
||||
"""
|
||||
Return the correct CAPI gameversion string for the given host/endpoint.
|
||||
|
||||
:param capi_host: CAPI host used.
|
||||
:param capi_endpoint: CAPI endpoint queried.
|
||||
:return: CAPI gameversion string.
|
||||
"""
|
||||
gv = ''
|
||||
#######################################################################
|
||||
# Base string
|
||||
if capi_host == companion.SERVER_LIVE or capi_host == companion.SERVER_BETA:
|
||||
gv = 'CAPI-Live-'
|
||||
|
||||
elif capi_host == companion.SERVER_LEGACY:
|
||||
gv = 'CAPI-Legacy-'
|
||||
|
||||
else:
|
||||
# Technically incorrect, but it will inform Listeners
|
||||
logger.error(f"{capi_host=} lead to bad gameversion")
|
||||
gv = 'CAPI-UNKNOWN-'
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
# endpoint
|
||||
if capi_endpoint == companion.Session.FRONTIER_CAPI_PATH_MARKET:
|
||||
gv += 'market'
|
||||
|
||||
elif capi_endpoint == companion.Session.FRONTIER_CAPI_PATH_SHIPYARD:
|
||||
gv += 'shipyard'
|
||||
|
||||
else:
|
||||
# Technically incorrect, but it will inform Listeners
|
||||
logger.error(f"{capi_endpoint=} lead to bad gameversion")
|
||||
gv += 'UNKNOWN'
|
||||
#######################################################################
|
||||
|
||||
return gv
|
||||
|
||||
|
||||
# Plugin callbacks
|
||||
|
||||
def plugin_start3(plugin_dir: str) -> str:
|
||||
"""
|
||||
Start this plugin.
|
||||
|
@ -34,6 +34,7 @@
|
||||
import json
|
||||
import threading
|
||||
import tkinter as tk
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
@ -42,6 +43,7 @@ from typing import TYPE_CHECKING, Any, List, Literal, Mapping, MutableMapping, O
|
||||
import requests
|
||||
|
||||
import killswitch
|
||||
import monitor
|
||||
import myNotebook as nb # noqa: N813
|
||||
import plug
|
||||
from companion import CAPIData
|
||||
@ -74,6 +76,9 @@ class This:
|
||||
self.game_version = ""
|
||||
self.game_build = ""
|
||||
|
||||
# Handle only sending Live galaxy data
|
||||
self.legacy_galaxy_last_notified: Optional[datetime] = None
|
||||
|
||||
self.session: requests.Session = requests.Session()
|
||||
self.session.headers['User-Agent'] = user_agent
|
||||
self.queue: Queue = Queue() # Items to be sent to EDSM by worker thread
|
||||
@ -420,20 +425,30 @@ def credentials(cmdr: str) -> Optional[Tuple[str, str]]:
|
||||
|
||||
def journal_entry( # noqa: C901, CCR001
|
||||
cmdr: str, is_beta: bool, system: str, station: str, entry: MutableMapping[str, Any], state: Mapping[str, Any]
|
||||
) -> None:
|
||||
"""Journal Entry hook."""
|
||||
) -> str:
|
||||
"""
|
||||
Process a Journal event.
|
||||
|
||||
:param cmdr:
|
||||
:param is_beta:
|
||||
:param system:
|
||||
:param station:
|
||||
:param entry:
|
||||
:param state:
|
||||
:return: str - empty if no error, else error string.
|
||||
"""
|
||||
should_return, new_entry = killswitch.check_killswitch('plugins.edsm.journal', entry, logger)
|
||||
if should_return:
|
||||
# LANG: EDSM plugin - Journal handling disabled by killswitch
|
||||
plug.show_error(_('EDSM Handler disabled. See Log.'))
|
||||
return
|
||||
return ''
|
||||
|
||||
should_return, new_entry = killswitch.check_killswitch(
|
||||
f'plugins.edsm.journal.event.{entry["event"]}', data=new_entry, log=logger
|
||||
)
|
||||
|
||||
if should_return:
|
||||
return
|
||||
return ''
|
||||
|
||||
this.game_version = state['GameVersion']
|
||||
this.game_build = state['GameBuild']
|
||||
@ -530,6 +545,21 @@ entry: {entry!r}'''
|
||||
|
||||
# Queue all events to send to EDSM. worker() will take care of dropping EDSM discarded events
|
||||
if config.get_int('edsm_out') and not is_beta and not this.multicrew and credentials(cmdr):
|
||||
if not monitor.monitor.is_live_galaxy():
|
||||
logger.info("EDSM only accepts Live galaxy data")
|
||||
# Since Update 14 on 2022-11-29 Inara only accepts Live data.
|
||||
if (
|
||||
this.legacy_galaxy_last_notified is None
|
||||
or (datetime.now(timezone.utc) - this.legacy_galaxy_last_notified) > timedelta(seconds=300)
|
||||
):
|
||||
# LANG: The Inara API only accepts Live galaxy data, not Legacy galaxy data
|
||||
logger.info("EDSM only accepts Live galaxy data")
|
||||
# this.parent.children['status']['text'] =
|
||||
this.legacy_galaxy_last_notified = datetime.now(timezone.utc)
|
||||
return _("EDSM only accepts Live galaxy data")
|
||||
|
||||
return ''
|
||||
|
||||
# Introduce transient states into the event
|
||||
transient = {
|
||||
'_systemName': system,
|
||||
@ -563,6 +593,8 @@ Queueing: {entry!r}'''
|
||||
|
||||
this.queue.put((cmdr, this.game_version, this.game_build, entry))
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
# Update system data
|
||||
def cmdr_data(data: CAPIData, is_beta: bool) -> None:
|
||||
|
@ -370,22 +370,21 @@ def journal_entry( # noqa: C901, CCR001
|
||||
:return: str - empty if no error, else error string.
|
||||
"""
|
||||
if not monitor.is_live_galaxy():
|
||||
# This only applies after Update 14, which as of 2022-11-27 is scheduled
|
||||
# for 2022-11-29, with the game servers presumably being down around
|
||||
# 09:00
|
||||
if datetime.now(timezone.utc) >= datetime.fromisoformat("2022-11-27T09:00:00+00:00"):
|
||||
# Update 14 ETA has passed, so perform the check
|
||||
if (
|
||||
# Since Update 14 on 2022-11-29 Inara only accepts Live data.
|
||||
if (
|
||||
(
|
||||
this.legacy_galaxy_last_notified is None
|
||||
or (datetime.now(timezone.utc) - this.legacy_galaxy_last_notified) > timedelta(seconds=300)
|
||||
):
|
||||
# LANG: The Inara API only accepts Live galaxy data, not Legacy galaxy data
|
||||
logger.info(_("Inara only accepts Live galaxy data"))
|
||||
# this.parent.children['status']['text'] =
|
||||
this.legacy_galaxy_last_notified = datetime.now(timezone.utc)
|
||||
return _("Inara only accepts Live galaxy data")
|
||||
)
|
||||
and config.get_int('inara_out') and not is_beta and not this.multicrew and credentials(cmdr)
|
||||
):
|
||||
# LANG: The Inara API only accepts Live galaxy data, not Legacy galaxy data
|
||||
logger.info(_("Inara only accepts Live galaxy data"))
|
||||
# this.parent.children['status']['text'] =
|
||||
this.legacy_galaxy_last_notified = datetime.now(timezone.utc)
|
||||
return _("Inara only accepts Live galaxy data")
|
||||
|
||||
return ''
|
||||
return ''
|
||||
|
||||
should_return, new_entry = killswitch.check_killswitch('plugins.inara.journal', entry, logger)
|
||||
if should_return:
|
||||
@ -1069,7 +1068,12 @@ def journal_entry( # noqa: C901, CCR001
|
||||
elif 'Power' in entry:
|
||||
data['opponentName'] = entry['Power']
|
||||
|
||||
new_add_event('addCommanderCombatInterdicted', entry['timestamp'], data)
|
||||
# Paranoia in case of e.g. Thargoid activity not having complete data
|
||||
if data['opponentName'] == "":
|
||||
logger.warning('Dropping addCommanderCombatInterdicted message because opponentName came out as ""')
|
||||
|
||||
else:
|
||||
new_add_event('addCommanderCombatInterdicted', entry['timestamp'], data)
|
||||
|
||||
elif event_name == 'Interdiction':
|
||||
data = OrderedDict([
|
||||
@ -1087,18 +1091,31 @@ def journal_entry( # noqa: C901, CCR001
|
||||
elif 'Power' in entry:
|
||||
data['opponentName'] = entry['Power']
|
||||
|
||||
new_add_event('addCommanderCombatInterdiction', entry['timestamp'], data)
|
||||
# Paranoia in case of e.g. Thargoid activity not having complete data
|
||||
if data['opponentName'] == "":
|
||||
logger.warning('Dropping addCommanderCombatInterdiction message because opponentName came out as ""')
|
||||
|
||||
else:
|
||||
new_add_event('addCommanderCombatInterdiction', entry['timestamp'], data)
|
||||
|
||||
elif event_name == 'EscapeInterdiction':
|
||||
new_add_event(
|
||||
'addCommanderCombatInterdictionEscape',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': system,
|
||||
'opponentName': entry['Interdictor'],
|
||||
'isPlayer': entry['IsPlayer'],
|
||||
}
|
||||
)
|
||||
# Paranoia in case of e.g. Thargoid activity not having complete data
|
||||
if entry.get('Interdictor') is None or entry['Interdictor'] == "":
|
||||
logger.warning(
|
||||
'Dropping addCommanderCombatInterdictionEscape message'
|
||||
'because opponentName came out as ""'
|
||||
)
|
||||
|
||||
else:
|
||||
new_add_event(
|
||||
'addCommanderCombatInterdictionEscape',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': system,
|
||||
'opponentName': entry['Interdictor'],
|
||||
'isPlayer': entry['IsPlayer'],
|
||||
}
|
||||
)
|
||||
|
||||
elif event_name == 'PVPKill':
|
||||
new_add_event(
|
||||
|
@ -5,7 +5,7 @@ wheel
|
||||
# We can't rely on just picking this up from either the base (not venv),
|
||||
# or venv-init-time version. Specify here so that dependabot will prod us
|
||||
# about new versions.
|
||||
setuptools==65.6.0
|
||||
setuptools==65.6.3
|
||||
|
||||
# Static analysis tools
|
||||
flake8==5.0.4
|
||||
@ -16,13 +16,13 @@ flake8-docstrings==1.6.0
|
||||
isort==5.10.1
|
||||
flake8-isort==5.0.3
|
||||
flake8-json==21.7.0
|
||||
flake8-noqa==1.2.9
|
||||
flake8-noqa==1.3.0
|
||||
flake8-polyfill==1.0.2
|
||||
flake8-use-fstring==1.4
|
||||
|
||||
mypy==0.991
|
||||
pep8-naming==0.13.2
|
||||
safety==2.3.1
|
||||
safety==2.3.3
|
||||
types-requests==2.28.11.5
|
||||
|
||||
# Code formatting tools
|
||||
|
@ -97,7 +97,7 @@ elif sys.platform == 'linux':
|
||||
class OldConfig():
|
||||
"""Object that holds all configuration data."""
|
||||
|
||||
OUT_MKT_EDDN = 1
|
||||
OUT_EDDN_SEND_STATION_DATA = 1
|
||||
# OUT_MKT_BPC = 2 # No longer supported
|
||||
OUT_MKT_TD = 4
|
||||
OUT_MKT_CSV = 8
|
||||
@ -106,12 +106,12 @@ class OldConfig():
|
||||
# OUT_SYS_FILE = 32 # No longer supported
|
||||
# OUT_STAT = 64 # No longer available
|
||||
# OUT_SHIP_CORIOLIS = 128 # Replaced by OUT_SHIP
|
||||
OUT_STATION_ANY = OUT_MKT_EDDN | OUT_MKT_TD | OUT_MKT_CSV
|
||||
# OUT_SYS_EDSM = 256 # Now a plugin
|
||||
# OUT_SYS_AUTO = 512 # Now always automatic
|
||||
OUT_MKT_MANUAL = 1024
|
||||
OUT_SYS_EDDN = 2048
|
||||
OUT_SYS_DELAY = 4096
|
||||
OUT_EDDN_SEND_NON_STATION = 2048
|
||||
OUT_EDDN_DELAY = 4096
|
||||
OUT_STATION_ANY = OUT_EDDN_SEND_STATION_DATA | OUT_MKT_TD | OUT_MKT_CSV
|
||||
|
||||
if sys.platform == 'darwin': # noqa: C901 # It's gating *all* the functions
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user