示例#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
示例#2
0
def on_reputation_event(event: journal.Event) -> InaraEvent:
    """From journal Reputation event create inara setCommanderReputationMajorFaction event"""
    return InaraEvent(
        eventName='setCommanderReputationMajorFaction',
        eventTimestamp=event.data['timestamp'],
        eventData=[{
            'majorfactionName': k,
            'majorfactionReputation': v / 100
        } for k, v in dict_subset(event.data, 'Empire', 'Federation',
                                  'Alliance').items()])
示例#3
0
def on_statistict_event(event: journal.Event) -> InaraEvent:
    """From journal Statistics event create inara setCommanderGameStatistics event"""
    return InaraEvent(eventName='setCommanderGameStatistics',
                      eventTimestamp=event.data['timestamp'],
                      eventData=dict_subset(event.data, 'Combat',
                                            'Bank_Account', 'Crime',
                                            'Smuggling', 'Trading', 'Mining',
                                            'Exploration', 'Passengers',
                                            'Search_And_Rescue', 'Crafting',
                                            'Crew', 'Multicrew'))
示例#4
0
def on_rank_event(event: journal.Event) -> InaraEvent:
    """From journal Rank event create inara setCommanderRankPilot event"""
    rank_keys = ('Combat', 'Trade', 'Explore', 'Empire', 'Federation', 'CQC')

    return InaraEvent(
        eventName='setCommanderRankPilot',
        eventTimestamp=event.data['timestamp'],
        eventData=[{
            'rankName': k,
            'rankValue': v
        } for k, v in dict_subset(event.data, *rank_keys).items()])
示例#5
0
    def _handshake(self) -> bool:
        """Do a handshake routine. Return True if successful"""
        ret_op, ret_data = self.request({
            'v': 1,
            'client_id': self._client_id
        },
                                        op=RPC_OP.OP_HANDSHAKE)

        if RPC_OP(ret_op) is RPC_OP.OP_FRAME and \
                dict_subset(ret_data, 'cmd', 'evt') == {'cmd': 'DISPATCH', 'evt': 'READY'}:
            return True

        if RPC_OP(ret_op) is RPC_OP.OP_CLOSE:
            self.close()
            return False

        return False
示例#6
0
def test_subset(d, k, result):
    assert utils.dict_subset(d, *k) == result
示例#7
0
def test_subset_strict(d, k, result, raises):
    if not raises:
        assert utils.dict_subset(d, *k, strict=True) == result
    else:
        with pytest.raises(KeyError):
            assert utils.dict_subset(d, *k, strict=True)
示例#8
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)