The McDisClient class extends discord.ext.commands.Bot and serves as the core of McDis-RCON. It manages configuration, processes, plugins, addons, and Discord integration.
def _load_config(self): try: self.config = read_yml('md_config.yml') except Exception as error: print('The file \'md_config.yml\' could not be opened.') os._exit(0)
async def _load_processes(self): for name in self.config['Processes']['Servers']: server = Server(name, self, self.config['Processes']['Servers'][name]) self.processes.append(server) self.servers.append(server) for name in self.config['Processes']['Networks']: network = Network(name, self, self.config['Processes']['Networks'][name]) self.processes.append(network) self.networks.append(network)
Creates Server and Network objects from configuration.
def is_valid_mcdis_path(self, path: str, *, check_if_file: bool = False, check_if_dir: bool = False): real_path = un_mcdis_path(path) new_path = os.path.join(self.cwd, real_path) if not path.split(os.sep)[0] == 'McDis': return self._('✖ The path must be a McDis path. E.g.: `McDis/Backups`.') if not new_path.startswith(self.cwd): return self._('✖ You must work within the directory where McDis is running.')
Validates McDis paths and prevents directory traversal.
def on_stop(self): self.unload_addons() if any([process.is_running() for process in self.processes]): print(self._('Closing processes...')) for process in self.processes: process.stop(omit_task=True) # Wait up to 60 seconds i = 60 while i > 0 and any([process.is_running() for process in self.processes]): i -= 1 time.sleep(1) # Force kill if needed if any([process.is_running() for process in self.processes]): for process in self.processes: process.kill(omit_task=True) os._exit(0)
Gracefully shuts down all processes before exiting.