Exemple #1
0
    async def on_message(self, message: typing.Dict):
        assert message['c'] == 'cmd'
        if message['n'] not in self._enabled_channels:
            LOGGER.core.error('Error, message received on closed channel: %s',
                              message)
            return

        try:
            data = message['d'].strip().split(' ')
            if not data:
                raise TypeError('Empty command?')

            entity = Entity(message['e_id'], itsme=True)
            entity.set_component(SystemComponent(connection=message['n']))

            command = self._commands[data[0].lower()]
            if getattr(command, 'get_self', False):
                await self._commands[data[0]](entity, *data)
            else:
                await self._commands[data[0]](entity, *data[1:])
        except KeyError as exc:
            if settings.RUNNING_TESTS:
                raise
            await self._on_error(message, "Command not found: %s" % data[0])
            LOGGER.core.exception('Unhandled exception %s', exc)
        except TypeError as exc:
            if settings.RUNNING_TESTS:
                raise
            await self._on_error(message, "Command error: %s" % str(exc))
            LOGGER.core.exception('Unhandled exception %s', exc)
        except Exception as exc:
            LOGGER.core.exception('Unhandled exception %s', exc)
            print(exc)
    async def create_character(sid, payload):
        token = auth_service.decode_session_token(payload['token'])
        assert token['context'] == 'world:create'
        system_component = SystemComponent()\
            .instance_of.set('character')\
            .created_at.set(int(time.time()))\
            .receive_events.enable()\
            .user_id.set(token['data']['user_id'])

        attributes = AttributesComponent().name.set(payload['name']).keyword.set('uomo')
        entity = Entity() \
            .set_for_update(system_component) \
            .set_for_update(attributes)

        entity = await world_repository.save_entity(entity)
        """
        URGENT - TODO - FIX - Completely move characters allocation outside of SQL.
        Create a "UserID Component" to pair the character in the ECS with the ecosystem uuid,
        as we do for the connection.
        """
        from core.src.auth.database import init_db, db
        init_db(db)
        character_id = psql_character_repository.store_new_character(
            token['data']['user_id'], payload["name"]
        ).character_id
        try:
            db.close()
        except:
            # FIXME - This shouldn't be here, but we miss the "store_new_character" HTTP endpoint yet.
            pass
        """
        Fix ends here, probably
        """
        redis_characters_index_repository.set_entity_id(character_id, entity.entity_id)
        await sio.emit('create', {'success': True, 'character_id': character_id}, to=sid)
Exemple #3
0
 async def on_message(self, message: typing.Dict):
     entity = Entity(message['e_id'], itsme=True).set_component(
         SystemComponent().connection.set(message['n']))
     if message['c'] == 'connected':
         await self.on_connect(entity)
     elif message['c'] == 'disconnected':
         await self.on_disconnect(entity)
     else:
         raise ValueError('wtf?!')
Exemple #4
0
 async def on_event(self, entity_id: int, message: typing.Dict,
                    room: typing.Tuple, transport_id: str):
     room = PositionComponent(coord='{},{},{}'.format(*room))
     entity = Entity(entity_id).set_component(
         SystemComponent().connection.set(transport_id))
     await load_components(entity, PositionComponent)
     curr_pos = entity.get_component(PositionComponent)
     interest_type = await self._get_message_interest_type(
         entity, room, curr_pos)
     if not interest_type.value:
         return
     await self.publish_event(entity, message, room, interest_type,
                              curr_pos)
Exemple #5
0
async def disconnect_entity(entity: Entity, msg=True):
    from core.src.world.builder import map_repository
    from core.src.world.builder import websocket_channels_service
    from core.src.world.builder import cmds_observer
    events_publisher = get_events_publisher()
    await load_components(entity, PositionComponent)
    listeners = await get_eligible_listeners_for_area(
        entity.get_component(PositionComponent))
    await events_publisher.on_entity_disappear_position(
        entity, entity.get_component(PositionComponent), "disconnect",
        listeners)
    msg and await emit_sys_msg(entity, "event", {"event": "quit"})
    current_channel_id = entity.get_component(SystemComponent).connection.value
    entity.set_for_update(SystemComponent().connection.set(""))
    if await update_entities(entity):
        await map_repository.remove_entity_from_map(
            entity.entity_id, entity.get_component(PositionComponent))
        await websocket_channels_service.close_namespace_for_entity_id(
            entity.entity_id)
        cmds_observer.close_channel(current_channel_id)
    def get_instance_of(self, name: str,
                        entity: Entity) -> typing.Optional[Entity]:
        e = Entity()
        data = self._local_copy.get(name)
        if not data:
            return

        system_component = SystemComponent()\
            .instance_of.set(data['libname'])\
            .created_at.set(int(time.time()))\
            .instance_by.set(entity.entity_id)

        e.set_for_update(system_component)
        for component in data['components']:
            comp_type = get_component_by_type(component)
            if comp_type.has_default:
                e.set_for_update(comp_type().activate())
            else:
                e.set_for_update(
                    comp_type(value=data['components'][component]))
        return e
Exemple #7
0
async def emit_msg(entity, message: str):
    from core.src.world.builder import transport
    from core.src.world.builder import world_repository
    if entity.itsme:
        connection_id = entity.get_component(SystemComponent).connection.value
        assert connection_id
        await transport.send_message(connection_id, message)
        return True
    else:
        if not entity.get_component(SystemComponent) or not entity.get_component(SystemComponent).connection:
            components_data = await world_repository.read_struct_components_for_entity(
                entity.entity_id, (SystemComponent, 'connection')
            )
            connection_id = components_data[SystemComponent.enum].connection.value
            if connection_id:
                entity.set_component(SystemComponent().connection.set(connection_id))
                await transport.send_message(
                    entity.get_component(SystemComponent).connection,
                    message
                )
                return True
    return False
Exemple #8
0
 async def on_connect(self, entity: Entity):
     connection_id = entity.get_component(SystemComponent).connection.value
     self.events_subscriber_service.add_observer_for_entity_id(
         entity.entity_id, self.pubsub_observer)
     await update_entities(
         entity.set_for_update(
             SystemComponent().connection.set(connection_id)))
     await load_components(entity, PositionComponent)
     if not entity.get_component(PositionComponent).coord:
         await cast_entity(entity,
                           get_base_room_for_entity(entity),
                           on_connect=True,
                           reason="connect")
         self.loop.create_task(self.greet(entity))
     else:
         await cast_entity(entity,
                           entity.get_component(PositionComponent),
                           update=False,
                           on_connect=True,
                           reason="connect")
     self.manager.set_transport(entity.entity_id, connection_id)
     self.commands_observer.enable_channel(connection_id)
     self.loop.create_task(look(entity))
     self.loop.create_task(getmap(entity))
 async def bootstrap_subscribes(self, data: typing.List[typing.Dict]):
     for en in data:
         await self.subscribe_events(
             Entity(en['entity_id']).set_component(
                 SystemComponent(connection=en['channel_id'])))
Exemple #10
0
 def get_follow_target(self, follower_id: int):
     response = self._follow_by_follower.get(follower_id)
     return response and Entity(response).set_component(SystemComponent(receive_events=True))