def process_event(self, event: journal.Event, state: GameStateData) -> EDDNSchema: """ Process journal events into journal message """ strip_localized = lambda d: utils.dict_subset( d, *(k for k in d.keys() if not k.endswith('_Localised'))) filter_faction = lambda d: strip_localized( utils.drop_keys(d, 'HappiestSystem', 'HomeSystem', 'MyReputation', 'SquadronFaction')) optional = utils.drop_keys(event.data, "ActiveFine", "CockpitBreach", "BoostUsed", "FuelLevel", "FuelUsed", "JumpDist", "Latitude", "Longitude", "Wanted") optional = strip_localized(optional) if 'StationEconomies' in optional: optional['StationEconomies'] = [ strip_localized(d) for d in optional['StationEconomies'] ] if utils.has_keys(event.data, 'StarPos', 'SystemAddress'): self._starpos_db[ event.data['SystemAddress']] = event.data['StarPos'] star_system = event.data.get('StarSystem', None) or state.location.system system_address = event.data.get('SystemAddress', None) or state.location.address star_pos = event.data.get('StarPos', None) or self._starpos_db.get(system_address or 0, None) \ or state.location.pos if not star_system or not star_pos or not system_address: raise ValueError( 'Got falsy StarPos or StarSystem or SystemAddress') message = JournalMessageSchema( timestamp=utils.to_ed_timestamp(event.timestamp), event=event.name, StarSystem=star_system, StarPos=star_pos, SystemAddress=system_address, Factions=[ filter_faction(f) for f in event.data.get('Factions', []) ], optional=optional, horizons=state.horizons, odyssey=state.odyssey, ) payload_dataclass = EDDNSchema( header=SchemaHeader(uploaderID=state.commander.name or 'unknown', ), schemaRef='https://eddn.edcd.io/schemas/journal/1', message=message) return payload_dataclass
def on_synthesis_event(event: journal.Event) -> List[InaraEvent]: """From journal Synthesis event create inara delCommanderInventoryMaterialsItem events""" return [ InaraEvent(eventName='delCommanderInventoryMaterialsItem', eventTimestamp=event.data['timestamp'], eventData={ 'itemName': material['Name'], 'itemCount': material['Count'] }) for material in event.data.get('Materials', []) if has_keys(material, 'Name', 'Count') ]
def on_mission_complete_event(event: journal.Event) -> List[InaraEvent]: """From journal MissionCompleted event create inara addCommanderInventoryMaterialsItem events""" return [ InaraEvent(eventName='addCommanderInventoryMaterialsItem', eventTimestamp=event.data['timestamp'], eventData={ 'itemName': material['Name'], 'itemCount': material['Count'] }) for material in event.data.get('MaterialsReward', []) if has_keys(material, 'Name', 'Count') ]
def material_discarded_event(event: Event, state: GameStateData): """ Handle MaterialDiscarded journal event Removes material from material storage """ if not has_keys(event.data, 'Category', 'Name', 'Count'): return state.material_storage.remove_material(event.data['Name'], event.data['Count'], event.data['Category'])
def material_collected_event(event: Event, state: GameStateData): """ Handle MaterialCollected journal event Updates material count in material storage """ if not has_keys(event.data, 'Category', 'Name', 'Count'): return state.material_storage.add_material(event.data['Name'], event.data['Count'], event.data['Category'])
def materials_event(event: Event, state: GameStateData): """ Handle Materials journal event Populates material storage """ for category in ['Raw', 'Encoded', 'Manufactured']: for material_data in event.data.get(category, []): # type: ignore if has_keys(material_data, 'Name', 'Count'): state.material_storage.add_material(material_data['Name'], material_data['Count'], category)
def test_has_keys(d, keys, result): assert utils.has_keys(d, *keys) == result
@mutation_registry.register('MaterialDiscarded') def material_discarded_event(event: Event, state: GameStateData): """ Handle MaterialDiscarded journal event Removes material from material storage """ if not has_keys(event.data, 'Category', 'Name', 'Count'): return state.material_storage.remove_material(event.data['Name'], event.data['Count'], event.data['Category']) filter_material = lambda seq: filter(lambda m: has_keys(m, 'Name', 'Count'), seq) @mutation_registry.register('Synthesis') def synthesis_event(event: Event, state: GameStateData): """ Handle Synthesis journal event Removes materials from material storage """ for material in filter_material(event.data.get('Materials', [])): for category in ['Raw', 'Encoded', 'Manufactured']: if material['Name'] in state.material_storage[category]: state.material_storage.remove_material(material['Name'], material['Count'],
def on_capi_market_info_commodities(self, data: dict): """Send commodities eddn message from CAPI market information""" gamestate = get_gamestate() if not gamestate.location.system or not gamestate.location.station.name \ or not gamestate.location.station.market: logger.warning('System and station info not set in gamestate') return commodities: List[Dict[str, Any]] = [] economies: List[Dict[str, Any]] = [] required_fields = [ 'name', 'meanPrice', 'buyPrice', 'stock', 'stockBracket', 'sellPrice', 'demand', 'demandBracket' ] for commodity in data.get('commodities', []): if not utils.has_keys(commodity, *required_fields) or not commodity.get('name') \ or commodity.get('legality') or commodity.get('categoryname') == 'NonMarketable': continue commodity_data = utils.dict_subset(commodity, *required_fields) status_flags: List[Union[int, str]] = list( set(filter(None, commodity.get('statusFlags', [])))) if status_flags: commodity_data['statusFlags'] = status_flags commodities.append(commodity_data) for economy in data.get('economies', {}).values(): name = economy.get('name') proportion = economy.get('proportion') if name and proportion is not None: economies.append({'name': name, 'proportion': proportion}) prohibited = {p for p in data.get('prohibited', {}).values() if p} optional = {} if prohibited: optional['prohibited'] = list(prohibited) message = CommodityMessageSchema( systemName=gamestate.location.system, stationName=gamestate.location.station.name, marketId=gamestate.location.station.market, horizons=gamestate.horizons, timestamp=datetime.datetime.utcnow().isoformat(timespec='seconds') + 'Z', commodities=commodities, economies=economies, optional=optional, odyssey=gamestate.odyssey, ) payload_dataclass = EDDNSchema( header=SchemaHeader(uploaderID=gamestate.commander.name or 'unknown', ), schemaRef='https://eddn.edcd.io/schemas/commodity/3', message=message) response = self.send_payload(payload_dataclass.to_dict()) if 400 <= response.status_code < 500: logger.error(data)
def on_loadout_event(event: journal.Event) -> List[InaraEvent]: """From journal Loadout event create inara setCommanderShip,setCommanderShipLoadout events""" modules = [] for m in event.data.get('Modules', []): d = map_keys(m, Slot='slotName', Item='itemName', Value='itemValue', Health='itemHealth', On='isOn', Priority='itemPriority', AmmoInClip='itemAmmoClip', AmmoInHopper='itemAmmoHopper') if 'Engineering' in m: e = m['Engineering'] d['engineering'] = { "blueprintName": e['BlueprintName'], "blueprintLevel": e['Level'], "blueprintQuality": e['Quality'], "modifiers": [{ "name": mod['Label'], "value": mod['Value'], "originalValue": mod['OriginalValue'], "lessIsGood": bool(mod['LessIsGood']) } for mod in e.get('Modifiers', []) if has_keys( mod, 'Label', 'Value', 'OriginalValue', 'LessIsGood')] } if 'ExperimentalEffect' in e: d['engineering']['experimentalEffect'] = e[ 'ExperimentalEffect'] modules.append(d) return [ InaraEvent(eventName='setCommanderShip', eventTimestamp=event.data['timestamp'], eventData={ 'shipType': event.data['Ship'], 'shipGameID': event.data['ShipID'], 'shipName': event.data['ShipName'], 'shipIdent': event.data['ShipIdent'], 'isCurrentShip': True, **map_keys(event.data, HullValue='shipHullValue', shipModulesValue='ModulesValue', shipRebuyCost='Rebuy') }), InaraEvent(eventName='setCommanderShipLoadout', eventTimestamp=event.data['timestamp'], eventData={ 'shipType': event.data['Ship'], 'shipGameID': event.data['ShipID'], 'shipLoadout': modules }) ]