Esempio n. 1
0
    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
Esempio n. 2
0
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')
    ]
Esempio n. 3
0
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')
    ]
Esempio n. 4
0
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'])
Esempio n. 5
0
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'])
Esempio n. 6
0
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)
Esempio n. 7
0
def test_has_keys(d, keys, result):
    assert utils.has_keys(d, *keys) == result
Esempio n. 8
0
@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'],
Esempio n. 9
0
    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)
Esempio n. 10
0
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
                   })
    ]