예제 #1
0
    def __init__(self, character_id, connection):
        self._character_manager = CharacterManager()
        self._room_manager = RoomManager()
        self._portal_manager = PortalManager()

        self._character_id = character_id
        self._connection = connection
예제 #2
0
 def __validate_name(self, name):
   character_manager = CharacterManager()
   if re.match('^[a-zA-Z]+$', name) is None:
     self._connection.send_line('<$red>Character names must contain only letters!')
     return False
   elif character_manager.find_by_name(name):
     self._connection.send_line('<$red>Character already exists!')
     return False
   return True
예제 #3
0
    def __init__(self):
      # Time is in milliseconds
      self._last_query_time = None
      self._running_time = 0

      self._timer_registry = queue.PriorityQueue()

      self._region_manager = RegionManager()
      self._room_manager = RoomManager()
      self._portal_manager = PortalManager()
      self._character_manager = CharacterManager()
      self._item_manager = ItemManager()
      self._command_manager = CommandManager()

      self._connected_characters = []
예제 #4
0
class GameHandler(Handler):
    def __init__(self, connection, account, character_id):
        super().__init__(connection)
        self._account = account
        self._character_id = character_id
        self._game_manager = GameManager()
        self._character_manager = CharacterManager()

    def enter(self):
        character = self._character_manager.get_character(self._character_id)
        character.add_existing_logic(
            TelnetReporter(self._character_id, self._connection))

        self._game_manager.do_action(
            Action('enterrealm', character_id=self._character_id))
        character.do_action(
            Action('seeroom',
                   character_id=self._character_id,
                   room_id=character.room_id))
        # self.prompt()

    def hang_up(self):
        self._connection.send(vt100.newline + vt100.bg_magenta + 'Goodbye!' +
                              vt100.newline)

    def handle(self, cmd_string):
        self._game_manager.do_action(
            Action('command',
                   character_id=self._character_id,
                   data={'cmd': cmd_string.strip()}))
예제 #5
0
class CharacterMenuHandler(Handler):
    def __init__(self, connection, account, character_id):
        super().__init__(connection)
        self._account = account
        self._character_id = character_id
        self._character_manager = CharacterManager()

    def enter(self):
        self._connection.send_line('<$nl>')
        self.__print_menu()
        self.__prompt()

    def hang_up(self):
        self._connection.send_line('<$nl>Goodbye!<$nl>')

    def handle(self, cmd):
        if not cmd:
            self._connection.leave_handler()
        elif cmd == '1':
            self._connection.enter_handler(
                GameHandler(self._connection, self._account,
                            self._character_id))
        elif cmd == '2':
            #TODO How to delete a character that is referenced by other objects (such as rooms)?
            self.__prompt()
        elif cmd.lower()[:1] == 'q':
            self._connection.hang_up()
        else:
            self._connection.send_line('<$nl><$red>Invalid option!<$nl>')
            self.__print_menu()
            self.__prompt()

    def __print_menu(self):
        character = self._character_manager.get_character(self._character_id)
        self._connection.send_line(
            'You are currently connected to account: {0}'.format(
                self._account.name))
        self._connection.send_line(
            'You are currently connected to character: {0}'.format(
                character.name))
        menu = """
<$nl>
Character Menu<$nl>
-------------------------------<$nl>
<$nl>
1) Enter the game<$nl>
2) Delete this character <$green>#TODO<$nl>
Q) Quit the game<$nl>
"""
        menu = menu.replace('\n', '')
        self._connection.send_line(menu)

    def __prompt(self):
        self._connection.send('Make your selection: ')
