async def init(): # called when server starts up cmds.load_commands() # load commands in pymine/logic/cmds/* # Load packet handlers / packet logic handlers under pymine/logic/handle for root, dirs, files in os.walk(os.path.join("pymine", "logic", "handle")): for file in filter((lambda f: f.endswith(".py")), files): importlib.import_module( os.path.join(root, file)[:-3].replace("\\", "/").replace("/", ".")) try: os.mkdir("plugins") except FileExistsError: pass plugins_dir = os.listdir("plugins") git_dir = git.Git("plugins") for plugin in plugins_dir: try: await load_plugin(git_dir, plugin) except BaseException as e: logger.error( f"Failed to load {plugin} due to: {logger.f_traceback(e)}") # start command handler task running_tasks.append(asyncio.create_task(cmds.handle_server_commands()))
async def handle_server_commands(): try: while True: in_text = await aioconsole.ainput(">") # In the future, commands *should* be handled async, # however, due to the way the console works rn we can't # without messing up the output # asyncio.create_task(handle_command(in_text)) await handle_server_command(in_text) except (KeyboardInterrupt, asyncio.CancelledError): pass except BaseException as e: logger.error(logger.f_traceback(e))
async def handle_con(reader, writer): # Handle a connection from a client stream = Stream(reader, writer) logger.debug( f"Connection received from {stream.remote[0]}:{stream.remote[1]}.") continue_ = True while continue_: try: continue_, stream = await handle_packet(stream) except BaseException as e: logger.error(logger.f_traceback(e)) break await close_con(stream)
async def handle_server_command(in_text: str): in_split = in_text.split(" ") cmd = in_split.pop(0) args = " ".join(in_split) reg_cmd = registered_commands.get(cmd) if reg_cmd is not None: cmd_func = reg_cmd[0] try: if asyncio.iscoroutinefunction(cmd_func): await cmd_func("server", args) else: cmd_func("server", args) except BaseException as e: logger.error(logger.f_traceback(e)) else: logger.warn(f"Invalid/unknown command: {cmd}")
async def load_plugin(git_dir, plugin_name): root = os.path.join("plugins", plugin_name) if os.path.isfile(root): if root.endswith(".py"): # .py file (so try to import) try: plugin_path = root.rstrip(".py").replace("\\", "/").replace( "/", ".") plugin_module = importlib.import_module(plugin_path) plugins[plugin_path] = plugin_module except BaseException as e: logger.error( f"Failed to load {plugin_name} due to: {logger.f_traceback(e)}" ) return plugin_config_file = os.path.join(root, "plugin.yml") if not os.path.isfile(plugin_config_file): logger.error( f"Failed to load {plugin_name} due to missing plugin.yml.") return try: conf = load_plugin_config(root) except ValueError as e: logger.error( f"Failed to load {plugin_name} due to invalid plugin.yml. ({str(e)})" ) return except BaseException as e: logger.error( f"Failed to load {plugin_name} due to invalid plugin.yml. Error: {logger.f_traceback(e)}" ) return if conf.get("git_url"): logger.info(f"Checking for updates for {plugin_name}...") try: update_repo(git_dir, conf["git_url"], root, plugin_name) except BaseException as e: logger.error( f"Failed to update {plugin_name} due to: {logger.f_traceback(e)}" ) return plugin_path = root if conf.get("module_folder"): plugin_path = os.path.join(plugin_path, conf["module_folder"]) plugin_path = plugin_path.replace("\\", "/").replace("/", ".") try: plugin_module = importlib.import_module(plugin_path) except BaseException as e: logger.error( f"Failed to import {plugin_name} due to: {logger.f_traceback(e)}") return try: await plugin_module.setup() except BaseException as e: logger.error( f"Failed to setup {plugin_name} due to: {logger.f_traceback(e)}") return plugins[plugin_path] = plugin_module