mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-15 00:30:33 +03:00
Merge pull request #1130 from EDCD/enhancement/1127-inara-odyssey-support
Update INARA plugin to support new odyssey API endpoints
This commit is contained in:
commit
4273e2b551
48
monitor.py
48
monitor.py
@ -160,6 +160,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
'Suits': {},
|
||||
'SuitLoadoutCurrent': None,
|
||||
'SuitLoadouts': {},
|
||||
'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.
|
||||
'Body': None,
|
||||
'BodyType': None,
|
||||
}
|
||||
|
||||
def start(self, root: 'tkinter.Tk') -> bool: # noqa: CCR001
|
||||
@ -261,6 +265,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.systemaddress = None
|
||||
self.is_beta = False
|
||||
self.state['OnFoot'] = False
|
||||
self.state['Body'] = None
|
||||
self.state['BodyType'] = None
|
||||
|
||||
if self.observed:
|
||||
logger.debug('self.observed: Calling unschedule_all()')
|
||||
@ -535,6 +541,10 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
'Reputation': {},
|
||||
'Statistics': {},
|
||||
'Role': None,
|
||||
'Taxi': None,
|
||||
'Dropship': None,
|
||||
'Body': None,
|
||||
'BodyType': None,
|
||||
})
|
||||
if entry.get('Ship') is not None and self._RE_SHIP_ONFOOT.search(entry['Ship']):
|
||||
self.state['OnFoot'] = True
|
||||
@ -668,6 +678,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.station = entry.get('StationName', '')
|
||||
|
||||
self.state['OnFoot'] = False
|
||||
self.state['Taxi'] = entry['Taxi']
|
||||
|
||||
elif event_type == 'Disembark':
|
||||
# This event is logged when the player steps out of a ship or SRV
|
||||
@ -694,10 +705,17 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.station = None
|
||||
|
||||
self.state['OnFoot'] = True
|
||||
if self.state['Taxi'] is not None and self.state['Taxi'] != entry.get('Taxi', False):
|
||||
logger.warning('Disembarked from a taxi but we didn\'t know we were in a taxi?')
|
||||
|
||||
self.state['Taxi'] = False
|
||||
self.state['Dropship'] = False
|
||||
|
||||
elif event_type == 'DropshipDeploy':
|
||||
# We're definitely on-foot now
|
||||
self.state['OnFoot'] = True
|
||||
self.state['Taxi'] = False
|
||||
self.state['Dropship'] = False
|
||||
|
||||
elif event_type == 'Docked':
|
||||
self.station = entry.get('StationName') # May be None
|
||||
@ -705,6 +723,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.stationtype = entry.get('StationType') # 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
|
||||
|
||||
elif event_type in ('Location', 'FSDJump', 'CarrierJump'):
|
||||
# alpha4 - any changes ?
|
||||
# Location:
|
||||
@ -715,12 +735,16 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
# • OnFoot: bool
|
||||
if event_type in ('Location', 'CarrierJump'):
|
||||
self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None
|
||||
self.state['Body'] = entry.get('Body')
|
||||
self.state['BodyType'] = entry.get('BodyType')
|
||||
|
||||
# if event_type == 'Location':
|
||||
# logger.trace('"Location" event')
|
||||
|
||||
elif event_type == 'FSDJump':
|
||||
self.planet = None
|
||||
self.state['Body'] = None
|
||||
self.state['BodyType'] = None
|
||||
|
||||
if 'StarPos' in entry:
|
||||
self.coordinates = tuple(entry['StarPos']) # type: ignore
|
||||
@ -742,11 +766,19 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.stationtype = entry.get('StationType') # May be None
|
||||
self.stationservices = entry.get('StationServices') # None in Odyssey for on-foot 'Location'
|
||||
|
||||
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.
|
||||
|
||||
elif event_type in ('LeaveBody', 'SupercruiseEntry'):
|
||||
self.planet = None
|
||||
self.state['Body'] = None
|
||||
self.state['BodyType'] = None
|
||||
|
||||
elif event_type in ('Rank', 'Promotion'):
|
||||
payload = dict(entry)
|
||||
@ -1284,6 +1316,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
|
||||
elif event_type == 'BookDropship':
|
||||
self.state['Credits'] -= entry.get('Cost', 0)
|
||||
self.state['Dropship'] = True
|
||||
# Technically we *might* now not be OnFoot.
|
||||
# The problem is that this event is recorded both for signing up for
|
||||
# an on-foot CZ, and when you use the Dropship to return after the
|
||||
@ -1297,12 +1330,16 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
|
||||
elif event_type == 'BookTaxi':
|
||||
self.state['Credits'] -= entry.get('Cost', 0)
|
||||
# Dont set taxi state here, as we're not IN a taxi yet. Set it on Embark
|
||||
|
||||
elif event_type == 'CancelDropship':
|
||||
self.state['Credits'] += entry.get('Refund', 0)
|
||||
self.state['Dropship'] = False
|
||||
self.state['Taxi'] = False
|
||||
|
||||
elif event_type == 'CancelTaxi':
|
||||
self.state['Credits'] += entry.get('Refund', 0)
|
||||
self.state['Taxi'] = False
|
||||
|
||||
elif event_type == 'NavRoute':
|
||||
# Added in ED 3.7 - multi-hop route details in NavRoute.json
|
||||
@ -1493,6 +1530,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.systemaddress = None
|
||||
self.state['OnFoot'] = False
|
||||
|
||||
self.state['Body'] = None
|
||||
self.state['BodyType'] = None
|
||||
|
||||
elif event_type == 'ChangeCrewRole':
|
||||
self.state['Role'] = entry['Role']
|
||||
|
||||
@ -1507,6 +1547,9 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
self.stationservices = None
|
||||
self.coordinates = None
|
||||
self.systemaddress = None
|
||||
|
||||
self.state['Body'] = None
|
||||
self.state['BodyType'] = None
|
||||
# TODO: on_foot: Will we get an event after this to know ?
|
||||
|
||||
elif event_type == 'Friends':
|
||||
@ -1588,6 +1631,11 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
|
||||
elif event_type == 'Resurrect':
|
||||
self.state['Credits'] -= entry.get('Cost', 0)
|
||||
|
||||
# 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:
|
||||
|
243
plugins/inara.py
243
plugins/inara.py
@ -565,15 +565,37 @@ def journal_entry( # noqa: C901, CCR001
|
||||
this.suppress_docked = False
|
||||
|
||||
else:
|
||||
to_send = {
|
||||
'starsystemName': system,
|
||||
'stationName': station,
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
|
||||
if entry.get('Taxi'):
|
||||
# we're in a taxi, dont store ShipType or shipGameID
|
||||
del to_send['shipType']
|
||||
del to_send['shipGameID']
|
||||
|
||||
# We were in a taxi. What kind?
|
||||
if state['Dropship'] is not None and state['Dropship']:
|
||||
to_send['isTaxiDropship'] = True
|
||||
|
||||
elif state['Taxi'] is not None and state['Taxi']:
|
||||
to_send['isTaxiShuttle'] = True
|
||||
|
||||
else: # we dont know one way or another. Given we were told it IS a taxi, assume its a shuttle.
|
||||
to_send['isTaxiShuttle'] = True
|
||||
|
||||
if 'MarketID' in entry:
|
||||
to_send['marketID'] = entry['MarketID']
|
||||
|
||||
# TODO: we _can_ include a Body name here, but I'm not entirely sure how best to go about doing that
|
||||
|
||||
new_add_event(
|
||||
'addCommanderTravelDock',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': system,
|
||||
'stationName': station,
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
to_send
|
||||
)
|
||||
|
||||
elif event_name == 'Undocked':
|
||||
@ -597,15 +619,29 @@ def journal_entry( # noqa: C901, CCR001
|
||||
|
||||
elif event_name == 'FSDJump':
|
||||
this.undocked = False
|
||||
to_send = {
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'starsystemCoords': entry['StarPos'],
|
||||
'jumpDistance': entry['JumpDist'],
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
|
||||
if state['Taxi'] is not None and state['Taxi']:
|
||||
del to_send['shipType']
|
||||
del to_send['shipGameID']
|
||||
|
||||
# taxi. What kind?
|
||||
if state['Dropship'] is not None and state['Dropship']:
|
||||
to_send['isTaxiDropship'] = True
|
||||
|
||||
else:
|
||||
to_send['isTaxiShuttle'] = True
|
||||
|
||||
new_add_event(
|
||||
'addCommanderTravelFSDJump',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'jumpDistance': entry['JumpDist'],
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
to_send
|
||||
)
|
||||
|
||||
if entry.get('Factions'):
|
||||
@ -619,16 +655,21 @@ def journal_entry( # noqa: C901, CCR001
|
||||
)
|
||||
|
||||
elif event_name == 'CarrierJump':
|
||||
to_send = {
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'stationName': entry['StationName'],
|
||||
'marketID': entry['MarketID'],
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
|
||||
if 'StarPos' in entry:
|
||||
to_send['starsystemCoords'] = entry['StarPos']
|
||||
|
||||
new_add_event(
|
||||
'addCommanderTravelCarrierJump',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'stationName': entry['StationName'],
|
||||
'marketID': entry['MarketID'],
|
||||
'shipType': state['ShipType'],
|
||||
'shipGameID': state['ShipID'],
|
||||
}
|
||||
to_send
|
||||
)
|
||||
|
||||
if entry.get('Factions'):
|
||||
@ -975,6 +1016,167 @@ def journal_entry( # noqa: C901, CCR001
|
||||
}
|
||||
)
|
||||
|
||||
# New Odyssey features
|
||||
elif event_name == 'DropshipDeploy':
|
||||
new_add_event(
|
||||
'addCommanderTravelLand',
|
||||
entry['timestamp'],
|
||||
{
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'starsystemBodyName': entry['Body'],
|
||||
'isTaxiDropship': True,
|
||||
}
|
||||
)
|
||||
|
||||
elif event_name == 'Touchdown':
|
||||
# Touchdown has FAR more info available on Odyssey vs Horizons:
|
||||
# Horizons:
|
||||
# {"timestamp":"2021-05-31T09:10:54Z","event":"Touchdown",
|
||||
# "PlayerControlled":true,"Latitude":46.691929,"Longitude":-92.679977}
|
||||
#
|
||||
# Odyssey:
|
||||
# {"timestamp":"2021-05-31T08:48:08Z","event":"Touchdown","PlayerControlled":true,"Taxi":false,
|
||||
# "Multicrew":false,"StarSystem":"Gateway","SystemAddress":2832631665362,"Body":"Saunder's Rock","BodyID":2,
|
||||
# "OnStation":false,"OnPlanet":true,"Latitude":54.79665,"Longitude":-99.498253}
|
||||
#
|
||||
# So we're going to do a lot of checking here and bail out if we dont like the look of ANYTHING here
|
||||
|
||||
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)
|
||||
body_name = entry.get('Body', state['Body'] if state['BodyType'] == 'Planet' else None)
|
||||
|
||||
if star_system_name is None:
|
||||
logger.warning('Refusing to update addCommanderTravelLand as we dont have a StarSystem!')
|
||||
to_send_data = None
|
||||
|
||||
if body_name is None:
|
||||
logger.warning('Refusing to update addCommanderTravelLand as we dont have a Body!')
|
||||
to_send_data = None
|
||||
|
||||
if (op := entry.get('OnPlanet')) is not None and not op:
|
||||
logger.warning('Refusing to update addCommanderTravelLand when OnPlanet is False!')
|
||||
logger.warning(f'{entry=}')
|
||||
to_send_data = None
|
||||
|
||||
if not entry['PlayerControlled']:
|
||||
logger.info("Not updating inara addCommanderTravelLand for autonomous recall landing")
|
||||
to_send_data = None
|
||||
|
||||
if to_send_data is not None:
|
||||
# Above checks passed. Lets build and send this!
|
||||
to_send_data['starsystemName'] = star_system_name # Required
|
||||
to_send_data['starsystemBodyName'] = body_name # Required
|
||||
|
||||
# Following are optional
|
||||
|
||||
# lat/long is always there unless its an automated (recall) landing. Thus as we're sure its _not_
|
||||
# we can assume this exists. If it doesn't its a bug anyway.
|
||||
to_send_data['starsystemBodyCoords'] = [entry['Latitude'], entry['Longitude']]
|
||||
if state.get('ShipID') is not None:
|
||||
to_send_data['shipGameID'] = state['ShipID']
|
||||
|
||||
if state.get('ShipType') is not None:
|
||||
to_send_data['shipType'] = state['ShipType']
|
||||
|
||||
to_send_data['isTaxiShuttle'] = False
|
||||
to_send_data['isTaxiDropShip'] = False
|
||||
|
||||
new_add_event('addCommanderTravelLand', entry['timestamp'], to_send_data)
|
||||
|
||||
elif event_name == 'ShipLockerMaterials':
|
||||
odyssey_plural_microresource_types = ('Items', 'Components', 'Data', 'Consumables')
|
||||
# we're getting new data here. so reset it on inara's side just to be sure that we set everything right
|
||||
reset_data = [{'itemType': t} for t in odyssey_plural_microresource_types]
|
||||
set_data = []
|
||||
for typ in odyssey_plural_microresource_types:
|
||||
set_data.extend([
|
||||
{'itemName': thing['Name'], 'itemCount': thing['Count'], 'itemType': typ} for thing in entry[typ]
|
||||
])
|
||||
|
||||
new_add_event('resetCommanderInventory', entry['timestamp'], reset_data)
|
||||
new_add_event('setCommanderInventory', entry['timestamp'], set_data)
|
||||
|
||||
elif event_name in ('CreateSuitLoadout', 'SuitLoadout'):
|
||||
# CreateSuitLoadout and SuitLoadout are pretty much the same event:
|
||||
# ╙─╴% cat Journal.* | jq 'select(.event == "SuitLoadout" or .event == "CreateSuitLoadout") | keys' -c \
|
||||
# | uniq
|
||||
#
|
||||
# ["LoadoutID","LoadoutName","Modules","SuitID","SuitMods","SuitName","SuitName_Localised","event",
|
||||
# "timestamp"]
|
||||
|
||||
to_send = {
|
||||
'loadoutGameID': entry['LoadoutID'],
|
||||
'loadoutName': entry['LoadoutName'],
|
||||
'suitGameID': entry['SuitID'],
|
||||
'suitType': entry['SuitName'],
|
||||
'suitMods': entry['SuitMods'],
|
||||
'suitLoadout': [
|
||||
{
|
||||
'slotName': x['SlotName'],
|
||||
'itemName': x['ModuleName'],
|
||||
'itemClass': x['Class'],
|
||||
'itemGameID': x['SuitModuleID'],
|
||||
'engineering': [{'blueprintName': mod} for mod in x['WeaponMods']],
|
||||
} for x in entry['Modules']
|
||||
],
|
||||
}
|
||||
|
||||
new_add_event('setCommanderSuitLoadout', entry['timestamp'], to_send)
|
||||
|
||||
elif event_name == 'DeleteSuitLoadout':
|
||||
new_add_event('delCommanderSuitLoadout', entry['timestamp'], {'loadoutGameID': entry['LoadoutID']})
|
||||
|
||||
elif event_name == 'RenameSuitLoadout':
|
||||
to_send = {
|
||||
'loadoutGameID': entry['LoadoutID'],
|
||||
'loadoutName': entry['LoadoutName'],
|
||||
# may as well...
|
||||
'suitType': entry['SuitName'],
|
||||
'suitGameID': entry['SuitID']
|
||||
}
|
||||
new_add_event('updateCommanderSuitLoadout', entry['timestamp'], {})
|
||||
|
||||
elif event_name == 'LoadoutEquipModule':
|
||||
to_send = {
|
||||
'loadoutGameID': entry['LoadoutID'],
|
||||
'loadoutName': entry['LoadoutName'],
|
||||
'suitType': entry['SuitName'],
|
||||
'suitGameID': entry['SuitID'],
|
||||
'suitLoadout': [
|
||||
{
|
||||
'slotName': entry['SlotName'],
|
||||
'itemName': entry['ModuleName'],
|
||||
'itemGameID': entry['SuitModuleID'],
|
||||
'itemClass': entry['Class'],
|
||||
'engineering': [{'blueprintName': mod} for mod in entry['WeaponMods']],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
new_add_event('updateCommanderSuitLoadout', entry['timestamp'], to_send)
|
||||
|
||||
elif event_name == "Location":
|
||||
to_send = {
|
||||
'starsystemName': entry['StarSystem'],
|
||||
'starsystemCoords': entry['StarPos'],
|
||||
}
|
||||
|
||||
if entry['Docked']:
|
||||
to_send['stationName'] = entry['StationName']
|
||||
to_send['marketID'] = entry['MarketID']
|
||||
|
||||
if entry['Docked'] and entry['BodyType'] == 'Planet':
|
||||
# we're Docked, but we're not on a Station, thus we're docked at a planetary base of some kind
|
||||
# and thus, we SHOULD include starsystemBodyName
|
||||
to_send['starsystemBodyName'] = entry['Body']
|
||||
|
||||
if 'Longitude' in entry and 'Latitude' in entry:
|
||||
# These were included thus we are landed
|
||||
to_send['starsystemBodyCoords'] = [entry['Latitude'], entry['Longitude']]
|
||||
|
||||
new_add_event('setCommanderTravelLocation', entry['timestamp'], to_send)
|
||||
|
||||
# Community Goals
|
||||
if event_name == 'CommunityGoal':
|
||||
# Remove any unsent
|
||||
@ -1250,7 +1452,7 @@ def new_worker():
|
||||
'appVersion': str(appversion()),
|
||||
'APIkey': creds.api_key,
|
||||
'commanderName': creds.cmdr,
|
||||
'commanderFrontierID': creds.fid
|
||||
'commanderFrontierID': creds.fid,
|
||||
},
|
||||
'events': [
|
||||
{'eventName': e.name, 'eventTimestamp': e.timestamp, 'eventData': e.data} for e in event_list
|
||||
@ -1307,6 +1509,7 @@ def send_data(url: str, data: Mapping[str, Any]) -> bool: # noqa: CCR001
|
||||
:param data: the data to POST
|
||||
:return: success state
|
||||
"""
|
||||
|
||||
r = this.session.post(url, data=json.dumps(data, separators=(',', ':')), timeout=_TIMEOUT)
|
||||
r.raise_for_status()
|
||||
reply = r.json()
|
||||
|
Loading…
x
Reference in New Issue
Block a user