예제 #6
0
class SelectCharacterHandler(Handler):
  def __init__(self, connection, account):
    super().__init__(connection)
    self._character_manager = CharacterManager()
    self._account = account
    self._character_list = []

  def enter(self):
    self._connection.send_blank_line()
    self.__print_menu()
    self.__prompt()

  def handle(self, cmd):
    if not cmd:
      self._connection.leave_handler()
    elif cmd.isdigit() and int(cmd) in range(1,len(self._character_list)+1):
      character = self._character_list[int(cmd)-1]
      if character.logged_in:
        self._connection.send_line('<$nl><$red>That character is already logged in!<$nl>')
        self.__print_menu()
        self.__prompt()
      else:
        self._connection.send_blank_line()
        self._connection.switch_handler(CharacterMenuHandler(self._connection, self._account, character.id))
    else:
      self._connection.send_line('<$nl><$red>Invalid option!<$nl>')
      self.__print_menu()
      self.__prompt()

  def __print_menu(self):
    if not self._character_list:
      self.__load_characters()

    self._connection.send_line('You are currently connected to account: {0}'.format(self._account.name))
    menu = """
<$nl>
Your Characters<$nl>
-------------------------------<$nl>
<$nl>"""
    for i in range(len(self._character_list)):
      color = '<$reset>'
      if self._character_list[i].logged_in:
        color = '<$red>'
      menu = menu + '{0}{1}) {2}<$nl>'.format(color, i+1, self._character_list[i].name)
    menu = menu.replace('\n', '')
    self._connection.send_line(menu)

  def __prompt(self):
    self._connection.send('Select a character: ')

  def __load_characters(self):
    characters = self._character_manager.find_by_account(self._account.id)
    for character in characters:
      self._character_list.append(character)
예제 #7
0
  def __setup(self):
    template_id = '5b76f8022ac515cffe5064db'
    character_manager = CharacterManager()
    template = character_manager.get_template(template_id)
    if not template:
      logging.error('Template "{0}" does not exist!'.format(template_id))
      self._connection.send_line('<$red>Error: unable to read template')
      self.__prompt()
      return
    character = Character()
    character.from_template(template)
    character.name = self._character_name
    character.account_id = self._account.id
    character.room_id = '5b7721032ac5150455940919'
    character.region_id = '5b71e3dc2ac51580c8d6baa6'

    character.add_command('look')
    character.add_command('quit')
    character.add_command('who')
    character.add_command('gossip')
    character.add_command('go')

    character.save()
예제 #8
0
  class __GameManager(object):
