""" some IDE's will throw 'PEP 8' warnings for imports, but this has to happen early, I think """ from gevent import monkey monkey.patch_all() """ standard imports """ from importlib import import_module from os import path, chdir, walk import json from collections import deque from bot.logger import get_logger root_dir = path.dirname(path.abspath(__file__)) logger = get_logger("init") chdir(root_dir) loaded_modules_dict = {} # this will be populated by the imports done next: telnet_prefixes = { "telnet_log": { # Modern 7D2D servers still include timestamp/stardate/INF in "Executing command" lines # Format: 2025-11-18T20:20:59 4851.528 INF Executing command... "timestamp": r"(?P\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\s(?P[-+]?\d*\.\d+|\d+)\sINF\s" }, "GMSG": { "command": ( r"GMSG:\s" r"Player\s\'" r"(?P.*)" r"\'\s" r"(?P.*)$" ) }, "BCM": { "chat": ( r"Chat\shandled\sby\smod\s\'(?P.*?)\':\s" r"Chat\s\(from\s\'(?P.*?)\',\sentity\sid\s\'(?P.*?)\',\s" r"to\s\'(?P.*)\'\)\:\s" ) }, "Allocs": { "chat": ( r"Chat\s\(from \'(?P.*)\',\sentity\sid\s\'(?P.*)\',\s" r"to \'(?P.*)\'\)\:\s" ) } } modules_to_start_list = deque() module_loading_order = [] started_modules_dict = {} available_modules_list = next(walk(path.join('modules', '.')))[1] for module in available_modules_list: """ at the bottom of each module, the loaded_modules_list will be updated modules may not do any stuff in their __init__, apart from setting variables and calling static methods, unless you know what you are doing """ import_module("bot.modules." + module) def batch_setup_modules(modules_list): def get_options_dict(module_name): try: options_dir = "{}/{}".format(root_dir, "options") with open(path.join(options_dir, module_name + ".json")) as open_file: return json.load(open_file) except FileNotFoundError: return dict if len(module_loading_order) >= 1: for module_to_setup in module_loading_order: module_options_dict = get_options_dict(module_to_setup) loaded_modules_dict[module_to_setup].setup(module_options_dict) modules_to_start_list.append(loaded_modules_dict[module_to_setup]) else: """ this should load all module in an order they can work with Make absolutely SURE there's no circular dependencies, because I won't :) """ for module_to_setup in modules_list: try: if isinstance(loaded_modules_dict[module_to_setup].required_modules, list): # has dependencies, load those first! batch_setup_modules(loaded_modules_dict[module_to_setup].required_modules) raise AttributeError except AttributeError: # raised by isinstance = has no dependencies, load right away if loaded_modules_dict[module_to_setup] not in modules_to_start_list: module_options_dict = get_options_dict(module_to_setup) loaded_modules_dict[module_to_setup].setup(module_options_dict) modules_to_start_list.append(loaded_modules_dict[module_to_setup]) def setup_modules(): loaded_modules_identifier_list = [] for loaded_module_identifier, loaded_module in loaded_modules_dict.items(): loaded_modules_identifier_list.append(loaded_module.get_module_identifier()) batch_setup_modules(loaded_modules_identifier_list) def start_modules(): for module_to_start in modules_to_start_list: module_to_start.start() started_modules_dict[module_to_start.get_module_identifier()] = module_to_start if len(loaded_modules_dict) == len(started_modules_dict): logger.info("modules_started", count=len(started_modules_dict), modules=list(started_modules_dict.keys()))