class AccessManager: def __init__(self): self.access_levels = [ {"label": "none", "level": 0, "handler": self.no_access}, {"label": "all", "level": 100, "handler": self.all_access}] self.logger = Logger("access_manager") def inject(self, registry): self.character_manager = registry.get_instance("character_manager") self.alts_manager = registry.get_instance("alts_manager") def register_access_level(self, label, level, handler): self.logger.debug("Registering access level %d with label '%s'" % (level, label)) self.access_levels.append({"label": label.lower(), "level": level, "handler": handler}) self.access_levels = sorted(self.access_levels, key=lambda k: k["level"]) def get_access_levels(self): return self.access_levels def get_access_level(self, char): char_id = self.character_manager.resolve_char_to_id(char) if not char_id: return None access_level1 = self.get_single_access_level(char_id) alts = list(self.alts_manager.get_alts(char_id)) if not alts: return access_level1 main = alts[0]['char'][0] if main['char_id'] == char_id: return access_level1 else: access_level2 = self.get_single_access_level(main['char_id']) if access_level1["level"] < access_level2["level"]: return access_level1 else: return access_level2 def get_single_access_level(self, char): char_id = self.character_manager.resolve_char_to_id(char) for access_level in self.access_levels: if access_level["handler"](char_id): return access_level def get_access_level_by_level(self, level): for access_level in self.access_levels: if access_level["level"] == level: return access_level return None def get_access_level_by_label(self, label): label = label.lower() for access_level in self.access_levels: if access_level["label"] == label: return access_level return None def check_access(self, char, access_level_label): return self.get_access_level(char)["level"] <= self.get_access_level_by_label(access_level_label)["level"] def no_access(self, char_id): return False def all_access(self, char_id): return True
class EventManager: def __init__(self): self.handlers = {} self.logger = Logger("event_manager") self.event_types = [] self.last_timer_event = 0 def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") def pre_start(self): self.register_event_type("timer") def start(self): # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "event"): event_type, description = getattr(method, "event") handler = getattr(inst, name) module = self.util.get_module_name(handler) self.register(handler, event_type, description, module) def register_event_type(self, event_type): event_type = event_type.lower() if event_type in self.event_types: self.logger.error( "Could not register event type '%s': event type already registered" % event_type) return self.logger.debug("Registering event type '%s'" % event_type) self.event_types.append(event_type) def is_event_type(self, event_base_type): return event_base_type in self.event_types def register(self, handler, event_type, description, module): event_base_type, event_sub_type = self.get_event_type_parts(event_type) module = module.lower() handler_name = self.util.get_handler_name(handler).lower() if event_base_type not in self.event_types: self.logger.error( "Could not register handler '%s' for event type '%s': event type does not exist" % (handler_name, event_type)) return if not description: self.logger.warning( "No description for event_type '%s' and handler '%s'" % (event_type, handler_name)) row = self.db.find('event_config', { 'event_type': event_base_type, 'handler': handler_name }) if row is None: # add new event commands self.db.insert( 'event_config', { 'event_type': event_base_type, 'event_sub_type': event_sub_type, 'handler': handler_name, 'description': description, 'module': module, 'verified': 1, 'enabled': 1, 'next_run': int(time.time()) }) else: # mark command as verified self.db.update('event_config', { 'event_type': event_base_type, 'handler': handler_name }, { 'verified': 1, 'module': module, 'description': description, 'event_sub_type': event_sub_type, }) # load command handler self.handlers[handler_name] = handler def fire_event(self, event_type, event_data=None): event_base_type, event_sub_type = self.get_event_type_parts(event_type) if event_base_type not in self.event_types: self.logger.error( "Could not fire event type '%s': event type does not exist" % event_type) return data = self.db.find_all( 'event_config', { 'event_type': event_base_type, 'event_sub_type': event_sub_type, 'enabled': 1 }) for row in data: handler = self.handlers.get(row['handler'], None) if not handler: self.logger.error( "Could not find handler callback for event type '%s' and handler '%s'" % (event_type, row.handler)) return try: handler(event_type, event_data) except Exception as e: self.logger.error("error processing event '%s'" % event_type, e) def get_event_type_parts(self, event_type): parts = event_type.lower().split(":", 1) if len(parts) == 2: return parts[0], parts[1] else: return parts[0], "" def get_event_type_key(self, event_base_type, event_sub_type): return event_base_type + ":" + event_sub_type def check_for_timer_events(self, timestamp): data = self.db.find('event_config', { 'enabled': 1, 'event_type': 'timer', 'next_run': { '$gte': timestamp } }) if data is not None: for row in data: event_type_key = self.get_event_type_key( row['event_type'], row['event_sub_type']) # timer event run times should be consistent, so we base the next run time off the last run time, # instead of the current timestamp next_run = row['next_run'] + int(row['event_sub_type']) # prevents timer events from getting too far behind, or having a large "catch-up" after # the bot has been offline for a time if next_run < timestamp: next_run = timestamp + int(row['event_sub_type']) self.db.update('event_config', { 'event_type': 'timer', 'handler': row['handler'] }, {'next_run': next_run}) self.fire_event(event_type_key)
class SettingManager: def __init__(self): self.logger = Logger("setting_manager") self.settings = {} def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") def start(self): # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "setting"): setting_name, value, description, obj = getattr(method, "setting") handler = getattr(inst, name) module = self.util.get_module_name(handler) self.register(setting_name, value, description, obj, module) def register(self, name, value, description, setting: SettingType, module): name = name.lower() module = module.lower() setting.set_name(name) setting.set_description(description) if not description: self.logger.warning("No description specified for setting '%s'" % name) row = self.db.find('settings', {"name": name}) if row is None: self.logger.debug("Adding setting '%s'" % name) self.db.insert("settings", { "name": name, "value": value, "description": description, "module": module, "verified": 1 }) # verify default value is a valid value, and is formatted appropriately setting.set_value(value) else: self.logger.debug("Updating setting '%s'" % name) self.db.update('settings', {"name": name}, {"description": description, "verified": 1, "module": module}) self.settings[name] = setting def get_value(self, name): row = self.db.find('settings', {"name": name}) return row['value'] if row else None def set_value(self, name, value): self.db.update('settings', {"name": name}, {"value": value}) def get(self, name): name = name.lower() setting = self.settings.get(name, None) if setting: return setting else: return None