# ----------------------------------------------------------------------
    def __init__(self):
      # Time is in milliseconds
      self._last_query_time = None
      self._running_time = 0

      self._timer_registry = queue.PriorityQueue()

      self._region_manager = RegionManager()
      self._room_manager = RoomManager()
      self._portal_manager = PortalManager()
      self._character_manager = CharacterManager()
      self._item_manager = ItemManager()
      self._command_manager = CommandManager()

      self._connected_characters = []

    def get_connected_characters(self):
      return self._connected_characters

    def __update_time(self):
      if self._last_query_time:
        current_time = self.__system_time_ms()
        self._running_time = self._running_time + (current_time - self._last_query_time)

      self._last_query_time = current_time

    def __system_time_ms(self):
      return int(round(time.time() * 1000))

    def get_time(self):
      self.__update_time()
      return self._running_time

    def reset_time(self):
      self.__update_time()
      self._running_time = 0

    def __add_timed_action(self, timed_action):
      if isinstance(timed_action, TimedAction):
        self._timer_registry.put(timed_action)

    # def add_action_relative(self, relative_time_ms, action_type, entities, data_string):
    #   action = Action(action_type, entities, data_string)
    #   self.add_action_relative(relative_time_ms, action)

    def add_action_relative(self, relative_time_ms, action):
      self.add_action_absolute(self.__system_time_ms() + relative_time_ms, action)

    # def add_action_absolute(self, absolute_time_ms, action_type, entities, data_string):
    #   action = Action(action_type, entities, data_string)
    #   self.add_action_absolute(absolute_time_ms, action)

    def add_action_absolute(self, absolute_time_ms, action):
      timed_action = TimedAction(self.__system_time_ms(), action)
      self.__add_timed_action(timed_action)

    def execute_timed_actions(self):
      current_time = self.__system_time_ms()

      while not self._timer_registry.empty():
        timed_action = self._timer_registry.get()
        if timed_action.get_execution_time() > current_time:
          self._timer_registry.put(timed_action)
          break

        if timed_action.valid:
          self.do_action(timed_action.get_action())
      asyncio.get_event_loop().call_later(.1, self.execute_timed_actions)

    def do_action(self, action):
      # logging.info('Game recieved action: ' + action.action_type)
      if action.action_type == 'chat' or action.action_type == 'announce':
        self.__action_to_realm_players(action)
      elif action.action_type == "do":
        self.__route_action(action)
      elif action.action_type == 'modifyattribute':
        self.__modify_attribute(action)
      elif  action.action_type == 'vision':
        self.__action_to_room_characters(action, action.room_id)
      elif action.action_type == 'enterrealm':
        self.__login(action.character_id)
      elif action.action_type == 'leaverealm':
        self.__logout(action.character_id)
      elif action.action_type == 'attemptsay':
        self.__say(action.character_id, action.data['msg'])
      elif action.action_type == 'command':
        self.__do_command(action.character_id, action.data['cmd'])
      elif action.action_type == 'attemptenterportal':
        self.__enter_portal(action.character_id, action.portal_id, action.data['direction'])
      elif action.action_type == 'attemptseethroughportal':
        self.__see_through_portal(action.character_id, action.portal_id, action.data['direction'])
      elif action.action_type == 'attempttransport':
        self.__transport(action.character_id, action.room_id)
      elif action.action_type == 'forcetransport':
        self.__transport(action.character_id, action.room_id, force=True)
      # elif action.action_type == 'attemptgetitem':
      #   self.__get_item(action.character_id, action.item_id, action.quantity) # TODO
      # elif action.action_type == 'attemptdropitem':
      #   self.__drop_item(action.character_id, action.item_id, action.quantity) # TODO
      # elif action.action_type ==  'attemptgiveitem':
      #   self.__give_item(action.character_id, action.other_character_id, action.item_id, action.quantity) # TODO
      # elif action.action_type == 'spawnitem':
      #   self.__spawn_item(action.template_id, action.room_id, action.character_id, action.quantity) # TODO
      # elif action.action_type == 'spawncharacter':
      #   self.__spawn_character(action.template_id, action.room_id) # TODO
      # elif action.action_type == 'destroyitem':
      #   self.__destroy_item(action.item_id) # TODO
      # elif action.action_type == 'destroycharacter':
      #   self.__destroy_character(action.character_id) # TODO
      # elif action.action_type == 'cleanup':
      #   self.__cleanup() # TODO
      # elif action.action_type == 'savedatabases':
      #   self.__save_all() # TODO
      # elif action.action_type == 'saveregion':
      #   self.__save_region(action.region_id) # TODO
      # elif action.action_type == 'saveplayers':
        # self.__save_players() # TODO
      # elif action.action_type == 'reloaditems':
      #   self.__reload_item_templates(action.data) # TODO
      # elif action.action_type == 'reloadcharacter':
      #   self.__reload_character_templates(action.data) # TODO
      elif action.action_type == 'reloadregion':
        self.__reload_region(action.data) # TODO
      elif action.action_type == 'reloadcommandscript':
        self.__reload_command_script(action.data) # TODO
      elif action.action_type == 'reloadlogicscript':
        self.__reload_logic_script(action.data) # TODO
      # elif action.action_type == 'messagelogic':
      #   self.__logic_action(action) # TODO
      # elif action.action_type == 'addlogic':
      #   self.__add_logic(action) # TODO
      # elif action.action_type == 'removelogic':
      #   self.__remove_logic(action) # TODO

    def __load_all(self):
      # Is this necesary if the managers load data dynamically from the database?
      pass # TODO

    def __load_timers(self):
      pass # TODO

    def __reload_item_templates(self):
      pass # TODO

    def __reload_charater_templates(self):
      pass # TODO

    def __reload_region(self, name):
      pass # TODO

    def __reload_command_script(self, name):
      pass # TODO

    def __reload_logic_script(self, name):
      pass # TODO

    def __save_all(self):
      pass # TODO

    def __save_players(self):
      pass # TODO

    def save_region(self, region_id):
      pass # TODO

    def __save_timers(self):
      pass # TODO

    def __clean_up(self):
      pass # TODO

    def __transport(self, character_id, room_id, force=False):
      character = self._character_manager.get_character(character_id)
      old_room = self._room_manager.get_room(character.room_id)
      new_room = self._room_manager.get_room(room_id)
      old_region = self._region_manager.get_region(old_room.region_id)
      new_region = self._region_manager.get_region(new_room.region_id)
      changing_regions = old_region.id != new_region.id


      # "ask permission" from the actors to perform the actions
      if not force:
        if changing_regions:
          if old_region.do_action(Action('canleaveregion', character_id=character.id)):
            return

          if new_region.do_action(Action('canenterregion', character_id=character.id)):
            return

          if character.do_action(Action('canleaveregion', region_id=old_region.id)):
            return

          if character.do_action(Action('canenterregion', region_id=new_region.id)):
            return

        if old_room.do_action(Action('canleaveroom', character_id=character.id)):
          return

        if new_room.do_action(Action('canenterroom', character_id=character.id)):
          return

        if character.do_action(Action('canleaveroom', room_id=old_room.id)):
          return

        if character.do_action(Action('canenterroom', room_id=new_room.id)):
          return

      # Move the character
      if changing_regions:
        old_region.remove_character(character.id)
        character.region_id = new_region.id
        new_region.add_character(character.id)

      old_room.remove_character(character.id)
      character.room_id = new_room.id
      new_room.add_character(character.id)

      # Notify actors that the event is complete
      if changing_regions:
        old_region.do_action(Action('leaveregion', character_id=character.id))
        character.do_action(Action('leaveregion', region_id=old_region.id))

      action = Action('leaveroom', character_id=character.id, room_id=old_room.id)
      old_room.do_action(action)
      character.do_action(action)
      self.__action_to_room_characters(action, old_room.id)
      self.__action_to_room_items(action, old_room.id)

      if changing_regions:
        action = Action('enterregion', character_id=character.id, room_id=new_region.id)
        new_region.do_action(action)
        character.do_action(action)

      action = Action('enterroom', character_id=character.id, room_id=new_room.id)
      new_room.do_action(action)
      self.__action_to_room_characters(action, new_room.id)
      self.__action_to_room_items(action, new_room.id)

    def __action_to_room_characters(self, action, room_id):
      room = self._room_manager.get_room(room_id)

      for character_id in room.character_ids:
        character = self._character_manager.get_character(character_id)
        if character:
          character.do_action(action)
        else:
          logging.error('do_action() error: character_id "{0}" not found!'.format(character_id))

    def __action_to_room_items(self, action, room_id):
      room = self._room_manager.get_room(room_id)

      for item_id in room.item_ids:
        item = self._item_manager.get_item(item_id)
        item.do_action(action)

    def __action_to_realm_players(self, action):
      for character in self._connected_characters:
        character.do_action(action)

    def __route_action(self, action):
      entity = self.__get_entity_from_action(action)

      if entity:
        entity.do_action(action)

    def __modify_attribute(self, action):
      entity = self.__get_entity_from_action(action)

      if entity:
        for key in action.data:
          entity.data[key] = action.data[key]

    def __get_entity_from_action(self, action):
      entity = None
      if action.target_type == EntityType.REGION:
        entity = self._region_manager.get_region(action.region_id)
      elif action.target_type == EntityType.ROOM:
        entity = self._room_manager.get_room(action.room_id)
      elif action.target_type == EntityType.PORTAL:
        entity = self._portal_manager.get_portal(action.portal_id)
      elif action.target_type == EntityType.CHARACTER:
        entity = self._character_manager.get_character(action.character_id)
      elif action.target_type == EntityType.ITEM:
        entity = self._item_manager.get_item(action.item_id)

      return entity

    def __login(self, character_id):
      character = self._character_manager.get_character(character_id)
      room = self._room_manager.get_room(character.room_id)
      region = self._region_manager.get_region(room.region_id)

      character.logged_in = True
      self._connected_characters.append(character)
      room.add_character(character_id)
      region.add_character(character_id)

      self.__action_to_realm_players(Action('enterrealm', character_id=character.id))
      region.do_action(Action('enterregion', character_id=character.id))
      character.do_action(Action('enterregion', character_id=character.id))
      room.do_action(Action('enterroom', character_id=character.id))
      self.__action_to_room_characters(Action('enterroom', character_id=character.id), room.id)
      self.__action_to_room_items(Action('enterroom', character_id=character.id), room.id)

    def __logout(self, character_id):
      character = self._character_manager.get_character(character_id)
      room = self._room_manager.get_room(character.room_id)
      region = self._region_manager.get_region(room.region_id)

      self.__action_to_room_items(Action('leaveroom', character_id=character.id), room.id)
      self.__action_to_room_characters(Action('leaveroom', character_id=character.id), room.id)
      room.do_action(Action('leaveroom', character_id=character.id))
      character.do_action(Action('leaveregion', character_id=character.id))
      region.do_action(Action('leaveregion', character_id=character.id))
      self.__action_to_realm_players(Action('leaverealm', character_id=character.id))

      room.remove_character(character)
      region.remove_character(character)
      self._connected_characters.remove(character)
      character.logged_in = False

    def __say(self, character_id, msg):
      character = self._character_manager.get_character(character_id)
      room = self._room_manager.get_room(character.room_id)
      region = self._region_manager.get_region(room.region_id)

      # ask permission
      action = Action('cansay', character_id=character.id, data={msg: msg})
      if character.do_action(action):
        return
      if room.do_action(action):
        return
      if region.do_action(action):
        return

      # Event notifications
      action = Action('say', character_id=character.id, data={msg: msg})
      self.__action_to_room_characters(action, room.id)
      room.do_action(action)
      region.do_action(action)

    def __enter_portal(self, character_id, portal_id, direction: str):
      character = self._character_manager.get_character(character_id)
      portal = self._portal_manager.get_portal(portal_id)
      old_room = self._room_manager.get_room(character.room_id)

      path = portal.find_path_from(old_room.id, direction)

      new_room = self._room_manager.get_room(path.end_room_id)
      old_region = self._region_manager.get_region(old_room.region_id)
      new_region = self._region_manager.get_region(new_room.region_id)
      changing_regions = (old_region.id != new_region.id)

      # Ask permission
      if changing_regions:
        action = Action('canleaveregion', character_id=character.id, region_id=old_region.id)
        if old_region.do_action(action):
          return
        if character.do_action(action):
          return

        action = Action('canenterregion', character_id=character.id, region_id=old_region.id)
        if new_region.do_action(action):
          return
        if character.do_action(action):
          return

      action = Action('canleaveroom', character_id=character.id, room_id=old_room.id)
      if old_room.do_action(action):
        return
      if character.do_action(action):
        return

      action = Action('canenterroom', character_id=character.id, room_id=new_room.id)
      if new_room.do_action(action):
        return
      if character.do_action(action):
        return

      if portal.do_action(Action('canenterportal', character_id=character.id, data={'direction': direction})):
        return

      # tell the room that the player is leaving
      if changing_regions:
        action = Action('leaveregion', character_id=character.id, region_id=old_region.id)
        old_region.do_action(action)
        character.do_action(action)

      action = Action('leaveroom', character_id=character.id, portal_id=portal.id, room_id=old_room.id, data={'path': path})
      self.__action_to_room_characters(action, old_room.id)
      self.__action_to_room_items(action, old_room.id)
      old_room.do_action(action)

      # tell the portal that the player has actually entered
      action = Action('enterportal', character_id=character.id, portal_id=portal)
      portal.do_action(action)
      character.do_action(action)

      # actually move the character
      if changing_regions:
        old_region.remove_character(character.id)
        character.region_id = new_region.id
        new_region.add_character(character.id)

      old_room.remove_character(character.id)
      character.room_id = new_room.id
      new_room.add_character(character.id)

      # tell everyone in the room that the player has entered
      if changing_regions:
        action = Action('enterregion', character_id=character.id, region_id=new_region.id)
        new_region.do_action(action)
        character.do_action(action)

      action = Action('enterroom', character_id=character.id, portal_id=portal.id, room_id=new_room.id, data={'path': path})
      new_room.do_action(action)
      self.__action_to_room_characters(action, new_room.id)
      self.__action_to_room_items(action, new_room.id)

    def __see_through_portal(self, character_id: str, portal_id: str, direction: str):
      character = self._character_manager.get_character(character_id)
      portal = self._portal_manager.get_portal(portal_id)
      old_room = self._room_manager.get_room(character.room_id)

      path = portal.find_path_from(old_room.id, direction)

      new_room = self._room_manager.get_room(path.end_room_id)
      old_region = self._region_manager.get_region(old_room.region_id)
      new_region = self._region_manager.get_region(new_room.region_id)
      changing_regions = (old_region.id != new_region.id)

      # Ask permission
      if changing_regions:
        action = Action('canseeregion', character_id=character.id, region_id=old_region.id)
        if old_region.do_action(action):
          return
        if character.do_action(action):
          return

      action = Action('canseeroom', character_id=character.id, room_id=new_room.id)
      if new_room.do_action(action):
        return
      if character.do_action(action):
        return

      if portal.do_action(Action('canenterportal', character_id=character.id, data={'direction': direction})):
        return

      # Perform actions
      action = Action('remoteseeroom', character_id=character.id, room_id=new_room.id, portal_id=portal, data={'path': path})
      portal.do_action(action)
      character.do_action(action)
      new_room.do_action(action)
      old_room.do_action(action)

    def __do_command(self, character_id: str, cmd_string: str):
      character = self._character_manager.get_character(character_id)

      cmd_name = string_utils.parse_word(cmd_string)
      params = string_utils.remove_word(cmd_string)

      # logging.info('{0} is attempting to execute \'{1}\' with parameters \'{2}\''.format(character.name, cmd_name, params))
      full_command_name = character.find_command(cmd_name)
      if full_command_name:
        command = self._command_manager.get(full_command_name)
        command.execute(character, params)
      else:
        character.do_action(Action("error", data={'msg': 'Unrecognized command: {0}<$nl>'.format(cmd_name)}))
