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 __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
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 = []
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()}))
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: ')
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)
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()
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)}))
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 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)
def __init__(self, connection, account): super().__init__(connection) self._character_manager = CharacterManager() self._account = account self._character_list = []
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