1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-22 20:00:29 +03:00

Share monitor state with plugins

This commit is contained in:
Jonathan Harris 2017-02-25 18:53:19 +00:00
parent 22de16e505
commit 9c6b9e71f7
6 changed files with 70 additions and 53 deletions

View File

@ -420,7 +420,7 @@ class AppWindow:
self.status['text'] = _("What are you flying?!") # Shouldn't happen
elif monitor.cmdr and data['commander']['name'] != monitor.cmdr:
raise companion.CmdrError() # Companion API return doesn't match Journal
elif (auto_update and not data['commander'].get('docked')) or (monitor.system and data['lastSystem']['name'] != monitor.system) or (monitor.shipid and data['ship']['id'] != monitor.shipid) or (monitor.shiptype and data['ship']['name'].lower() != monitor.shiptype):
elif (auto_update and not data['commander'].get('docked')) or (monitor.system and data['lastSystem']['name'] != monitor.system) or (monitor.state['ShipID'] and data['ship']['id'] != monitor.state['ShipID']) or (monitor.state['ShipType'] and data['ship']['name'].lower() != monitor.state['ShipType']):
raise companion.ServerLagging()
else:
@ -431,9 +431,9 @@ class AppWindow:
h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8'))
self.ship['text'] = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name'])
if not monitor.shiptype: # Started game in SRV or fighter
monitor.shipid = data['ship']['id']
monitor.shiptype = data['ship']['name'].lower()
if not monitor.state['ShipType']: # Started game in SRV or fighter
monitor.state['ShipID'] = data['ship']['id']
monitor.state['ShipType'] = data['ship']['name'].lower()
if not monitor.system:
self.system['text'] = data['lastSystem']['name']
self.system['image'] = ''
@ -503,8 +503,9 @@ class AppWindow:
if config.getint('output') & config.OUT_SYS_EDSM:
try:
if data['commander'].get('credits') is not None:
monitor.credits = (data['commander']['credits'], data['commander'].get('debt', 0))
self.edsm.setcredits(monitor.credits)
monitor.state['Credits'] = data['commander']['credits']
monitor.state['Loan'] = data['commander'].get('debt', 0)
self.edsm.setcredits(monitor.state['Credits'], monitor.state['Loan'])
ship = companion.ship(data)
if ship == self.edsm.lastship:
props = []
@ -515,14 +516,14 @@ class AppWindow:
('linkToCoriolis', coriolis.url(data)),
('linkToEDShipyard', edshipyard.url(data)),
]
if monitor.shippaint is None:
if monitor.state['PaintJob'] is None:
# Companion API server can lag, so prefer Journal. But paintjob only reported in Journal on change.
monitor.shipid = data['ship']['id']
monitor.shiptype = data['ship']['name'].lower()
monitor.shippaint = data['ship']['modules']['PaintJob'] and data['ship']['modules']['PaintJob']['module']['name'].lower() or ''
props.append(('paintJob', monitor.shippaint))
monitor.state['ShipID'] = data['ship']['id']
monitor.state['ShipType'] = data['ship']['name'].lower()
monitor.state['PaintJob'] = data['ship']['modules']['PaintJob'] and data['ship']['modules']['PaintJob']['module']['name'].lower() or ''
props.append(('paintJob', monitor.state['PaintJob']))
if props:
self.edsm.updateship(monitor.shipid, monitor.shiptype, props)
self.edsm.updateship(monitor.state['ShipID'], monitor.state['ShipType'], props)
self.edsm.lastship = ship
except Exception as e:
# Not particularly important so silent on failure
@ -580,7 +581,7 @@ class AppWindow:
# Update main window
self.cmdr['text'] = monitor.cmdr and monitor.group and ' / '.join([monitor.cmdr, monitor.group]) or monitor.cmdr or ''
self.ship['text'] = monitor.shiptype and companion.ship_map.get(monitor.shiptype, monitor.shiptype) or ''
self.ship['text'] = monitor.state['ShipType'] and companion.ship_map.get(monitor.state['ShipType'], monitor.state['ShipType']) or ''
self.station['text'] = monitor.station or (EDDB.system(monitor.system) and self.STATION_UNDOCKED or '')
if system_changed or station_changed:
self.status['text'] = ''
@ -601,26 +602,26 @@ class AppWindow:
# Send credits to EDSM on new game (but not on startup - data might be old)
if entry['event'] == 'LoadGame':
self.edsm.setcredits(monitor.credits)
self.edsm.setcredits(monitor.state['Credits'], monitor.state['Loan'])
# Send rank info to EDSM on startup or change
if entry['event'] in ['StartUp', 'Progress', 'Promotion'] and monitor.ranks:
self.edsm.setranks(monitor.ranks)
if entry['event'] in ['StartUp', 'Progress', 'Promotion'] and monitor.state['Rank']:
self.edsm.setranks(monitor.state['Rank'])
# Send ship info to EDSM on startup or change
if entry['event'] in ['StartUp', 'LoadGame', 'ShipyardNew', 'ShipyardSwap'] and monitor.shipid:
self.edsm.setshipid(monitor.shipid)
self.edsm.updateship(monitor.shipid, monitor.shiptype, monitor.shippaint and [('paintJob', monitor.shippaint)] or [])
if entry['event'] in ['StartUp', 'LoadGame', 'ShipyardNew', 'ShipyardSwap'] and monitor.state['ShipID']:
self.edsm.setshipid(monitor.state['ShipID'])
self.edsm.updateship(monitor.state['ShipID'], monitor.state['ShipType'], monitor.state['PaintJob'] is not None and [('paintJob', monitor.state['PaintJob'])] or [])
elif entry['event'] in ['ShipyardBuy', 'ShipyardSell']:
self.edsm.sellship(entry.get('SellShipID'))
# Send paintjob info to EDSM on change
if entry['event'] in ['ModuleBuy', 'ModuleSell'] and entry['Slot'] == 'PaintJob':
self.edsm.updateship(monitor.shipid, monitor.shiptype, [('paintJob', monitor.shippaint)])
self.edsm.updateship(monitor.state['ShipID'], monitor.state['ShipType'], [('paintJob', monitor.state['PaintJob'])])
# Write EDSM log on change
if monitor.mode and entry['event'] in ['Location', 'FSDJump']:
self.edsm.writelog(timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), monitor.system, monitor.coordinates, monitor.shipid)
self.edsm.writelog(timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), monitor.system, monitor.coordinates, monitor.state['ShipID'])
except Exception as e:
if __debug__: print_exc()
@ -647,7 +648,7 @@ class AppWindow:
return # Startup or in CQC
# Plugins
plug.notify_journal_entry(monitor.cmdr, monitor.system, monitor.station, entry)
plug.notify_journal_entry(monitor.cmdr, monitor.system, monitor.station, entry, monitor.state)
if system_changed: # Backwards compatibility
plug.notify_system_changed(timegm(strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')), monitor.system, monitor.coordinates)

View File

@ -77,10 +77,12 @@ Your events all get called on the main tkinter loop so be sure not to block for
### Journal Entry
This gets called when EDMC sees a new entry in the game's journal. A special 'StartUp' event is sent when EDMC is started while the game is already running.
This gets called when EDMC sees a new entry in the game's journal. `state` is a dictionary containing information about the Cmdr and their ship and cargo (including the effect of the current journal entry).
A special 'StartUp' entry is sent if EDMC 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 reflect the cumulative effect of these missed events.
```
def journal_entry(cmdr, system, station, entry):
def journal_entry(cmdr, system, station, entry, state):
if entry['event'] == 'FSDJump':
# We arrived at a new system!
if 'StarPos' in entry:

View File

@ -206,9 +206,9 @@ class EDSM:
if args:
self.call('api-commander-v1/set-ranks', args)
def setcredits(self, credits):
if credits:
self.call('api-commander-v1/set-credits', '&balance=%d&loan=%d' % credits)
def setcredits(self, balance, loan):
if balance is not None:
self.call('api-commander-v1/set-credits', '&balance=%d&loan=%d' % (balance, loan))
def setshipid(self, shipid):
if shipid is not None:

View File

@ -86,15 +86,20 @@ class EDLogs(FileSystemEventHandler):
self.mode = None
self.group = None
self.cmdr = None
self.shipid = None
self.shiptype = None
self.shippaint = None
self.body = None
self.system = None
self.station = None
self.coordinates = None
self.ranks = None
self.credits = None
# Cmdr state shared with EDSM and plugins
self.state = {
'Credits' : None,
'Loan' : None,
'PaintJob' : None,
'Rank' : { 'Combat': None, 'Trade': None, 'Explore': None, 'Empire': None, 'Federation': None, 'CQC': None },
'ShipID' : None,
'ShipType' : None,
}
def set_callback(self, name, callback):
if name in self.callbacks:
@ -251,29 +256,32 @@ class EDLogs(FileSystemEventHandler):
self.cmdr = entry['Commander']
self.mode = entry.get('GameMode') # 'Open', 'Solo', 'Group', or None for CQC
self.group = entry.get('Group')
self.shiptype = 'Ship' in entry and entry['Ship'] not in ['TestBuggy', 'Empire_Fighter', 'Federation_Fighter', 'Independent_Fighter'] and entry['Ship'].lower() or None # None in CQC. TestBuggy or *_Fighter if game starts in SRV/fighter.
self.shipid = self.shiptype and entry.get('ShipID') or None # None in CQC
self.shippaint = None
self.state = {
'Credits' : entry['Credits'],
'Loan' : entry['Loan'],
'PaintJob' : None,
'Rank' : { 'Combat': None, 'Trade': None, 'Explore': None, 'Empire': None, 'Federation': None, 'CQC': None },
'ShipID' : entry.get('ShipID') if entry.get('Ship') not in ['TestBuggy', 'Empire_Fighter', 'Federation_Fighter', 'Independent_Fighter'] else None # None in CQC or if game starts in SRV/fighter
}
self.state['ShipType'] = self.state['ShipID'] and entry.get('Ship').lower()
self.body = None
self.system = None
self.station = None
self.coordinates = None
self.ranks = { "Combat": None, "Trade": None, "Explore": None, "Empire": None, "Federation": None, "CQC": None }
self.credits = ( entry['Credits'], entry['Loan'] )
elif entry['event'] == 'NewCommander':
self.cmdr = entry['Name']
self.group = None
elif entry['event'] == 'ShipyardNew':
self.shipid = entry['NewShipID']
self.shiptype = entry['ShipType'].lower()
self.shippaint = None
self.state['ShipID'] = entry['NewShipID']
self.state['ShipType'] = entry['ShipType'].lower()
self.state['PaintJob'] = None
elif entry['event'] == 'ShipyardSwap':
self.shipid = entry['ShipID']
self.shiptype = entry['ShipType'].lower()
self.shippaint = None
self.state['ShipID'] = entry['ShipID']
self.state['ShipType'] = entry['ShipType'].lower()
self.state['PaintJob'] = None
elif entry['event'] in ['ModuleBuy', 'ModuleSell'] and entry['Slot'] == 'PaintJob':
symbol = re.match('\$(.+)_name;', entry.get('BuyItem', ''))
self.shippaint = symbol and symbol.group(1).lower() or entry.get('BuyItem', '')
self.state['PaintJob'] = symbol and symbol.group(1).lower() or entry.get('BuyItem', '')
elif entry['event'] in ['Undocked']:
self.station = None
elif entry['event'] in ['Location', 'FSDJump', 'Docked']:
@ -289,14 +297,15 @@ class EDLogs(FileSystemEventHandler):
self.body = entry.get('BodyType') == 'Planet' and entry.get('Body')
elif entry['event'] == 'SupercruiseEntry':
self.body = None
elif entry['event'] in ['Rank', 'Promotion'] and self.ranks:
elif entry['event'] in ['Rank', 'Promotion']:
for k,v in entry.iteritems():
if k in self.ranks:
self.ranks[k] = (v,0)
elif entry['event'] == 'Progress' and self.ranks:
if k in self.state['Rank']:
self.state['Rank'][k] = (v,0)
elif entry['event'] == 'Progress':
for k,v in entry.iteritems():
if self.ranks.get(k) is not None:
self.ranks[k] = (self.ranks[k][0], min(v, 100)) # perhaps not taken promotion mission yet
if self.state['Rank'].get(k) is not None:
self.state['Rank'][k] = (self.state['Rank'][k][0], min(v, 100)) # perhaps not taken promotion mission yet
return entry
except:
if __debug__:

View File

@ -101,13 +101,14 @@ def notify_prefs_changed():
print plugerr
def notify_journal_entry(cmdr, system, station, entry):
def notify_journal_entry(cmdr, system, station, entry, state):
"""
Send a journal entry to each plugin.
:param cmdr: The Cmdr name, or None if not yet known
:param system: The current system, or None if not yet known
:param station: The current station, or None if not docked or not yet known
:param entry: The journal entry as a dictionary
:param state: A dictionary containing info about the Cmdr, current ship and cargo
:return:
"""
for plugname in PLUGINS:
@ -115,7 +116,10 @@ def notify_journal_entry(cmdr, system, station, entry):
if journal_entry:
try:
# Pass a copy of the journal entry in case the callee modifies it
journal_entry(cmdr, system, station, dict(entry))
if journal_entry.func_code.co_argcount == 4:
journal_entry(cmdr, system, station, dict(entry))
else:
journal_entry(cmdr, system, station, dict(entry), dict(state))
except Exception as plugerr:
print plugerr

View File

@ -46,13 +46,14 @@ def plugin_app(parent):
return plugin_app.status
def journal_entry(cmdr, system, station, entry):
def journal_entry(cmdr, system, station, entry, state):
"""
E:D client made a journal entry
:param cmdr: The Cmdr name, or None if not yet known
:param system: The current system, or None if not yet known
:param station: The current station, or None if not docked or not yet known
:param entry: The journal entry as a dictionary
:param state: A dictionary containing info about the Cmdr, current ship and cargo
:return:
"""
if entry['event'] == 'FSDJump':