예제 #9
0
 def __init__(self, connection, account, character_id):
     super().__init__(connection)
     self._account = account
     self._character_id = character_id
     self._game_manager = GameManager()
     self._character_manager = CharacterManager()
예제 #10
0
def main():
  props = Properties()
  props.init_props('properties.yml')

  configure_log_file(props.get('log.prefix'))
  logging.info('******************')

  connect(props.get('db.database'), host='mongodb://' + props.get('db.user') + ':' + props.get('db.password') + '@' + props.get('db.host'))
  logging.info('Connected to database')
  logging.info('Host: %s', props.get('db.host'))
  logging.info('Database: %s', props.get('db.database'))
  logging.info('User: %s', props.get('db.user'))

  props.load_config()

  character_manager = CharacterManager()
  room_manager = RoomManager()

  # character = character_manager.get_character('5b71dc8b2ac5154cbaf5b07f')
  # room = room_manager.get_room('5b71e47c2ac5158358a4f4f5')

  # character.room_id = room.id
  # room.add_character(character)

  # room.save()
  # character.save()

  # region = Region()
  # region.name = 'Starting Region'
  # region.keywords = 'start'
  # region.save()

  # room = Room()
  # room.name = 'Starting Room'
  # room.description = 'You find yourself in an empty room.'
  # room.coordinates = Coordinate(0,0,0)
  # room.region_id = '5b71e3dc2ac51580c8d6baa6'
  # room.save()

  # template = CharacterTemplate()
  # template.name = 'Generic Human'
  # template.region_id = '5b71e3dc2ac51580c8d6baa6'
  # template.save()

  # templates = CharacterTemplate.objects()
  # print(len(templates))
  # for template in templates:
  #   print(template.id)
  # room_manager = RoomManager()

  # start_room = room_manager.get_room('5b7721032ac5150455940919')
  # end_room = room_manager.get_room('5b86a295f230b2181003380f')
  # portal = Portal()
  # portal.name = 'test'
  # portal_path = PortalPath()
  # portal_path.start_room_id = start_room.id
  # portal_path.end_room_id = end_room.id
  # portal_path.direction_name = 'east'
  # portal.paths.append(portal_path)
  # portal.save()

  portal_manager = PortalManager()
  # portal = portal_manager.get_portal('5b86a5502ac51594c8845dfb')
  # print(portal.id)

  room = room_manager.get_room('5b7721032ac5150455940919')
  portal = room.find_portal('east')
  print(portal.id)
