예제 #1
0
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
예제 #2
0
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)
예제 #3
0
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