예제 #11
0
 def __init__(self, connection, account):
   super().__init__(connection)
   self._character_manager = CharacterManager()
   self._account = account
   self._character_list = []
예제 #12
0
class TelnetReporter(Logic):
    def __init__(self, character_id, connection):
        self._character_manager = CharacterManager()
        self._room_manager = RoomManager()
        self._portal_manager = PortalManager()

        self._character_id = character_id
        self._connection = connection

    def do_action(self, action):
        # logging.info('Character {0} recieved action: type={1}'.format(self._character_id, action.action_type))
        if action.action_type == 'enterrealm':
            name = 'You enter'
            if action.character_id != self._character_id:
                character = self._character_manager.get_character(
                    action.character_id)
                name = character.name + ' enters'
            self.__send_line('<$nl>{0} the realm.'.format(name))
        elif action.action_type == 'enterroom':
            if action.character_id and action.character_id == self._character_id:
                self.__see_room(self._room_manager.get_room(action.room_id))
            elif action.data:
                character = self._character_manager.get_character(
                    action.character_id)
                path = action.data['path']
                if path:
                    self._connection.send_line(
                        '{0} walks in from the {1}.'.format(
                            character.name, path.direction_name))
                else:
                    self._connection.send_line('{0} walks in.'.format(
                        character.name))
            self.prompt()
        elif action.action_type == 'leaveroom':
            if action.character_id != self._character_id:
                character = self._character_manager.get_character(
                    action.character_id)
                path = action.data['path']
                if path:
                    self._connection.send_line(
                        '{0} leaves towards the {1}.'.format(
                            character.name, path.direction_name))
                else:
                    self._connection.send_line('{0} walks away.'.format(
                        character.name))
            self.prompt()
        elif action.action_type == 'seeroom':
            if action.character_id and action.character_id == self._character_id:
                self.__see_room(self._room_manager.get_room(action.room_id))
            self.prompt()
        elif action.action_type == 'remoteseeroom':
            if action.character_id == self._character_id:
                character = self._character_manager.get_character(
                    self._character_id)
                if action.room_id != character.room_id:
                    room = self._room_manager.get_room(action.room_id)

                    if action.data and action.data['path']:
                        direction = action.data['path'].direction_name
                        self._connection.send_line(
                            'You look {0}wards.'.format(direction))
                    self.__see_room_name(room)
                    self.__see_room_characters(room)

                    self.prompt()
        elif action.action_type == 'error':
            self._connection.send('<$bold><$red>' + action.data['msg'])
            self.prompt()
        elif action.action_type == 'leave':
            self._connection.leave_handler()
            self.prompt()
        elif action.action_type == 'announce':
            self._connection.send(action.data['msg'])
            self.prompt()
        elif action.action_type == 'chat':
            character = self._character_manager.get_character(
                action.character_id)
            name = character.name
            if character.id == self._character_id:
                name = 'You'
            self._connection.send_line(
                '<$nl><$dim><$yellow>{0} gossips, "{1}"<$reset>'.format(
                    name, action.data['msg']))
            self.prompt()

    def prompt(self):
        self._connection.send('<$nl><$red>?<$reset> ')

    def __send_line(self, msg, indent=False, wrap=False):
        self._connection.send_line(msg, indent, wrap)

    def __see_room(self, room: Room):
        if room:
            self.__see_room_name(room)
            self.__see_room_description(room)
            self.__see_room_exits(room)
            self.__see_room_characters(room)
            self.__see_room_items(room)

    def __see_room_name(self, room: Room):
        self.__send_line('<$cyan>{0}'.format(room.name))

    def __see_room_description(self, room: Room):
        self.__send_line(room.description, indent=True, wrap=True)

    def __see_room_exits(self, room: Room):
        exits = []
        portal_ids = room.portal_ids
        for portal_id in portal_ids:
            portal = self._portal_manager.get_portal(portal_id)
            for path in portal.paths:
                if path.start_room_id == room.id:
                    exits.append(path.direction_name.lower().capitalize())

        if exits:
            self.__send_line('Exits: {0}'.format(', '.join(exits)))

    def __see_room_characters(self, room: Room):
        character_ids = room.character_ids
        for character_id in character_ids:
            if character_id != self._character_id:
                character = self._character_manager.get_character(character_id)
                self.__send_line('{0} is standing here.'.format(
                    character.name))

    def __see_room_items(self, room: Room):
        self.__send_line('No items.')  #TODO