From aa15aea749955473401c440297f55dae61bf5e8b Mon Sep 17 00:00:00 2001 From: adator <85586985+adator85@users.noreply.github.com> Date: Thu, 20 Nov 2025 00:29:32 +0100 Subject: [PATCH] Introduce full asyncio version (still some module to migrate). Defender JSONRPC Server ready and using with uvcorn --- core/base.py | 103 ++-- core/classes/interfaces/imodule.py | 19 +- core/classes/interfaces/iprotocol.py | 29 +- core/classes/modules/admin.py | 8 +- core/classes/modules/channel.py | 66 ++- core/classes/modules/client.py | 4 +- core/classes/modules/rehash.py | 70 +-- core/classes/modules/rpc/__init__.py | 1 + core/classes/modules/rpc/rpc.py | 243 +++----- core/classes/modules/rpc/rpc_channel.py | 4 +- core/classes/modules/rpc/rpc_command.py | 16 +- core/classes/modules/rpc/rpc_user.py | 12 +- core/classes/protocols/factory.py | 21 +- core/classes/protocols/inspircd.py | 711 +++++++++++------------ core/classes/protocols/unreal6.py | 620 ++++++++++---------- core/definition.py | 3 +- core/irc.py | 726 ++++++++++-------------- core/loader.py | 18 +- core/logs.py | 2 +- core/module.py | 239 ++++---- core/utils.py | 12 + defender.py | 1 + mods/clone/clone_manager.py | 2 +- mods/clone/mod_clone.py | 175 +++--- mods/clone/threads.py | 13 +- mods/clone/utils.py | 18 +- mods/command/mod_command.py | 647 ++++++++++----------- mods/command/utils.py | 180 +++--- mods/defender/mod_defender.py | 698 ++++++++++++----------- mods/defender/threads.py | 115 ++-- mods/defender/utils.py | 363 ++++++------ mods/test/mod_test.py | 11 +- requirements.txt | 4 +- version.json | 6 +- 34 files changed, 2533 insertions(+), 2627 deletions(-) create mode 100644 core/classes/modules/rpc/__init__.py diff --git a/core/base.py b/core/base.py index dff0d0e..6d9fbb7 100644 --- a/core/base.py +++ b/core/base.py @@ -45,9 +45,6 @@ class Base: # Liste des fonctions en attentes self.periodic_func: dict[object] = self.Settings.PERIODIC_FUNC - # Création du lock - self.lock = self.Settings.LOCK - # Init install variable self.install: bool = False @@ -57,8 +54,8 @@ class Base: # Create the database # self.__create_db() - def init(self) -> None: - self.__create_db() + async def init(self) -> None: + await self.__create_db() def __set_current_defender_version(self) -> None: """This will put the current version of Defender @@ -145,7 +142,7 @@ class Base: except Exception as err: self.logs.error(f'General Error: {err}') - def create_log(self, log_message: str) -> None: + async def create_log(self, log_message: str) -> None: """Enregiste les logs Args: @@ -156,11 +153,11 @@ class Base: """ sql_insert = f"INSERT INTO {self.Config.TABLE_LOG} (datetime, server_msg) VALUES (:datetime, :server_msg)" mes_donnees = {'datetime': str(self.Utils.get_sdatetime()),'server_msg': f'{log_message}'} - self.db_execute_query(sql_insert, mes_donnees) + await self.db_execute_query(sql_insert, mes_donnees) return None - def log_cmd(self, user_cmd: str, cmd: str) -> None: + async def log_cmd(self, user_cmd: str, cmd: str) -> None: """Enregistre les commandes envoyées par les utilisateurs Args: @@ -176,11 +173,11 @@ class Base: insert_cmd_query = f"INSERT INTO {self.Config.TABLE_COMMAND} (datetime, user, commande) VALUES (:datetime, :user, :commande)" mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': user_cmd, 'commande': cmd} - self.db_execute_query(insert_cmd_query, mes_donnees) + await self.db_execute_query(insert_cmd_query, mes_donnees) return None - def db_sync_core_config(self, module_name: str, dataclassObj: object) -> bool: + async def db_sync_core_config(self, module_name: str, dataclassObj: object) -> bool: """Sync module local parameters with the database if new module then local param will be stored in the database if old module then db param will be moved to the local dataclassObj @@ -207,7 +204,7 @@ class Base: param_to_search = {'module_name': module_name, 'param_key': param_key} search_query = f'''SELECT id FROM {core_table} WHERE module_name = :module_name AND param_key = :param_key''' - excecute_search_query = self.db_execute_query(search_query, param_to_search) + excecute_search_query = await self.db_execute_query(search_query, param_to_search) result_search_query = excecute_search_query.fetchone() if result_search_query is None: @@ -219,7 +216,7 @@ class Base: insert_query = f'''INSERT INTO {core_table} (datetime, module_name, param_key, param_value) VALUES (:datetime, :module_name, :param_key, :param_value) ''' - execution = self.db_execute_query(insert_query, param_to_insert) + execution = await self.db_execute_query(insert_query, param_to_insert) if execution.rowcount > 0: self.logs.debug(f'New parameter added to the database: {param_key} --> {param_value}') @@ -227,14 +224,14 @@ class Base: # Delete from DB unused parameter query_select = f"SELECT module_name, param_key, param_value FROM {core_table} WHERE module_name = :module_name" parameter = {'module_name': module_name} - execute_query_select = self.db_execute_query(query_select, parameter) + execute_query_select = await self.db_execute_query(query_select, parameter) result_query_select = execute_query_select.fetchall() for result in result_query_select: db_mod_name, db_param_key, db_param_value = result if not hasattr(dataclassObj, db_param_key): mes_donnees = {'param_key': db_param_key, 'module_name': db_mod_name} - execute_delete = self.db_execute_query(f'DELETE FROM {core_table} WHERE module_name = :module_name and param_key = :param_key', mes_donnees) + execute_delete = await self.db_execute_query(f'DELETE FROM {core_table} WHERE module_name = :module_name and param_key = :param_key', mes_donnees) row_affected = execute_delete.rowcount if row_affected > 0: self.logs.debug(f'A parameter has been deleted from the database: {db_param_key} --> {db_param_value} | Mod: {db_mod_name}') @@ -242,7 +239,7 @@ class Base: # Sync local variable with Database query = f"SELECT param_key, param_value FROM {core_table} WHERE module_name = :module_name" parameter = {'module_name': module_name} - response = self.db_execute_query(query, parameter) + response = await self.db_execute_query(query, parameter) result = response.fetchall() for param, value in result: @@ -259,7 +256,7 @@ class Base: self.logs.error(err) return False - def db_update_core_config(self, module_name:str, dataclass_obj: object, param_key:str, param_value: str) -> bool: + async def db_update_core_config(self, module_name:str, dataclass_obj: object, param_key:str, param_value: str) -> bool: core_table = self.Config.TABLE_CONFIG # Check if the param exist @@ -269,7 +266,7 @@ class Base: mes_donnees = {'module_name': module_name, 'param_key': param_key, 'param_value': param_value} search_param_query = f"SELECT id FROM {core_table} WHERE module_name = :module_name AND param_key = :param_key" - result = self.db_execute_query(search_param_query, mes_donnees) + result = await self.db_execute_query(search_param_query, mes_donnees) is_param_exist = result.fetchone() if not is_param_exist is None: @@ -279,7 +276,7 @@ class Base: 'param_value': param_value } query = f'''UPDATE {core_table} SET datetime = :datetime, param_value = :param_value WHERE module_name = :module_name AND param_key = :param_key''' - update = self.db_execute_query(query, mes_donnees) + update = await self.db_execute_query(query, mes_donnees) updated_rows = update.rowcount if updated_rows > 0: setattr(dataclass_obj, param_key, self.int_if_possible(param_value)) @@ -293,9 +290,9 @@ class Base: return True - def db_create_first_admin(self) -> None: + async def db_create_first_admin(self) -> None: - user = self.db_execute_query(f"SELECT id FROM {self.Config.TABLE_ADMIN}") + user = await self.db_execute_query(f"SELECT id FROM {self.Config.TABLE_ADMIN}") if not user.fetchall(): admin = self.Config.OWNER password = self.Utils.hash_password(self.Config.PASSWORD) @@ -308,7 +305,7 @@ class Base: 'language': 'EN', 'level': 5 } - self.db_execute_query(f""" + await self.db_execute_query(f""" INSERT INTO {self.Config.TABLE_ADMIN} (createdOn, user, password, hostname, vhost, language, level) VALUES @@ -381,11 +378,28 @@ class Base: return None task = asyncio.create_task(func, name=name) + task.add_done_callback(self.asynctask_done) self.running_asynctasks.append(task) self.logs.debug(f"++ New asynchrone task created as: {task.get_name()}") return task + def asynctask_done(self, task: asyncio.Task): + """Log task when done + + Args: + task (asyncio.Task): The Asyncio Task callback + """ + try: + if task.exception(): + self.logs.error(f"[ASYNCIO] Task {task.get_name()} failed with exception: {task.exception()}") + else: + self.logs.debug(f"[ASYNCIO] Task {task.get_name()} completed successfully.") + except asyncio.CancelledError as ce: + self.logs.debug(f"[ASYNCIO] Task {task.get_name()} terminated with cancelled error.") + except asyncio.InvalidStateError as ie: + self.logs.debug(f"[ASYNCIO] Task {task.get_name()} terminated with invalid state error.") + def is_thread_alive(self, thread_name: str) -> bool: """Check if the thread is still running! using the is_alive method of Threads. @@ -429,7 +443,7 @@ class Base: Returns: int: Number of threads """ - with self.lock: + with self.Settings.LOCK: count = 0 for thr in self.running_threads: @@ -478,7 +492,7 @@ class Base: self.running_sockets.remove(soc) self.logs.debug(f"-- Socket ==> closed {str(soc.fileno())}") - def shutdown(self) -> None: + async def shutdown(self) -> None: """Methode qui va préparer l'arrêt complêt du service """ # Nettoyage des timers @@ -507,6 +521,9 @@ class Base: self.running_sockets.remove(soc) self.logs.debug(f"> Socket ==> closed {str(soc.fileno())}") + + await self.Loader.RpcServer.stop_server() + self.db_close() return None @@ -524,7 +541,7 @@ class Base: self.logs.info("-- Database connexion has been initiated") return engine, cursor - def __create_db(self) -> None: + async def __create_db(self) -> None: table_core_log = f'''CREATE TABLE IF NOT EXISTS {self.Config.TABLE_LOG} ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -594,27 +611,27 @@ class Base: ) ''' - self.db_execute_query(table_core_log) - self.db_execute_query(table_core_log_command) - self.db_execute_query(table_core_module) - self.db_execute_query(table_core_admin) - self.db_execute_query(table_core_client) - self.db_execute_query(table_core_channel) - self.db_execute_query(table_core_config) + await self.db_execute_query(table_core_log) + await self.db_execute_query(table_core_log_command) + await self.db_execute_query(table_core_module) + await self.db_execute_query(table_core_admin) + await self.db_execute_query(table_core_client) + await self.db_execute_query(table_core_channel) + await self.db_execute_query(table_core_config) # Patch database - self.db_patch(self.Config.TABLE_ADMIN, "language", "TEXT") + await self.db_patch(self.Config.TABLE_ADMIN, "language", "TEXT") if self.install: - self.Loader.ModuleUtils.db_register_module('mod_command', 'sys', True) - self.Loader.ModuleUtils.db_register_module('mod_defender', 'sys', True) + await self.Loader.ModuleUtils.db_register_module('mod_command', 'sys', True) + await self.Loader.ModuleUtils.db_register_module('mod_defender', 'sys', True) self.install = False return None - def db_execute_query(self, query:str, params:dict = {}) -> CursorResult: + async def db_execute_query(self, query:str, params:dict = {}) -> CursorResult: - with self.lock: + async with self.Loader.Settings.AILOCK: insert_query = text(query) if not params: response = self.cursor.execute(insert_query) @@ -625,8 +642,8 @@ class Base: return response - def db_is_column_exist(self, table_name: str, column_name: str) -> bool: - q = self.db_execute_query(f"PRAGMA table_info({table_name})") + async def db_is_column_exist(self, table_name: str, column_name: str) -> bool: + q = await self.db_execute_query(f"PRAGMA table_info({table_name})") existing_columns = [col[1] for col in q.fetchall()] if column_name in existing_columns: @@ -634,12 +651,12 @@ class Base: else: return False - def db_patch(self, table_name: str, column_name: str, column_type: str) -> bool: - if not self.db_is_column_exist(table_name, column_name): + async def db_patch(self, table_name: str, column_name: str, column_type: str) -> bool: + if not await self.db_is_column_exist(table_name, column_name): patch = f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_type}" update_row = f"UPDATE {table_name} SET language = 'EN' WHERE language is null" - self.db_execute_query(patch) - self.db_execute_query(update_row) + await self.db_execute_query(patch) + await self.db_execute_query(update_row) self.logs.debug(f"The patch has been applied") self.logs.debug(f"Table name: {table_name}, Column name: {column_name}, Column type: {column_type}") return True @@ -647,9 +664,9 @@ class Base: return False def db_close(self) -> None: - try: self.cursor.close() + self.logs.debug("Database engine closed!") except AttributeError as ae: self.logs.error(f"Attribute Error : {ae}") diff --git a/core/classes/interfaces/imodule.py b/core/classes/interfaces/imodule.py index 309b853..7f8c306 100644 --- a/core/classes/interfaces/imodule.py +++ b/core/classes/interfaces/imodule.py @@ -24,22 +24,19 @@ class IModule(ABC): # Log the module self.ctx.Logs.debug(f'Loading Module {self.module_name} ...') - def init(self) -> None: - self.load() - self.create_tables() - + async def sync_db(self) -> None: # Sync the configuration with core configuration (Mandatory) - self.ctx.Base.db_sync_core_config(self.module_name, self.mod_config) + await self.ctx.Base.db_sync_core_config(self.module_name, self.mod_config) return None - def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None: + async def update_configuration(self, param_key: str, param_value: Union[str, int]) -> None: """Update the local and core configuration Args: param_key (str): The parameter key param_value (str): The parameter value """ - self.ctx.Base.db_update_core_config(self.module_name, self.mod_config, param_key, param_value) + await self.ctx.Base.db_update_core_config(self.module_name, self.mod_config, param_key, param_value) @property @abstractmethod @@ -58,17 +55,17 @@ class IModule(ABC): """ @abstractmethod - def load(self) -> None: + async def load(self) -> None: """This method is executed when the module is loaded or reloaded. """ @abstractmethod - def unload(self) -> None: + async def unload(self) -> None: """This method is executed when the module is unloaded or reloaded. """ @abstractmethod - def cmd(self, data: list) -> None: + async def cmd(self, data: list) -> None: """When recieving server messages. Args: @@ -76,7 +73,7 @@ class IModule(ABC): """ @abstractmethod - def hcmds(self, user: str, channel: Optional[str], cmd: list[str], fullcmd: Optional[list[str]] = None) -> None: + async def hcmds(self, user: str, channel: Optional[str], cmd: list[str], fullcmd: Optional[list[str]] = None) -> None: """These are the commands recieved from a client Args: diff --git a/core/classes/interfaces/iprotocol.py b/core/classes/interfaces/iprotocol.py index 7c7ad3b..6ff5bfc 100644 --- a/core/classes/interfaces/iprotocol.py +++ b/core/classes/interfaces/iprotocol.py @@ -4,31 +4,20 @@ from core.classes.protocols.command_handler import CommandHandler if TYPE_CHECKING: from core.definition import MClient, MSasl, MUser, MChannel - from core.irc import Irc + from core.loader import Loader class IProtocol(ABC): Handler: Optional[CommandHandler] = None - def __init__(self, uplink: 'Irc'): + def __init__(self, context: 'Loader'): self.name: Optional[str] = None self.protocol_version: int = -1 self.known_protocol: set[str] = set() - - self._Irc = uplink - self._Config = uplink.Config - self._Base = uplink.Base - self._Settings = uplink.Base.Settings - self._Utils = uplink.Loader.Utils - self._Logs = uplink.Loader.Logs - self._User = uplink.User - self._Channel = uplink.Channel - - self.Handler = CommandHandler(uplink.Loader) - + self._ctx = context + self.Handler = CommandHandler(context) self.init_protocol() - - self._Logs.info(f"[PROTOCOL] Protocol [{self.__class__.__name__}] loaded!") + self._ctx.Logs.info(f"[PROTOCOL] Protocol [{self.__class__.__name__}] loaded!") @abstractmethod def init_protocol(self): @@ -313,7 +302,7 @@ class IProtocol(ABC): # ------------------------------------------------------------------------ @abstractmethod - async def parse_uid(self, server_msg: list[str]) -> Optional['MUser']: + def parse_uid(self, server_msg: list[str]) -> Optional['MUser']: """Parse UID and return dictionary. Args: @@ -324,7 +313,7 @@ class IProtocol(ABC): """ @abstractmethod - async def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]: + def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]: """Parse quit and return dictionary. >>> [':97KAAAAAB', 'QUIT', ':Quit:', 'this', 'is', 'my', 'reason', 'to', 'quit'] Args: @@ -335,7 +324,7 @@ class IProtocol(ABC): """ @abstractmethod - async def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]: + def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]: """Parse nick changes and return dictionary. >>> [':97KAAAAAC', 'NICK', 'testinspir', '1757360740'] @@ -349,7 +338,7 @@ class IProtocol(ABC): """ @abstractmethod - async def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]: + def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]: """Parse PRIVMSG message. >>> [':97KAAAAAE', 'PRIVMSG', '#welcome', ':This', 'is', 'my', 'public', 'message'] diff --git a/core/classes/modules/admin.py b/core/classes/modules/admin.py index 7f59939..a71a87d 100644 --- a/core/classes/modules/admin.py +++ b/core/classes/modules/admin.py @@ -173,7 +173,7 @@ class Admin: return admin.language - def db_auth_admin_via_fingerprint(self, fp: str, uidornickname: str) -> bool: + async def db_auth_admin_via_fingerprint(self, fp: str, uidornickname: str) -> bool: """Check the fingerprint Args: @@ -188,7 +188,7 @@ class Admin: query = f"SELECT user, level, language FROM {self.Config.TABLE_ADMIN} WHERE fingerprint = :fp" data = {'fp': fp} - exe = self.Base.db_execute_query(query, data) + exe = await self.Base.db_execute_query(query, data) result = exe.fetchone() if result: account = result[0] @@ -204,7 +204,7 @@ class Admin: return False - def db_is_admin_exist(self, admin_nickname: str) -> bool: + async def db_is_admin_exist(self, admin_nickname: str) -> bool: """Verify if the admin exist in the database! Args: @@ -216,7 +216,7 @@ class Admin: mes_donnees = {'admin': admin_nickname} query_search_user = f"SELECT id FROM {self.Config.TABLE_ADMIN} WHERE user = :admin" - r = self.Base.db_execute_query(query_search_user, mes_donnees) + r = await self.Base.db_execute_query(query_search_user, mes_donnees) exist_user = r.fetchone() if exist_user: return True diff --git a/core/classes/modules/channel.py b/core/classes/modules/channel.py index 0bcb0fb..0ea36d4 100644 --- a/core/classes/modules/channel.py +++ b/core/classes/modules/channel.py @@ -17,9 +17,7 @@ class Channel: Args: loader (Loader): The Loader Instance """ - self.Logs = loader.Logs - self.Base = loader.Base - self.Utils = loader.Utils + self._ctx = loader def insert(self, new_channel: 'MChannel') -> bool: """This method will insert a new channel and if the channel exist it will update the user list (uids) @@ -34,14 +32,14 @@ class Channel: exist = False if not self.is_valid_channel(new_channel.name): - self.Logs.error(f"The channel {new_channel.name} is not valid, channel must start with #") + self._ctx.Logs.error(f"The channel {new_channel.name} is not valid, channel must start with #") return False for record in self.UID_CHANNEL_DB: if record.name.lower() == new_channel.name.lower(): # If the channel exist, update the user list and do not go further exist = True - # self.Logs.debug(f'{record.name} already exist') + # self._ctx.Logs.debug(f'{record.name} already exist') for user in new_channel.uids: record.uids.append(user) @@ -49,7 +47,7 @@ class Channel: # Supprimer les doublons del_duplicates = list(set(record.uids)) record.uids = del_duplicates - # self.Logs.debug(f'Updating a new UID to the channel {record}') + # self._ctx.Logs.debug(f'Updating a new UID to the channel {record}') return result if not exist: @@ -57,10 +55,10 @@ class Channel: new_channel.name = new_channel.name.lower() self.UID_CHANNEL_DB.append(new_channel) result = True - # self.Logs.debug(f'New Channel Created: ({new_channel})') + # self._ctx.Logs.debug(f'New Channel Created: ({new_channel})') if not result: - self.Logs.critical(f'The Channel Object was not inserted {new_channel}') + self._ctx.Logs.critical(f'The Channel Object was not inserted {new_channel}') self.clean_channel() @@ -103,7 +101,7 @@ class Channel: return result for userid in chan_obj.uids: - if self.Utils.clean_uid(userid) == self.Utils.clean_uid(uid): + if self._ctx.Utils.clean_uid(userid) == self._ctx.Utils.clean_uid(uid): chan_obj.uids.remove(userid) result = True @@ -111,7 +109,7 @@ class Channel: return result except ValueError as ve: - self.Logs.error(f'{ve}') + self._ctx.Logs.error(f'{ve}') return False def delete_user_from_all_channel(self, uid:str) -> bool: @@ -128,7 +126,7 @@ class Channel: for record in self.UID_CHANNEL_DB: for user_id in record.uids: - if self.Utils.clean_uid(user_id) == self.Utils.clean_uid(uid): + if self._ctx.Utils.clean_uid(user_id) == self._ctx.Utils.clean_uid(uid): record.uids.remove(user_id) result = True @@ -136,7 +134,7 @@ class Channel: return result except ValueError as ve: - self.Logs.error(f'{ve}') + self._ctx.Logs.error(f'{ve}') return False def add_user_to_a_channel(self, channel_name: str, uid: str) -> bool: @@ -154,7 +152,7 @@ class Channel: if chan_obj is None: # Create a new channel if the channel don't exist - self.Logs.debug(f"New channel will be created ({channel_name} - {uid})") + self._ctx.Logs.debug(f"New channel will be created ({channel_name} - {uid})") return self.insert(MChannel(channel_name, uids=[uid])) chan_obj.uids.append(uid) @@ -163,7 +161,7 @@ class Channel: return True except Exception as err: - self.Logs.error(f'{err}') + self._ctx.Logs.error(f'{err}') return False def is_user_present_in_channel(self, channel_name: str, uid: str) -> bool: @@ -180,9 +178,9 @@ class Channel: if chan is None: return False - clean_uid = self.Utils.clean_uid(uid=uid) + clean_uid = self._ctx.Utils.clean_uid(uid=uid) for chan_uid in chan.uids: - if self.Utils.clean_uid(chan_uid) == clean_uid: + if self._ctx.Utils.clean_uid(chan_uid) == clean_uid: return True return False @@ -197,7 +195,7 @@ class Channel: return None except Exception as err: - self.Logs.error(f'{err}') + self._ctx.Logs.error(f'{err}') def get_channel(self, channel_name: str) -> Optional['MChannel']: """Get the channel object @@ -237,13 +235,13 @@ class Channel: else: return True except TypeError as te: - self.Logs.error(f'TypeError: [{channel_to_check}] - {te}') + self._ctx.Logs.error(f'TypeError: [{channel_to_check}] - {te}') return False except Exception as err: - self.Logs.error(f'Error Not defined: {err}') + self._ctx.Logs.error(f'Error Not defined: {err}') return False - def db_query_channel(self, action: Literal['add','del'], module_name: str, channel_name: str) -> bool: + async def db_query_channel(self, action: Literal['add','del'], module_name: str, channel_name: str) -> bool: """You can add a channel or delete a channel. Args: @@ -256,39 +254,49 @@ class Channel: """ try: channel_name = channel_name.lower() if self.is_valid_channel(channel_name) else None - core_table = self.Base.Config.TABLE_CHANNEL + core_table = self._ctx.Base.Config.TABLE_CHANNEL if not channel_name: - self.Logs.warning(f'The channel [{channel_name}] is not correct') + self._ctx.Logs.warning(f'The channel [{channel_name}] is not correct') return False match action: case 'add': mes_donnees = {'module_name': module_name, 'channel_name': channel_name} - response = self.Base.db_execute_query(f"SELECT id FROM {core_table} WHERE module_name = :module_name AND channel_name = :channel_name", mes_donnees) + response = await self._ctx.Base.db_execute_query(f"SELECT id FROM {core_table} WHERE module_name = :module_name AND channel_name = :channel_name", mes_donnees) is_channel_exist = response.fetchone() if is_channel_exist is None: - mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'channel_name': channel_name, 'module_name': module_name} - insert = self.Base.db_execute_query(f"INSERT INTO {core_table} (datetime, channel_name, module_name) VALUES (:datetime, :channel_name, :module_name)", mes_donnees) + mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'channel_name': channel_name, 'module_name': module_name} + insert = await self._ctx.Base.db_execute_query(f"INSERT INTO {core_table} (datetime, channel_name, module_name) VALUES (:datetime, :channel_name, :module_name)", mes_donnees) if insert.rowcount: - self.Logs.debug(f'Channel added to DB: channel={channel_name} / module_name={module_name}') + self._ctx.Logs.debug(f'Channel added to DB: channel={channel_name} / module_name={module_name}') return True else: return False case 'del': mes_donnes = {'channel_name': channel_name, 'module_name': module_name} - response = self.Base.db_execute_query(f"DELETE FROM {core_table} WHERE channel_name = :channel_name AND module_name = :module_name", mes_donnes) + response = await self._ctx.Base.db_execute_query(f"DELETE FROM {core_table} WHERE channel_name = :channel_name AND module_name = :module_name", mes_donnes) if response.rowcount > 0: - self.Logs.debug(f'Channel deleted from DB: channel={channel_name} / module: {module_name}') + self._ctx.Logs.debug(f'Channel deleted from DB: channel={channel_name} / module: {module_name}') return True else: return False except Exception as err: - self.Logs.error(err) + self._ctx.Logs.error(err) return False + + async def db_join_saved_channels(self) -> None: + """## Joining saved channels""" + exec_query = await self._ctx.Base.db_execute_query(f'SELECT distinct channel_name FROM {self._ctx.Config.TABLE_CHANNEL}') + result_query = exec_query.fetchall() + + if result_query: + for chan_name in result_query: + chan = chan_name[0] + await self._ctx.Irc.Protocol.send_sjoin(channel=chan) \ No newline at end of file diff --git a/core/classes/modules/client.py b/core/classes/modules/client.py index 2ea01c3..ec422eb 100644 --- a/core/classes/modules/client.py +++ b/core/classes/modules/client.py @@ -201,7 +201,7 @@ class Client: return True - def db_is_account_exist(self, account: str) -> bool: + async def db_is_account_exist(self, account: str) -> bool: """Check if the account exist in the database Args: @@ -213,7 +213,7 @@ class Client: table_client = self.Base.Config.TABLE_CLIENT account_to_check = {'account': account.lower()} - account_to_check_query = self.Base.db_execute_query(f""" + account_to_check_query = await self.Base.db_execute_query(f""" SELECT id FROM {table_client} WHERE LOWER(account) = :account """, account_to_check) diff --git a/core/classes/modules/rehash.py b/core/classes/modules/rehash.py index 6b96998..791fe9b 100644 --- a/core/classes/modules/rehash.py +++ b/core/classes/modules/rehash.py @@ -5,7 +5,7 @@ from typing import TYPE_CHECKING import socket if TYPE_CHECKING: - from core.irc import Irc + from core.loader import Loader # Modules impacted by rehashing! REHASH_MODULES = [ @@ -14,7 +14,10 @@ REHASH_MODULES = [ 'core.classes.modules.config', 'core.base', 'core.classes.modules.commands', - 'core.classes.modules.rpc', + 'core.classes.modules.rpc.rpc_channel', + 'core.classes.modules.rpc.rpc_command', + 'core.classes.modules.rpc.rpc_user', + 'core.classes.modules.rpc.rpc', 'core.classes.interfaces.iprotocol', 'core.classes.interfaces.imodule', 'core.classes.protocols.command_handler', @@ -24,66 +27,62 @@ REHASH_MODULES = [ ] -def restart_service(uplink: 'Irc', reason: str = "Restarting with no reason!") -> None: +async def restart_service(uplink: 'Loader', reason: str = "Restarting with no reason!") -> None: """ Args: uplink (Irc): The Irc instance reason (str): The reason of the restart. """ - # reload modules. + # unload modules. for module in uplink.ModuleUtils.model_get_loaded_modules().copy(): - uplink.ModuleUtils.unload_one_module(uplink, module.module_name) + await uplink.ModuleUtils.unload_one_module(module.module_name) uplink.Base.garbage_collector_thread() uplink.Logs.debug(f'[{uplink.Config.SERVICE_NICKNAME} RESTART]: Reloading configuration!') - uplink.Protocol.send_squit(server_id=uplink.Config.SERVEUR_ID, server_link=uplink.Config.SERVEUR_LINK, reason=reason) + await uplink.Irc.Protocol.send_squit(server_id=uplink.Config.SERVEUR_ID, server_link=uplink.Config.SERVEUR_LINK, reason=reason) uplink.Logs.debug('Restarting Defender ...') - uplink.IrcSocket.shutdown(socket.SHUT_RDWR) - uplink.IrcSocket.close() - - while uplink.IrcSocket.fileno() != -1: - time.sleep(0.5) - uplink.Logs.warning('-- Waiting for socket to close ...') - - # Reload configuration - uplink.Loader.Config = uplink.Loader.ConfModule.Configuration(uplink.Loader).configuration_model - uplink.Loader.Base = uplink.Loader.BaseModule.Base(uplink.Loader) for mod in REHASH_MODULES: importlib.reload(sys.modules[mod]) - uplink.Protocol = uplink.Loader.PFactory.get() - uplink.Protocol.register_command() + # Reload configuration + uplink.Config = uplink.ConfModule.Configuration(uplink).configuration_model + uplink.Base = uplink.BaseModule.Base(uplink) uplink.ModuleUtils.model_clear() # Clear loaded modules. uplink.User.UID_DB.clear() # Clear User Object uplink.Channel.UID_CHANNEL_DB.clear() # Clear Channel Object uplink.Client.CLIENT_DB.clear() # Clear Client object + uplink.Irc.Protocol.Handler.DB_IRCDCOMMS.clear() - uplink.init_service_user() - uplink.Utils.create_socket(uplink) - uplink.Protocol.send_link() + # Reload Service modules + for module in uplink.ModuleUtils.model_get_loaded_modules().copy(): + await uplink.ModuleUtils.reload_one_module(module.module_name, uplink.Settings.current_admin) + + uplink.Irc.signal = True + await uplink.Irc.run() uplink.Config.DEFENDER_RESTART = 0 -def rehash_service(uplink: 'Irc', nickname: str) -> None: +async def rehash_service(uplink: 'Loader', nickname: str) -> None: need_a_restart = ["SERVEUR_ID"] uplink.Settings.set_cache('db_commands', uplink.Commands.DB_COMMANDS) - uplink.Loader.RpcServer.stop_server() + + await uplink.RpcServer.stop_server() restart_flag = False config_model_bakcup = uplink.Config mods = REHASH_MODULES for mod in mods: importlib.reload(sys.modules[mod]) - uplink.Protocol.send_priv_msg( + await uplink.Irc.Protocol.send_priv_msg( nick_from=uplink.Config.SERVICE_NICKNAME, msg=f'[REHASH] Module [{mod}] reloaded', channel=uplink.Config.SERVICE_CHANLOG ) uplink.Utils = sys.modules['core.utils'] - uplink.Config = uplink.Loader.Config = uplink.Loader.ConfModule.Configuration(uplink.Loader).configuration_model + uplink.Config = uplink.ConfModule.Configuration(uplink).configuration_model uplink.Config.HSID = config_model_bakcup.HSID uplink.Config.DEFENDER_INIT = config_model_bakcup.DEFENDER_INIT uplink.Config.DEFENDER_RESTART = config_model_bakcup.DEFENDER_RESTART @@ -96,7 +95,7 @@ def rehash_service(uplink: 'Irc', nickname: str) -> None: for key, value in conf_bkp_dict.items(): if config_dict[key] != value and key != 'COLORS': - uplink.Protocol.send_priv_msg( + await uplink.Irc.Protocol.send_priv_msg( nick_from=uplink.Config.SERVICE_NICKNAME, msg=f'[{key}]: {value} ==> {config_dict[key]}', channel=uplink.Config.SERVICE_CHANLOG @@ -105,27 +104,28 @@ def rehash_service(uplink: 'Irc', nickname: str) -> None: restart_flag = True if config_model_bakcup.SERVICE_NICKNAME != uplink.Config.SERVICE_NICKNAME: - uplink.Protocol.send_set_nick(uplink.Config.SERVICE_NICKNAME) + await uplink.Irc.Protocol.send_set_nick(uplink.Config.SERVICE_NICKNAME) if restart_flag: uplink.Config.SERVEUR_ID = config_model_bakcup.SERVEUR_ID - uplink.Protocol.send_priv_msg( + await uplink.Irc.Protocol.send_priv_msg( nick_from=uplink.Config.SERVICE_NICKNAME, channel=uplink.Config.SERVICE_CHANLOG, msg='You need to restart defender !') # Reload Main Commands Module - uplink.Commands = uplink.Loader.CommandModule.Command(uplink.Loader) - uplink.Loader.RpcServer = uplink.Loader.RpcServerModule.JSONRPCServer(uplink.Loader) - uplink.Loader.RpcServer.start_server() + uplink.Commands = uplink.CommandModule.Command(uplink) uplink.Commands.DB_COMMANDS = uplink.Settings.get_cache('db_commands') - uplink.Loader.Base = uplink.Loader.BaseModule.Base(uplink.Loader) - uplink.Protocol = uplink.Loader.PFactory.get() - uplink.Protocol.register_command() + uplink.Base = uplink.BaseModule.Base(uplink) + uplink.Irc.Protocol = uplink.PFactory.get() + uplink.Irc.Protocol.register_command() + + uplink.RpcServer = uplink.RpcServerModule.JSonRpcServer(uplink) + uplink.Base.create_asynctask(uplink.RpcServer.start_server()) # Reload Service modules for module in uplink.ModuleUtils.model_get_loaded_modules().copy(): - uplink.ModuleUtils.reload_one_module(uplink, module.module_name, nickname) + await uplink.ModuleUtils.reload_one_module(module.module_name, nickname) return None \ No newline at end of file diff --git a/core/classes/modules/rpc/__init__.py b/core/classes/modules/rpc/__init__.py new file mode 100644 index 0000000..75977e6 --- /dev/null +++ b/core/classes/modules/rpc/__init__.py @@ -0,0 +1 @@ +__version__ = '1.0.0' \ No newline at end of file diff --git a/core/classes/modules/rpc/rpc.py b/core/classes/modules/rpc/rpc.py index 95170a0..b26e34e 100644 --- a/core/classes/modules/rpc/rpc.py +++ b/core/classes/modules/rpc/rpc.py @@ -1,8 +1,11 @@ import base64 import json -import logging +from starlette.applications import Starlette +from starlette.responses import JSONResponse +from starlette.requests import Request +from starlette.routing import Route +import uvicorn from enum import Enum -from http.server import BaseHTTPRequestHandler, HTTPServer from typing import TYPE_CHECKING, Any, Optional from core.classes.modules.rpc.rpc_user import RPCUser from core.classes.modules.rpc.rpc_channel import RPCChannel @@ -11,120 +14,101 @@ from core.classes.modules.rpc.rpc_command import RPCCommand if TYPE_CHECKING: from core.loader import Loader -ProxyLoader: Optional['Loader'] = None +class JSonRpcServer: -class RPCRequestHandler(BaseHTTPRequestHandler): + def __init__(self, context: 'Loader', *, hostname: str = 'localhost', port: int = 5000): + self._ctx = context + self.live: bool = False + self.host = hostname + self.port = port + self.routes: list[Route] = [] + self.server: Optional[uvicorn.Server] = None - def log_message(self, format, *args): - pass - - def do_POST(self): - logs = ProxyLoader.Logs - self.server_version = 'Defender6' - self.sys_version = ProxyLoader.Config.CURRENT_VERSION - content_length = int(self.headers['Content-Length']) - body = self.rfile.read(content_length) - request_data: dict = json.loads(body) - rip, rport = self.client_address - - if not self.authenticate(request_data): - return None - - response_data = { - 'jsonrpc': '2.0', - 'id': request_data.get('id', 123) + self.methods: dict = { + 'user.list': RPCUser(context).user_list, + 'user.get': RPCUser(context).user_get, + 'channel.list': RPCChannel(context).channel_list, + 'command.list': RPCCommand(context).command_list, + 'command.get.by.name': RPCCommand(context).command_get_by_name, + 'command.get.by.module': RPCCommand(context).command_get_by_module } - method = request_data.get("method") + async def start_server(self): + + if not self.live: + self.routes = [Route('/api', self.request_handler, methods=['POST'])] + self.app_jsonrpc = Starlette(debug=False, routes=self.routes) + config = uvicorn.Config(self.app_jsonrpc, host=self.host, port=self.port, log_level=self._ctx.Config.DEBUG_LEVEL) + self.server = uvicorn.Server(config) + self.live = True + await self._ctx.Irc.Protocol.send_priv_msg( + self._ctx.Config.SERVICE_NICKNAME, + "[DEFENDER JSONRPC SERVER] RPC Server started!", + self._ctx.Config.SERVICE_CHANLOG + ) + await self.server.serve() + self._ctx.Logs.debug("Server is going to shutdown!") + else: + self._ctx.Logs.debug("Server already running") + + async def stop_server(self): + + if self.server: + self.server.should_exit = True + await self.server.shutdown() + self.live = False + self._ctx.Logs.debug("JSON-RPC Server off!") + await self._ctx.Irc.Protocol.send_priv_msg( + self._ctx.Config.SERVICE_NICKNAME, + "[DEFENDER JSONRPC SERVER] RPC Server Stopped!", + self._ctx.Config.SERVICE_CHANLOG + ) + + async def request_handler(self, request: Request) -> JSONResponse: + + request_data: dict = await request.json() + method = request_data.get("method", None) params: dict[str, Any] = request_data.get("params", {}) + + auth: JSONResponse = self.authenticate(request.headers, request_data) + if not json.loads(auth.body).get('result', False): + return auth + + response_data = { + "jsonrpc": "2.0", + "id": request_data.get('id', 123) + } + response_data['method'] = method + rip = request.client.host + rport = request.client.port http_code = 200 - match method: - case 'user.list': - user = RPCUser(ProxyLoader) - response_data['result'] = user.user_list() - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del user - - case 'user.get': - user = RPCUser(ProxyLoader) - uid_or_nickname = params.get('uid_or_nickname', None) - response_data['result'] = user.user_get(uid_or_nickname) - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del user + if method in self.methods: + response_data['result'] = self.methods[method](**params) + return JSONResponse(response_data, http_code) - case 'channel.list': - channel = RPCChannel(ProxyLoader) - response_data['result'] = channel.channel_list() - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del channel + response_data['error'] = create_error_response(JSONRPCErrorCode.METHOD_NOT_FOUND) + self._ctx.Logs.debug(f'[RPC ERROR] {method} recieved from {rip}:{rport}') + http_code = 404 + return JSONResponse(response_data, http_code) - case 'command.list': - command = RPCCommand(ProxyLoader) - response_data['result'] = command.command_list() - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del command + def authenticate(self, headers: dict, body: dict) -> JSONResponse: + ok_auth = { + 'jsonrpc': '2.0', + 'id': body.get('id', 123), + 'result': True + } - case 'command.get.by.module': - command = RPCCommand(ProxyLoader) - module_name = params.get('name', None) - response_data['result'] = command.command_get_by_module(module_name) - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del command - - case 'command.get.by.name': - command = RPCCommand(ProxyLoader) - command_name = params.get('name', None) - response_data['result'] = command.command_get_by_name(command_name) - logs.debug(f'[RPC] {method} recieved from {rip}:{rport}') - del command - - case _: - response_data['error'] = create_error_response(JSONRPCErrorCode.METHOD_NOT_FOUND) - logs.debug(f'[RPC ERROR] {method} recieved from {rip}:{rport}') - http_code = 404 - - self.send_response(http_code) - self.send_header('Content-Type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) - - return None - - def do_GET(self): - self.server_version = 'Defender6' - self.sys_version = ProxyLoader.Config.CURRENT_VERSION - content_length = int(self.headers['Content-Length']) - body = self.rfile.read(content_length) - request_data: dict = json.loads(body) - - if not self.authenticate(request_data): - return None - - response_data = {'jsonrpc': '2.0', 'id': request_data.get('id', 321), - 'error': create_error_response(JSONRPCErrorCode.INVALID_REQUEST)} - - self.send_response(404) - self.send_header('Content-Type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) - - return None - - - def authenticate(self, request_data: dict) -> bool: - logs = ProxyLoader.Logs - auth = self.headers.get('Authorization', None) - if auth is None: - self.send_auth_error(request_data) - return False + logs = self._ctx.Logs + auth: str = headers.get('Authorization', '') + if not auth: + return self.send_auth_error(body) # Authorization header format: Basic base64(username:password) auth_type, auth_string = auth.split(' ', 1) if auth_type.lower() != 'basic': - self.send_auth_error(request_data) - return False + return self.send_auth_error(body) try: # Decode the base64-encoded username:password @@ -132,70 +116,25 @@ class RPCRequestHandler(BaseHTTPRequestHandler): username, password = decoded_credentials.split(":", 1) # Check the username and password. - for rpcuser in ProxyLoader.Irc.Config.RPC_USERS: + for rpcuser in self._ctx.Config.RPC_USERS: if rpcuser.get('USERNAME', None) == username and rpcuser.get('PASSWORD', None) == password: - return True + return JSONResponse(ok_auth) - self.send_auth_error(request_data) - return False + return self.send_auth_error(body) except Exception as e: - self.send_auth_error(request_data) logs.error(e) - return False + return self.send_auth_error(body) - def send_auth_error(self, request_data: dict) -> None: + def send_auth_error(self, request_data: dict) -> JSONResponse: response_data = { 'jsonrpc': '2.0', 'id': request_data.get('id', 123), 'error': create_error_response(JSONRPCErrorCode.AUTHENTICATION_ERROR) } + return JSONResponse(response_data) - self.send_response(401) - self.send_header('WWW-Authenticate', 'Basic realm="Authorization Required"') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) - -class JSONRPCServer: - def __init__(self, loader: 'Loader'): - global ProxyLoader - - ProxyLoader = loader - self._Loader = loader - self._Base = loader.Base - self._Logs = loader.Logs - self.rpc_server: Optional[HTTPServer] = None - self.connected: bool = False - - def start_server(self, server_class=HTTPServer, handler_class=RPCRequestHandler, *, hostname: str = 'localhost', port: int = 5000): - logging.getLogger('http.server').setLevel(logging.CRITICAL) - server_address = (hostname, port) - self.rpc_server = server_class(server_address, handler_class) - self._Logs.debug(f"Server ready on http://{hostname}:{port}...") - self._Base.create_thread(self.thread_start_rpc_server, (), True) - - def thread_start_rpc_server(self) -> None: - self._Loader.Irc.Protocol.send_priv_msg( - self._Loader.Config.SERVICE_NICKNAME, "Defender RPC Server has started successfuly!", self._Loader.Config.SERVICE_CHANLOG - ) - self.connected = True - self.rpc_server.serve_forever() - ProxyLoader.Logs.debug(f"RPC Server down!") - - def stop_server(self): - self._Base.create_thread(self.thread_stop_rpc_server) - - def thread_stop_rpc_server(self): - self.rpc_server.shutdown() - ProxyLoader.Logs.debug(f"RPC Server shutdown!") - self.rpc_server.server_close() - ProxyLoader.Logs.debug(f"RPC Server clean-up!") - self._Base.garbage_collector_thread() - self._Loader.Irc.Protocol.send_priv_msg( - self._Loader.Config.SERVICE_NICKNAME, "Defender RPC Server has stopped successfuly!", self._Loader.Config.SERVICE_CHANLOG - ) - self.connected = False class JSONRPCErrorCode(Enum): PARSE_ERROR = -32700 # Syntax error in the request (malformed JSON) diff --git a/core/classes/modules/rpc/rpc_channel.py b/core/classes/modules/rpc/rpc_channel.py index e45e782..4f39338 100644 --- a/core/classes/modules/rpc/rpc_channel.py +++ b/core/classes/modules/rpc/rpc_channel.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING if TYPE_CHECKING: from core.loader import Loader @@ -8,5 +8,5 @@ class RPCChannel: self._Loader = loader self._Channel = loader.Channel - def channel_list(self) -> list[dict]: + def channel_list(self, **kwargs) -> list[dict]: return [chan.to_dict() for chan in self._Channel.UID_CHANNEL_DB] \ No newline at end of file diff --git a/core/classes/modules/rpc/rpc_command.py b/core/classes/modules/rpc/rpc_command.py index 1c2025d..230af53 100644 --- a/core/classes/modules/rpc/rpc_command.py +++ b/core/classes/modules/rpc/rpc_command.py @@ -8,14 +8,22 @@ class RPCCommand: self._Loader = loader self._Command = loader.Commands - def command_list(self) -> list[dict]: + def command_list(self, **kwargs) -> list[dict]: return [command.to_dict() for command in self._Command.DB_COMMANDS] - def command_get_by_module(self, module_name: str) -> list[dict]: + def command_get_by_module(self, **kwargs) -> list[dict]: + module_name = kwargs.get('module_name', None) + if module_name is None: + return [] + return [command.to_dict() for command in self._Command.DB_COMMANDS if command.module_name.lower() == module_name.lower()] - def command_get_by_name(self, command_name: str) -> dict: + def command_get_by_name(self, **kwargs) -> dict: + command_name: str = kwargs.get('command_name', '') + if not command_name: + return dict() + for command in self._Command.DB_COMMANDS: if command.command_name.lower() == command_name.lower(): return command.to_dict() - return {} \ No newline at end of file + return dict() \ No newline at end of file diff --git a/core/classes/modules/rpc/rpc_user.py b/core/classes/modules/rpc/rpc_user.py index b9e014b..bf8a323 100644 --- a/core/classes/modules/rpc/rpc_user.py +++ b/core/classes/modules/rpc/rpc_user.py @@ -6,11 +6,10 @@ if TYPE_CHECKING: class RPCUser: def __init__(self, loader: 'Loader'): - self._Loader = loader - self._User = loader.User + self._ctx = loader - def user_list(self) -> list[dict]: - users = self._User.UID_DB.copy() + def user_list(self, **kwargs) -> list[dict]: + users = self._ctx.User.UID_DB.copy() copy_users: list['MUser'] = [] for user in users: @@ -20,8 +19,9 @@ class RPCUser: return [user.to_dict() for user in copy_users] - def user_get(self, uidornickname: str) -> Optional[dict]: - user = self._User.get_user(uidornickname) + def user_get(self, **kwargs) -> Optional[dict]: + uidornickname = kwargs.get('uid_or_nickname', None) + user = self._ctx.User.get_user(uidornickname) if user: user_copy = user.copy() user_copy.connexion_datetime = user_copy.connexion_datetime.strftime('%d-%m-%Y') diff --git a/core/classes/protocols/factory.py b/core/classes/protocols/factory.py index 6d30ffe..0ae4425 100644 --- a/core/classes/protocols/factory.py +++ b/core/classes/protocols/factory.py @@ -4,30 +4,29 @@ from .inspircd import Inspircd from ..interfaces.iprotocol import IProtocol if TYPE_CHECKING: - from core.irc import Irc + from core.loader import Loader class ProtocolFactorty: - def __init__(self, uplink: 'Irc'): + def __init__(self, context: 'Loader'): """ProtocolFactory init. Args: - uplink (Irc): The Irc object + context (Loader): The Context object """ - self.__Config = uplink.Config - self.__uplink = uplink + self.__ctx = context def get(self) -> Optional[IProtocol]: - protocol = self.__Config.SERVEUR_PROTOCOL + protocol = self.__ctx.Config.SERVEUR_PROTOCOL match protocol: case 'unreal6': - self.__uplink.Logs.debug(f"[PROTOCOL] {protocol} has been loaded") - return Unrealircd6(self.__uplink) + self.__ctx.Logs.debug(f"[PROTOCOL] {protocol} has been loaded") + return Unrealircd6(self.__ctx) case 'inspircd': - self.__uplink.Logs.debug(f"[PROTOCOL] {protocol} has been loaded") - return Inspircd(self.__uplink) + self.__ctx.Logs.debug(f"[PROTOCOL] {protocol} has been loaded") + return Inspircd(self.__ctx) case _: - self.__uplink.Logs.critical(f"[PROTOCOL ERROR] This protocol name ({protocol} is not valid!)") + self.__ctx.Logs.critical(f"[PROTOCOL ERROR] This protocol name ({protocol} is not valid!)") raise Exception("Unknown protocol!") diff --git a/core/classes/protocols/inspircd.py b/core/classes/protocols/inspircd.py index 52704af..f8a6f71 100644 --- a/core/classes/protocols/inspircd.py +++ b/core/classes/protocols/inspircd.py @@ -1,6 +1,6 @@ import sys from base64 import b64decode -from re import match, findall, search +from re import A, match, findall, search from datetime import datetime from typing import TYPE_CHECKING, Any, Optional from ssl import SSLEOFError, SSLError @@ -12,7 +12,7 @@ if TYPE_CHECKING: class Inspircd(IProtocol): - def init_protocol(self): + async def init_protocol(self): self.name = 'InspIRCd-4' self.protocol_version = 1206 @@ -23,7 +23,7 @@ class Inspircd(IProtocol): 'MODE', 'QUIT', 'SQUIT', 'VERSION'} - def get_ircd_protocol_poisition(self, cmd: list[str], log: bool = False) -> tuple[int, Optional[str]]: + async def get_ircd_protocol_poisition(self, cmd: list[str], log: bool = False) -> tuple[int, Optional[str]]: """Get the position of known commands Args: @@ -38,12 +38,12 @@ class Inspircd(IProtocol): return index, token.upper() if log: - self._Logs.debug(f"[IRCD LOGS] You need to handle this response: {cmd}") + self._ctx.Logs.debug(f"[IRCD LOGS] You need to handle this response: {cmd}") return -1, None - def register_command(self): - m = self._Irc.Loader.Definition.MIrcdCommand + async def register_command(self): + m = self._ctx.Definition.MIrcdCommand self.Handler.register(m('PING', self.on_server_ping)) self.Handler.register(m('NICK', self.on_nick)) self.Handler.register(m('SASL', self.on_sasl)) @@ -58,7 +58,7 @@ class Inspircd(IProtocol): self.Handler.register(m('ENDBURST', self.on_endburst)) self.Handler.register(m('METADATA', self.on_metedata)) - def send2socket(self, message: str, print_log: bool = True) -> None: + async def send2socket(self, message: str, print_log: bool = True) -> None: """Envoit les commandes à envoyer au serveur. Args: @@ -66,31 +66,32 @@ class Inspircd(IProtocol): print_log (bool): if True print the log. """ try: - with self._Base.lock: - self._Irc.IrcSocket.send(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[0])) + with self._ctx.Settings.AILOCK: + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[0])) + await self._ctx.Irc.writer.drain() if print_log: - self._Logs.debug(f'<< {message}') + self._ctx.Logs.debug(f'<< {message}') except UnicodeDecodeError as ude: - self._Logs.error(f'Decode Error try iso-8859-1 - {ude} - {message}') - self._Irc.IrcSocket.send(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[1],'replace')) + self._ctx.Logs.error(f'Decode Error try iso-8859-1 - {ude} - {message}') + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[1],'replace')) except UnicodeEncodeError as uee: - self._Logs.error(f'Encode Error try iso-8859-1 - {uee} - {message}') - self._Irc.IrcSocket.send(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[1],'replace')) + self._ctx.Logs.error(f'Encode Error try iso-8859-1 - {uee} - {message}') + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[1],'replace')) except AssertionError as ae: - self._Logs.warning(f'Assertion Error {ae} - message: {message}') + self._ctx.Logs.warning(f'Assertion Error {ae} - message: {message}') except SSLEOFError as soe: - self._Logs.error(f"SSLEOFError: {soe} - {message}") + self._ctx.Logs.error(f"SSLEOFError: {soe} - {message}") except SSLError as se: - self._Logs.error(f"SSLError: {se} - {message}") + self._ctx.Logs.error(f"SSLError: {se} - {message}") except OSError as oe: - self._Logs.error(f"OSError: {oe} - {message}") + self._ctx.Logs.error(f"OSError: {oe} - {message}") if oe.errno == 10053: sys.exit(oe.__str__()) except AttributeError as ae: - self._Logs.critical(f"Attribute Error: {ae}") + self._ctx.Logs.critical(f"Attribute Error: {ae}") - def send_priv_msg(self, nick_from: str, msg: str, channel: str = None, nick_to: str = None): + async def send_priv_msg(self, nick_from: str, msg: str, channel: str = None, nick_to: str = None): """Sending PRIVMSG to a channel or to a nickname by batches could be either channel or nickname not both together Args: @@ -100,27 +101,27 @@ class Inspircd(IProtocol): nick_to (str, optional): The reciever nickname. Defaults to None. """ try: - batch_size = self._Config.BATCH_SIZE - user_from = self._Irc.User.get_user(nick_from) - user_to = self._Irc.User.get_user(nick_to) if nick_to is not None else None + batch_size = self._ctx.Config.BATCH_SIZE + user_from = self._ctx.User.get_user(nick_from) + user_to = self._ctx.User.get_user(nick_to) if nick_to is not None else None if user_from is None: - self._Logs.error(f"The sender nickname [{nick_from}] do not exist") + self._ctx.Logs.error(f"The sender nickname [{nick_from}] do not exist") return None if not channel is None: for i in range(0, len(str(msg)), batch_size): batch = str(msg)[i:i+batch_size] - self.send2socket(f":{user_from.uid} PRIVMSG {channel} :{batch}") + await self.send2socket(f":{user_from.uid} PRIVMSG {channel} :{batch}") if not nick_to is None: for i in range(0, len(str(msg)), batch_size): batch = str(msg)[i:i+batch_size] - self.send2socket(f":{nick_from} PRIVMSG {user_to.uid} :{batch}") + await self.send2socket(f":{nick_from} PRIVMSG {user_to.uid} :{batch}") except Exception as err: - self._Logs.error(f"General Error: {err}") + self._ctx.Logs.error(f"General Error: {err}") - def send_notice(self, nick_from: str, nick_to: str, msg: str) -> None: + async def send_notice(self, nick_from: str, nick_to: str, msg: str) -> None: """Sending NOTICE by batches Args: @@ -129,71 +130,71 @@ class Inspircd(IProtocol): nick_to (str): The reciever nickname """ try: - batch_size = self._Config.BATCH_SIZE - user_from = self._Irc.User.get_user(nick_from) - user_to = self._Irc.User.get_user(nick_to) + batch_size = self._ctx.Config.BATCH_SIZE + user_from = self._ctx.User.get_user(nick_from) + user_to = self._ctx.User.get_user(nick_to) if user_from is None or user_to is None: - self._Logs.error(f"The sender [{nick_from}] or the Reciever [{nick_to}] do not exist") + self._ctx.Logs.error(f"The sender [{nick_from}] or the Reciever [{nick_to}] do not exist") return None for i in range(0, len(str(msg)), batch_size): batch = str(msg)[i:i+batch_size] - self.send2socket(f":{user_from.uid} NOTICE {user_to.uid} :{batch}") + await self.send2socket(f":{user_from.uid} NOTICE {user_to.uid} :{batch}") except Exception as err: - self._Logs.error(f"General Error: {err}") + self._ctx.Logs.error(f"General Error: {err}") - def send_link(self): + async def send_link(self): """Créer le link et envoyer les informations nécessaires pour la connexion au serveur. """ - service_id = self._Config.SERVICE_ID - service_nickname = self._Config.SERVICE_NICKNAME - service_username = self._Config.SERVICE_USERNAME - service_realname = self._Config.SERVICE_REALNAME - service_info = self._Config.SERVICE_INFO - service_smodes = self._Config.SERVICE_SMODES - service_hostname = self._Config.SERVICE_HOST - service_name = self._Config.SERVICE_NAME + service_id = self._ctx.Config.SERVICE_ID + service_nickname = self._ctx.Config.SERVICE_NICKNAME + service_username = self._ctx.Config.SERVICE_USERNAME + service_realname = self._ctx.Config.SERVICE_REALNAME + service_info = self._ctx.Config.SERVICE_INFO + service_smodes = self._ctx.Config.SERVICE_SMODES + service_hostname = self._ctx.Config.SERVICE_HOST + service_name = self._ctx.Config.SERVICE_NAME - server_password = self._Config.SERVEUR_PASSWORD - server_link = self._Config.SERVEUR_LINK - server_id = self._Config.SERVEUR_ID - server_hostname = self._Settings.MAIN_SERVER_HOSTNAME = self._Config.SERVEUR_HOSTNAME + server_password = self._ctx.Config.SERVEUR_PASSWORD + server_link = self._ctx.Config.SERVEUR_LINK + server_id = self._ctx.Config.SERVEUR_ID + server_hostname = self._ctx.Settings.MAIN_SERVER_HOSTNAME = self._ctx.Config.SERVEUR_HOSTNAME - version = self._Config.CURRENT_VERSION - unixtime = self._Utils.get_unixtime() + version = self._ctx.Config.CURRENT_VERSION + unixtime = self._ctx.Utils.get_unixtime() - self.send2socket(f"CAPAB START {self.protocol_version}") - self.send2socket(f"CAPAB MODULES :services") - self.send2socket(f"CAPAB MODSUPPORT :") - self.send2socket(f"CAPAB CAPABILITIES :NICKMAX=30 CHANMAX=64 MAXMODES=20 IDENTMAX=10 MAXQUIT=255 MAXTOPIC=307 MAXKICK=255 MAXREAL=128 MAXAWAY=200 MAXHOST=64 MAXLINE=512 CASEMAPPING=ascii GLOBOPS=0") - self.send2socket(f"CAPAB END") - self.send2socket(f"SERVER {server_link} {server_password} {server_id} :{service_info}") - self.send2socket(f"BURST {unixtime}") - self.send2socket(f":{server_id} SINFO version :{service_name}-{version.split('.')[0]}. {server_hostname} :") - self.send2socket(f":{server_id} SINFO fullversion :{service_name}-{version}. {service_hostname} :") - self.send2socket(f":{server_id} SINFO rawversion :{service_name}-{version}") - self.send_uid(service_nickname, service_username, service_hostname, service_id, service_smodes, service_hostname, "127.0.0.1", service_realname) - self.send2socket(f":{server_id} ENDBURST") + await self.send2socket(f"CAPAB START {self.protocol_version}") + await self.send2socket(f"CAPAB MODULES :services") + await self.send2socket(f"CAPAB MODSUPPORT :") + await self.send2socket(f"CAPAB CAPABILITIES :NICKMAX=30 CHANMAX=64 MAXMODES=20 IDENTMAX=10 MAXQUIT=255 MAXTOPIC=307 MAXKICK=255 MAXREAL=128 MAXAWAY=200 MAXHOST=64 MAXLINE=512 CASEMAPPING=ascii GLOBOPS=0") + await self.send2socket(f"CAPAB END") + await self.send2socket(f"SERVER {server_link} {server_password} {server_id} :{service_info}") + await self.send2socket(f"BURST {unixtime}") + await self.send2socket(f":{server_id} SINFO version :{service_name}-{version.split('.')[0]}. {server_hostname} :") + await self.send2socket(f":{server_id} SINFO fullversion :{service_name}-{version}. {service_hostname} :") + await self.send2socket(f":{server_id} SINFO rawversion :{service_name}-{version}") + await self.send_uid(service_nickname, service_username, service_hostname, service_id, service_smodes, service_hostname, "127.0.0.1", service_realname) + await self.send2socket(f":{server_id} ENDBURST") # self.send_sjoin(chan) - self._Logs.debug(f'>> {__name__} Link information sent to the server') + self._ctx.Logs.debug(f'>> {__name__} Link information sent to the server') - def gline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: + async def gline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: # TKL + G user host set_by expire_timestamp set_at_timestamp :reason - self.send2socket(f":{self._Config.SERVEUR_ID} TKL + G {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL + G {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") return None - def send_set_nick(self, newnickname: str) -> None: + async def send_set_nick(self, newnickname: str) -> None: - self.send2socket(f":{self._Config.SERVICE_NICKNAME} NICK {newnickname}") + await self.send2socket(f":{self._ctx.Config.SERVICE_NICKNAME} NICK {newnickname}") return None - def send_set_mode(self, modes: str, *, nickname: Optional[str] = None, channel_name: Optional[str] = None, params: Optional[str] = None) -> None: + async def send_set_mode(self, modes: str, *, nickname: Optional[str] = None, channel_name: Optional[str] = None, params: Optional[str] = None) -> None: """Set a mode to channel or to a nickname or for a user in a channel Args: @@ -202,94 +203,94 @@ class Inspircd(IProtocol): channel_name (Optional[str]): The channel name params (Optional[str]): Params to pass to the mode """ - service_id = self._Config.SERVICE_ID + service_id = self._ctx.Config.SERVICE_ID params = '' if params is None else params if modes[0] not in ['+', '-']: - self._Logs.error(f"[MODE ERROR] The mode you have provided is missing the sign: {modes}") + self._ctx.Logs.error(f"[MODE ERROR] The mode you have provided is missing the sign: {modes}") return None if nickname and channel_name: - # :98KAAAAAB MODE #services +o defenderdev - if not self._Irc.Channel.is_valid_channel(channel_name): - self._Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") + # :98KAAAAAB MODE #services +o async defenderdev + if not self._ctx.Channel.is_valid_channel(channel_name): + self._ctx.Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") return None - if not all(mode in self._Settings.PROTOCTL_PREFIX_MODES_SIGNES for mode in list(modes.replace('+','').replace('-',''))): - self._Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') + if not all(mode in self._ctx.Settings.PROTOCTL_PREFIX_MODES_SIGNES for mode in list(modes.replace('+','').replace('-',''))): + self._ctx.Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') return None - self.send2socket(f":{service_id} MODE {channel_name} {modes} {nickname}") + await self.send2socket(f":{service_id} MODE {channel_name} {modes} {nickname}") return None if nickname and channel_name is None: # :98KAAAAAB MODE nickname +o - if not all(mode in self._Settings.PROTOCTL_USER_MODES for mode in list(modes.replace('+','').replace('-',''))): - self._Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') + if not all(mode in self._ctx.Settings.PROTOCTL_USER_MODES for mode in list(modes.replace('+','').replace('-',''))): + self._ctx.Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') return None - self.send2socket(f":{service_id} MODE {nickname} {modes}") + await self.send2socket(f":{service_id} MODE {nickname} {modes}") return None if nickname is None and channel_name: # :98KAAAAAB MODE #channel +o - if not all(mode in self._Settings.PROTOCTL_CHANNEL_MODES for mode in list(modes.replace('+','').replace('-',''))): - self._Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') + if not all(mode in self._ctx.Settings.PROTOCTL_CHANNEL_MODES for mode in list(modes.replace('+','').replace('-',''))): + self._ctx.Logs.debug(f'[USERMODE UNVAILABLE] This mode {modes} is not available!') return None - if not self._Irc.Channel.is_valid_channel(channel_name): - self._Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") + if not self._ctx.Channel.is_valid_channel(channel_name): + self._ctx.Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") return None - self.send2socket(f":{service_id} MODE {channel_name} {modes} {params}") + await self.send2socket(f":{service_id} MODE {channel_name} {modes} {params}") return None return None - def send_squit(self, server_id: str, server_link: str, reason: str) -> None: + async def send_squit(self, server_id: str, server_link: str, reason: str) -> None: if not reason: reason = 'Service Shutdown' - self.send2socket(f":{server_id} SQUIT {server_link} :{reason}") + await self.send2socket(f":{server_id} SQUIT {server_link} :{reason}") return None - def send_ungline(self, nickname: str, hostname: str) -> None: + async def send_ungline(self, nickname: str, hostname: str) -> None: - self.send2socket(f":{self._Config.SERVEUR_ID} TKL - G {nickname} {hostname} {self._Config.SERVICE_NICKNAME}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL - G {nickname} {hostname} {self._ctx.Config.SERVICE_NICKNAME}") return None - def send_kline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: + async def send_kline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: # TKL + k user host set_by expire_timestamp set_at_timestamp :reason - self.send2socket(f":{self._Config.SERVEUR_ID} TKL + k {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL + k {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") return None - def send_sjoin(self, channel: str) -> None: + async def send_sjoin(self, channel: str) -> None: """Service join a channel Args: channel (str): The channel name. """ - server_id = self._Config.SERVEUR_ID - service_nickname = self._Config.SERVICE_NICKNAME - service_modes = self._Config.SERVICE_UMODES - service_id = self._Config.SERVICE_ID + server_id = self._ctx.Config.SERVEUR_ID + service_nickname = self._ctx.Config.SERVICE_NICKNAME + service_modes = self._ctx.Config.SERVICE_UMODES + service_id = self._ctx.Config.SERVICE_ID - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None - self.send2socket(f":{server_id} FJOIN {channel} {self._Utils.get_unixtime()} :o, {service_id}") + await self.send2socket(f":{server_id} FJOIN {channel} {self._ctx.Utils.get_unixtime()} :o, {service_id}") self.send_set_mode(service_modes, nickname=service_nickname, channel_name=channel) - # Add defender to the channel uids list - self._Irc.Channel.insert(self._Irc.Loader.Definition.MChannel(name=channel, uids=[service_id])) + # Add async defender to the channel uids list + self._ctx.Channel.insert(self._ctx.Definition.MChannel(name=channel, uids=[service_id])) return None - def send_quit(self, uid: str, reason: str, print_log: bool = True) -> None: + async def send_quit(self, uid: str, reason: str, print_log: bool = True) -> None: """Send quit message Args: @@ -297,22 +298,22 @@ class Inspircd(IProtocol): reason (str): The reason for the quit print_log (bool): If True then print logs """ - user_obj = self._Irc.User.get_user(uidornickname=uid) - reputation_obj = self._Irc.Reputation.get_reputation(uidornickname=uid) + user_obj = self._ctx.User.get_user(uidornickname=uid) + reputation_obj = self._ctx.Reputation.get_reputation(uidornickname=uid) if not user_obj is None: - self.send2socket(f":{user_obj.uid} QUIT :{reason}", print_log=print_log) - self._Irc.User.delete(user_obj.uid) + await self.send2socket(f":{user_obj.uid} QUIT :{reason}", print_log=print_log) + self._ctx.User.delete(user_obj.uid) if not reputation_obj is None: - self._Irc.Reputation.delete(reputation_obj.uid) + self._ctx.Reputation.delete(reputation_obj.uid) - if not self._Irc.Channel.delete_user_from_all_channel(uid): - self._Logs.error(f"The UID [{uid}] has not been deleted from all channels") + if not self._ctx.Channel.delete_user_from_all_channel(uid): + self._ctx.Logs.error(f"The UID [{uid}] has not been deleted from all channels") return None - def send_uid(self, nickname: str, username: str, hostname: str, + async def send_uid(self, nickname: str, username: str, hostname: str, uid:str, umodes: str, vhost: str, remote_ip: str, realname: str, print_log: bool = True) -> None: """Send UID to the server @@ -329,20 +330,20 @@ class Inspircd(IProtocol): print_log (bool, optional): print logs if true. Defaults to True. """ # {self.Config.SERVEUR_ID} UID - # {clone.nickname} 1 {self._Utils.get_unixtime()} {clone.username} {clone.hostname} {clone.uid} * {clone.umodes} {clone.vhost} * {self.Base.encode_ip(clone.remote_ip)} :{clone.realname} + # {clone.nickname} 1 {self._ctx.Utils.get_unixtime()} {clone.username} {clone.hostname} {clone.uid} * {clone.umodes} {clone.vhost} * {self.Base.encode_ip(clone.remote_ip)} :{clone.realname} try: - unixtime = self._Utils.get_unixtime() - # encoded_ip = self._Base.encode_ip(remote_ip) + unixtime = self._ctx.Utils.get_unixtime() + # encoded_ip = self._ctx.Base.encode_ip(remote_ip) new_umodes = [] for mode in list(umodes.replace('+', '').replace('-', '')): - if mode in self._Settings.PROTOCTL_USER_MODES: + if mode in self._ctx.Settings.PROTOCTL_USER_MODES: new_umodes.append(mode) final_umodes = '+' + ''.join(new_umodes) # Create the user - self._Irc.User.insert( - self._Irc.Loader.Definition.MUser( + self._ctx.User.insert( + self._ctx.Definition.MUser( uid=uid, nickname=nickname, username=username, realname=realname,hostname=hostname, umodes=final_umodes, vhost=vhost, remote_ip=remote_ip @@ -350,17 +351,17 @@ class Inspircd(IProtocol): ) # [:] UID []+ : - # :98K UID 98KAAAAAB 1756932359 defenderdev defenderdev.deb.biz.st defenderdev.deb.biz.st Dev-PyDefender 127.0.0.1 1756932359 + :Dev Python Security + # :98K UID 98KAAAAAB 1756932359 async defenderdev async defenderdev.deb.biz.st async defenderdev.deb.biz.st Dev-PyDefender 127.0.0.1 1756932359 + :Dev Python Security # [':97K', 'UID', '97KAAAAAA', '1756926679', 'adator', '172.18.128.1', 'attila.example.org', '...', '...', '172.18.128.1', '1756926678', '+o', ':...'] - uid_msg = f":{self._Config.SERVEUR_ID} UID {uid} {unixtime} {nickname} {hostname} {vhost} {username} {username} {remote_ip} {unixtime} {final_umodes} :{realname}" - self.send2socket(uid_msg, print_log=print_log) + uid_msg = f":{self._ctx.Config.SERVEUR_ID} UID {uid} {unixtime} {nickname} {hostname} {vhost} {username} {username} {remote_ip} {unixtime} {final_umodes} :{realname}" + await self.send2socket(uid_msg, print_log=print_log) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def send_join_chan(self, uidornickname: str, channel: str, password: str = None, print_log: bool = True) -> None: + async def send_join_chan(self, uidornickname: str, channel: str, password: str = None, print_log: bool = True) -> None: """Joining a channel Args: @@ -370,23 +371,23 @@ class Inspircd(IProtocol): print_log (bool, optional): Write logs. Defaults to True. """ - user_obj = self._Irc.User.get_user(uidornickname) + user_obj = self._ctx.User.get_user(uidornickname) password_channel = password if not password is None else '' if user_obj is None: return None - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None - self.send2socket(f":{user_obj.uid} FJOIN {channel} {self._Utils.get_unixtime()} :,{user_obj.uid} {password_channel}", print_log=print_log) + await self.send2socket(f":{user_obj.uid} FJOIN {channel} {self._ctx.Utils.get_unixtime()} :,{user_obj.uid} {password_channel}", print_log=print_log) - # Add defender to the channel uids list - self._Irc.Channel.insert(self._Irc.Loader.Definition.MChannel(name=channel, uids=[user_obj.uid])) + # Add async defender to the channel uids list + self._ctx.Channel.insert(self._ctx.Definition.MChannel(name=channel, uids=[user_obj.uid])) return None - def send_part_chan(self, uidornickname: str, channel: str, print_log: bool = True) -> None: + async def send_part_chan(self, uidornickname: str, channel: str, print_log: bool = True) -> None: """Part from a channel Args: @@ -395,38 +396,38 @@ class Inspircd(IProtocol): print_log (bool, optional): Write logs. Defaults to True. """ - user_obj = self._Irc.User.get_user(uidornickname) + user_obj = self._ctx.User.get_user(uidornickname) if user_obj is None: - self._Logs.error(f"The user [{uidornickname}] is not valid") + self._ctx.Logs.error(f"The user [{uidornickname}] is not valid") return None - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None - self.send2socket(f":{user_obj.uid} PART {channel}", print_log=print_log) + await self.send2socket(f":{user_obj.uid} PART {channel}", print_log=print_log) - # Add defender to the channel uids list - self._Irc.Channel.delete_user_from_channel(channel, user_obj.uid) + # Add async defender to the channel uids list + self._ctx.Channel.delete_user_from_channel(channel, user_obj.uid) return None - def send_unkline(self, nickname: str, hostname: str) -> None: + async def send_unkline(self, nickname: str, hostname: str) -> None: - self.send2socket(f":{self._Config.SERVEUR_ID} TKL - K {nickname} {hostname} {self._Config.SERVICE_NICKNAME}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL - K {nickname} {hostname} {self._ctx.Config.SERVICE_NICKNAME}") return None - def send_raw(self, raw_command: str) -> None: + async def send_raw(self, raw_command: str) -> None: - self.send2socket(f":{self._Config.SERVEUR_ID} {raw_command}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} {raw_command}") return None # ------------------------------------------------------------------------ # RECIEVED IRC MESSAGES # ------------------------------------------------------------------------ - def on_umode2(self, server_msg: list[str]) -> None: + async def on_umode2(self, server_msg: list[str]) -> None: """Handle umode2 coming from a server Args: @@ -435,25 +436,25 @@ class Inspircd(IProtocol): try: # [':adator_', 'UMODE2', '-iwx'] - user_obj = self._Irc.User.get_user(str(server_msg[0]).lstrip(':')) + user_obj = self._ctx.User.get_user(str(server_msg[0]).lstrip(':')) user_mode = server_msg[2] if user_obj is None: # If user is not created return None # TODO : User object should be able to update user modes - if self._Irc.User.update_mode(user_obj.uid, user_mode): + if self._ctx.User.update_mode(user_obj.uid, user_mode): return None - # self._Logs.debug(f"Updating user mode for [{userObj.nickname}] [{old_umodes}] => [{userObj.umodes}]") + # self._ctx.Logs.debug(f"Updating user mode for [{userObj.nickname}] [{old_umodes}] => [{userObj.umodes}]") return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_quit(self, server_msg: list[str]) -> None: + async def on_quit(self, server_msg: list[str]) -> None: """Handle quit coming from a server >> [':97KAAAAAZ', 'QUIT', ':Quit:', '....'] Args: @@ -463,40 +464,40 @@ class Inspircd(IProtocol): uid_who_quit = str(server_msg[0]).lstrip(':') - self._Irc.Channel.delete_user_from_all_channel(uid_who_quit) - self._Irc.User.delete(uid_who_quit) - self._Irc.Reputation.delete(uid_who_quit) + self._ctx.Channel.delete_user_from_all_channel(uid_who_quit) + self._ctx.User.delete(uid_who_quit) + self._ctx.Reputation.delete(uid_who_quit) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_squit(self, server_msg: list[str]) -> None: + async def on_squit(self, server_msg: list[str]) -> None: """Handle squit coming from a server Args: server_msg (list[str]): Original server message """ - # ['@msgid=QOEolbRxdhpVW5c8qLkbAU;time=2024-09-21T17:33:16.547Z', 'SQUIT', 'defender.deb.biz.st', ':Connection', 'closed'] + # ['@msgid=QOEolbRxdhpVW5c8qLkbAU;time=2024-09-21T17:33:16.547Z', 'SQUIT', 'async defender.deb.biz.st', ':Connection', 'closed'] server_hostname = server_msg[2] uid_to_delete = None - for s_user in self._Irc.User.UID_DB: + for s_user in self._ctx.User.UID_DB: if s_user.hostname == server_hostname and 'S' in s_user.umodes: uid_to_delete = s_user.uid if uid_to_delete is None: return None - self._Irc.User.delete(uid_to_delete) - self._Irc.Channel.delete_user_from_all_channel(uid_to_delete) + self._ctx.User.delete(uid_to_delete) + self._ctx.Channel.delete_user_from_all_channel(uid_to_delete) return None - def on_protoctl(self, server_msg: list[str]) -> None: + async def on_protoctl(self, server_msg: list[str]) -> None: """Handle CAPAB coming from a server Args: @@ -525,9 +526,9 @@ class Inspircd(IProtocol): channel_modes.append(cmode) - self._Settings.PROTOCTL_PREFIX_SIGNES_MODES = sign_mode - self._Settings.PROTOCTL_PREFIX_MODES_SIGNES = mode_sign - self._Settings.PROTOCTL_CHANNEL_MODES = list(set(channel_modes)) + self._ctx.Settings.PROTOCTL_PREFIX_SIGNES_MODES = sign_mode + self._ctx.Settings.PROTOCTL_PREFIX_MODES_SIGNES = mode_sign + self._ctx.Settings.PROTOCTL_CHANNEL_MODES = list(set(channel_modes)) # ['CAPAB', 'USERMODES', ':param-set:snomask=s', 'simple:bot=B', 'simple:invisible=i', 'simple:oper=o', 'simple:servprotect=k', # 'simple:sslqueries=z', 'simple:u_registered=r', 'simple:wallops=w'] @@ -539,11 +540,11 @@ class Inspircd(IProtocol): umode = prefix.split('=')[1] if len(prefix.split('=')) > 1 else None user_modes.append(umode) - self._Settings.PROTOCTL_USER_MODES = list(set(user_modes)) + self._ctx.Settings.PROTOCTL_USER_MODES = list(set(user_modes)) return None - def on_nick(self, server_msg: list[str]) -> None: + async def on_nick(self, server_msg: list[str]) -> None: """Handle nick coming from a server new nickname @@ -560,18 +561,18 @@ class Inspircd(IProtocol): uid = str(scopy[0]).replace(':','') newnickname = scopy[2] - self._Irc.User.update_nickname(uid, newnickname) - self._Irc.Client.update_nickname(uid, newnickname) - self._Irc.Admin.update_nickname(uid, newnickname) + self._ctx.User.update_nickname(uid, newnickname) + self._ctx.Client.update_nickname(uid, newnickname) + self._ctx.Admin.update_nickname(uid, newnickname) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_sjoin(self, server_msg: list[str]) -> None: + async def on_sjoin(self, server_msg: list[str]) -> None: """Handle sjoin coming from a server Args: @@ -591,8 +592,8 @@ class Inspircd(IProtocol): list_users = list(set(list_users)) if list_users: - self._Irc.Channel.insert( - self._Irc.Loader.Definition.MChannel( + self._ctx.Channel.insert( + self._ctx.Definition.MChannel( name=channel, uids=list_users ) @@ -600,11 +601,11 @@ class Inspircd(IProtocol): return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_endburst(self, server_msg: list[str]) -> None: + async def on_endburst(self, server_msg: list[str]) -> None: """Handle EOS coming from a server Args: @@ -614,71 +615,71 @@ class Inspircd(IProtocol): # [':97K', 'ENDBURST'] scopy = server_msg.copy() hsid = str(scopy[0]).replace(':','') - if hsid == self._Config.HSID: - if self._Config.DEFENDER_INIT == 1: - current_version = self._Config.CURRENT_VERSION - latest_version = self._Config.LATEST_VERSION - if self._Base.check_for_new_version(False): + if hsid == self._ctx.Config.HSID: + if self._ctx.Config.DEFENDER_INIT == 1: + current_version = self._ctx.Config.CURRENT_VERSION + latest_version = self._ctx.Config.LATEST_VERSION + if self._ctx.Base.check_for_new_version(False): version = f'{current_version} >>> {latest_version}' else: version = f'{current_version}' print(f"################### DEFENDER ###################") print(f"# SERVICE CONNECTE ") - print(f"# SERVEUR : {self._Config.SERVEUR_IP} ") - print(f"# PORT : {self._Config.SERVEUR_PORT} ") - print(f"# SSL : {self._Config.SERVEUR_SSL} ") - print(f"# SSL VER : {self._Config.SSL_VERSION} ") - print(f"# NICKNAME : {self._Config.SERVICE_NICKNAME} ") - print(f"# CHANNEL : {self._Config.SERVICE_CHANLOG} ") + print(f"# SERVEUR : {self._ctx.Config.SERVEUR_IP} ") + print(f"# PORT : {self._ctx.Config.SERVEUR_PORT} ") + print(f"# SSL : {self._ctx.Config.SERVEUR_SSL} ") + print(f"# SSL VER : {self._ctx.Config.SSL_VERSION} ") + print(f"# NICKNAME : {self._ctx.Config.SERVICE_NICKNAME} ") + print(f"# CHANNEL : {self._ctx.Config.SERVICE_CHANLOG} ") print(f"# VERSION : {version} ") print(f"################################################") - self._Logs.info(f"################### DEFENDER ###################") - self._Logs.info(f"# SERVICE CONNECTE ") - self._Logs.info(f"# SERVEUR : {self._Config.SERVEUR_IP} ") - self._Logs.info(f"# PORT : {self._Config.SERVEUR_PORT} ") - self._Logs.info(f"# SSL : {self._Config.SERVEUR_SSL} ") - self._Logs.info(f"# SSL VER : {self._Config.SSL_VERSION} ") - self._Logs.info(f"# NICKNAME : {self._Config.SERVICE_NICKNAME} ") - self._Logs.info(f"# CHANNEL : {self._Config.SERVICE_CHANLOG} ") - self._Logs.info(f"# VERSION : {version} ") - self._Logs.info(f"################################################") + self._ctx.Logs.info(f"################### DEFENDER ###################") + self._ctx.Logs.info(f"# SERVICE CONNECTE ") + self._ctx.Logs.info(f"# SERVEUR : {self._ctx.Config.SERVEUR_IP} ") + self._ctx.Logs.info(f"# PORT : {self._ctx.Config.SERVEUR_PORT} ") + self._ctx.Logs.info(f"# SSL : {self._ctx.Config.SERVEUR_SSL} ") + self._ctx.Logs.info(f"# SSL VER : {self._ctx.Config.SSL_VERSION} ") + self._ctx.Logs.info(f"# NICKNAME : {self._ctx.Config.SERVICE_NICKNAME} ") + self._ctx.Logs.info(f"# CHANNEL : {self._ctx.Config.SERVICE_CHANLOG} ") + self._ctx.Logs.info(f"# VERSION : {version} ") + self._ctx.Logs.info(f"################################################") - self.send_sjoin(self._Config.SERVICE_CHANLOG) + self.send_sjoin(self._ctx.Config.SERVICE_CHANLOG) - if self._Base.check_for_new_version(False): + if self._ctx.Base.check_for_new_version(False): self.send_priv_msg( - nick_from=self._Config.SERVICE_NICKNAME, + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f" New Version available {version}", - channel=self._Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) # Initialisation terminé aprés le premier PING self.send_priv_msg( - nick_from=self._Config.SERVICE_NICKNAME, - msg=tr("[ %sINFORMATION%s ] >> %s is ready!", self._Config.COLORS.green, self._Config.COLORS.nogc, self._Config.SERVICE_NICKNAME), - channel=self._Config.SERVICE_CHANLOG + nick_from=self._ctx.Config.SERVICE_NICKNAME, + msg=tr("[ %sINFORMATION%s ] >> %s is ready!", self._ctx.Config.COLORS.green, self._ctx.Config.COLORS.nogc, self._ctx.Config.SERVICE_NICKNAME), + channel=self._ctx.Config.SERVICE_CHANLOG ) - self._Config.DEFENDER_INIT = 0 + self._ctx.Config.DEFENDER_INIT = 0 # Send EOF to other modules - for module in self._Irc.ModuleUtils.model_get_loaded_modules().copy(): + for module in self._ctx.ModuleUtils.model_get_loaded_modules().copy(): module.class_instance.cmd(scopy) # Join saved channels & load existing modules - self._Irc.join_saved_channels() - self._Irc.ModuleUtils.db_load_all_existing_modules(self._Irc) + self._ctx.Irc.join_saved_channels() + self._ctx.ModuleUtils.db_load_all_existing_modules(self._ctx.Irc) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Key Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Key Error: {ie}") except KeyError as ke: - self._Logs.error(f"{__name__} - Key Error: {ke}") + self._ctx.Logs.error(f"{__name__} - Key Error: {ke}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_part(self, server_msg: list[str]) -> None: + async def on_part(self, server_msg: list[str]) -> None: """Handle part coming from a server Args: @@ -690,16 +691,16 @@ class Inspircd(IProtocol): uid = str(server_msg[0]).lstrip(':') channel = str(server_msg[2]).lower() # reason = str(' '.join(server_msg[3:])) - self._Irc.Channel.delete_user_from_channel(channel, uid) + self._ctx.Channel.delete_user_from_channel(channel, uid) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_uid(self, server_msg: list[str]) -> None: + async def on_uid(self, server_msg: list[str]) -> None: """Handle uid message coming from the server [:] UID []+ : [':97K', 'UID', '97KAAAAAB', '1756928055', 'adator_', '172.18.128.1', '172.18.128.1', '...', '...', '172.18.128.1', '1756928055', '+', ':...'] @@ -707,9 +708,9 @@ class Inspircd(IProtocol): server_msg (list[str]): Original server message """ try: - red = self._Config.COLORS.red - green = self._Config.COLORS.green - nogc = self._Config.COLORS.nogc + red = self._ctx.Config.COLORS.red + green = self._ctx.Config.COLORS.green + nogc = self._ctx.Config.COLORS.nogc is_webirc = True if 'webirc' in server_msg[0] else False is_websocket = True if 'websocket' in server_msg[0] else False @@ -721,7 +722,7 @@ class Inspircd(IProtocol): vhost = str(server_msg[6]) if not 'S' in umodes: - # remote_ip = self._Base.decode_ip(str(serverMsg[9])) + # remote_ip = self._ctx.Base.decode_ip(str(serverMsg[9])) remote_ip = str(server_msg[9]) else: remote_ip = '127.0.0.1' @@ -740,8 +741,8 @@ class Inspircd(IProtocol): score_connexion = 0 - self._Irc.User.insert( - self._Irc.Loader.Definition.MUser( + self._ctx.User.insert( + self._ctx.Definition.MUser( uid=uid, nickname=nickname, username=username, @@ -758,39 +759,39 @@ class Inspircd(IProtocol): ) ) - for module in self._Irc.ModuleUtils.model_get_loaded_modules().copy(): + for module in self._ctx.ModuleUtils.model_get_loaded_modules().copy(): module.class_instance.cmd(server_msg) # SASL authentication - dnickname = self._Config.SERVICE_NICKNAME - dchanlog = self._Config.SERVICE_CHANLOG + dnickname = self._ctx.Config.SERVICE_NICKNAME + dchanlog = self._ctx.Config.SERVICE_CHANLOG # uid = serverMsg[8] # nickname = serverMsg[3] - sasl_obj = self._Irc.Sasl.get_sasl_obj(uid) + sasl_obj = self._ctx.Sasl.get_sasl_obj(uid) if sasl_obj: if sasl_obj.auth_success: - self._Irc.insert_db_admin(sasl_obj.client_uid, sasl_obj.username, sasl_obj.level, sasl_obj.language) - self.send_priv_msg(nick_from=dnickname, + self._ctx.Irc.insert_db_admin(sasl_obj.client_uid, sasl_obj.username, sasl_obj.level, sasl_obj.language) + await self.send_priv_msg(nick_from=dnickname, msg=tr("[ %sSASL AUTH%s ] - %s (%s) is now connected successfuly to %s", green, nogc, nickname, sasl_obj.username, dnickname), channel=dchanlog) - self.send_notice(nick_from=dnickname, nick_to=nickname, msg=tr("Successfuly connected to %s", dnickname)) + await self.send_notice(nick_from=dnickname, nick_to=nickname, msg=tr("Successfuly connected to %s", dnickname)) else: - self.send_priv_msg(nick_from=dnickname, + await self.send_priv_msg(nick_from=dnickname, msg=tr("[ %sSASL AUTH%s ] - %s provided a wrong password for this username %s", red, nogc, nickname, sasl_obj.username), channel=dchanlog) - self.send_notice(nick_from=dnickname, nick_to=nickname, msg=tr("Wrong password!")) + await self.send_notice(nick_from=dnickname, nick_to=nickname, msg=tr("Wrong password!")) # Delete sasl object! - self._Irc.Sasl.delete_sasl_client(uid) + self._ctx.Sasl.delete_sasl_client(uid) return None return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}", exc_info=True) + self._ctx.Logs.error(f"{__name__} - General Error: {err}", exc_info=True) - def on_privmsg(self, server_msg: list[str]) -> None: + async def on_privmsg(self, server_msg: list[str]) -> None: """Handle PRIVMSG message coming from the server Args: @@ -804,36 +805,36 @@ class Inspircd(IProtocol): cmd.pop(0) get_uid_or_nickname = str(cmd[0].replace(':','')) - user_trigger = self._Irc.User.get_nickname(get_uid_or_nickname) - # dnickname = self._Config.SERVICE_NICKNAME - pattern = fr'(:\{self._Config.SERVICE_PREFIX})(.*)$' + user_trigger = self._ctx.User.get_nickname(get_uid_or_nickname) + # dnickname = self._ctx.Config.SERVICE_NICKNAME + pattern = fr'(:\{self._ctx.Config.SERVICE_PREFIX})(.*)$' hcmds = search(pattern, ' '.join(cmd)) # va matcher avec tout les caractéres aprés le . if hcmds: # Commande qui commencent par le point liste_des_commandes = list(hcmds.groups()) convert_to_string = ' '.join(liste_des_commandes) arg = convert_to_string.split() - arg.remove(f":{self._Config.SERVICE_PREFIX}") - if not self._Irc.Commands.is_command_exist(arg[0]): - self._Logs.debug(f"This command {arg[0]} is not available") + arg.remove(f":{self._ctx.Config.SERVICE_PREFIX}") + if not self._ctx.Commands.is_command_exist(arg[0]): + self._ctx.Logs.debug(f"This command {arg[0]} is not available") self.send_notice( - nick_from=self._Config.SERVICE_NICKNAME, + nick_from=self._ctx.Config.SERVICE_NICKNAME, nick_to=user_trigger, - msg=f"This command [{self._Config.COLORS.bold}{arg[0]}{self._Config.COLORS.bold}] is not available" + msg=f"This command [{self._ctx.Config.COLORS.bold}{arg[0]}{self._ctx.Config.COLORS.bold}] is not available" ) return None cmd_to_send = convert_to_string.replace(':','') - self._Base.log_cmd(user_trigger, cmd_to_send) + await self._ctx.Base.log_cmd(user_trigger, cmd_to_send) - fromchannel = str(cmd[2]).lower() if self._Irc.Channel.is_valid_channel(cmd[2]) else None - self._Irc.hcmds(user_trigger, fromchannel, arg, cmd) + fromchannel = str(cmd[2]).lower() if self._ctx.Channel.is_valid_channel(cmd[2]) else None + self._ctx.Irc.hcmds(user_trigger, fromchannel, arg, cmd) - if cmd[2] == self._Config.SERVICE_ID: + if cmd[2] == self._ctx.Config.SERVICE_ID: pattern = fr'^:.*?:(.*)$' hcmds = search(pattern, ' '.join(cmd)) - if hcmds: # par /msg defender [commande] + if hcmds: # par /msg async defender [commande] liste_des_commandes = list(hcmds.groups()) convert_to_string = ' '.join(liste_des_commandes) arg = convert_to_string.split() @@ -853,32 +854,32 @@ class Inspircd(IProtocol): self.on_ping(srv_msg) return None - if not self._Irc.Commands.is_command_exist(arg[0]): - self._Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") + if not self._ctx.Commands.is_command_exist(arg[0]): + self._ctx.Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") return None - # if not arg[0].lower() in self._Irc.module_commands_list: - # self._Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") + # if not arg[0].lower() in self._ctx.Irc.module_commands_list: + # self._ctx.Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") # return False cmd_to_send = convert_to_string.replace(':','') - self._Base.log_cmd(user_trigger, cmd_to_send) + await self._ctx.Base.log_cmd(user_trigger, cmd_to_send) fromchannel = None if len(arg) >= 2: - fromchannel = str(arg[1]).lower() if self._Irc.Channel.is_valid_channel(arg[1]) else None + fromchannel = str(arg[1]).lower() if self._ctx.Channel.is_valid_channel(arg[1]) else None - self._Irc.hcmds(user_trigger, fromchannel, arg, cmd) + self._ctx.Irc.hcmds(user_trigger, fromchannel, arg, cmd) return None except KeyError as ke: - self._Logs.error(f"Key Error: {ke}") + self._ctx.Logs.error(f"Key Error: {ke}") except AttributeError as ae: - self._Logs.error(f"Attribute Error: {ae}") + self._ctx.Logs.error(f"Attribute Error: {ae}") except Exception as err: - self._Logs.error(f"General Error: {err}", exc_info=True) + self._ctx.Logs.error(f"General Error: {err}", exc_info=True) - def on_server_ping(self, server_msg: list[str]) -> None: + async def on_server_ping(self, server_msg: list[str]) -> None: """Send a PONG message to the server Args: @@ -890,13 +891,13 @@ class Inspircd(IProtocol): # -> :808 PONG 3IN hsid = str(server_msg[0]).replace(':','') - self.send2socket(f":{self._Config.SERVEUR_ID} PONG {hsid}", print_log=False) + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} PONG {hsid}", print_log=False) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_server(self, server_msg: list[str]) -> None: + async def on_server(self, server_msg: list[str]) -> None: """_summary_ >>> [':97K', 'SINFO', 'customversion', ':'] >>> [':97K', 'SINFO', 'rawbranch', ':InspIRCd-4'] @@ -906,16 +907,16 @@ class Inspircd(IProtocol): """ try: param = str(server_msg[2]) - self._Config.HSID = self._Settings.MAIN_SERVER_ID = str(server_msg[0]).replace(':', '') + self._ctx.Config.HSID = self._ctx.Settings.MAIN_SERVER_ID = str(server_msg[0]).replace(':', '') if param == 'rawversion': - self._Logs.debug(f">> Server Version: {server_msg[3].replace(':', '')}") + self._ctx.Logs.debug(f">> Server Version: {server_msg[3].replace(':', '')}") elif param == 'rawbranch': - self._Logs.debug(f">> Branch Version: {server_msg[3].replace(':', '')}") + self._ctx.Logs.debug(f">> Branch Version: {server_msg[3].replace(':', '')}") except Exception as err: - self._Logs.error(f'General Error: {err}') + self._ctx.Logs.error(f'General Error: {err}') - def on_version(self, server_msg: list[str]) -> None: + async def on_version(self, server_msg: list[str]) -> None: """Sending Server Version to the server Args: @@ -925,21 +926,21 @@ class Inspircd(IProtocol): # Réponse a un CTCP VERSION try: - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(server_msg[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(server_msg[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = server_msg[4].replace(':', '') if nickname is None: return None if arg == '\x01VERSION\x01': - self.send2socket(f':{dnickname} NOTICE {nickname} :\x01VERSION Service {self._Config.SERVICE_NICKNAME} V{self._Config.CURRENT_VERSION}\x01') + await self.send2socket(f':{dnickname} NOTICE {nickname} :\x01VERSION Service {self._ctx.Config.SERVICE_NICKNAME} V{self._ctx.Config.CURRENT_VERSION}\x01') return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_time(self, server_msg: list[str]) -> None: + async def on_time(self, server_msg: list[str]) -> None: """Sending TIME answer to a requestor Args: @@ -949,22 +950,22 @@ class Inspircd(IProtocol): # Réponse a un CTCP VERSION try: - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(server_msg[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(server_msg[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = server_msg[4].replace(':', '') - current_datetime = self._Utils.get_sdatetime() + current_datetime = self._ctx.Utils.get_sdatetime() if nickname is None: return None if arg == '\x01TIME\x01': - self.send2socket(f':{dnickname} NOTICE {nickname} :\x01TIME {current_datetime}\x01') + await self.send2socket(f':{dnickname} NOTICE {nickname} :\x01TIME {current_datetime}\x01') return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_ping(self, server_msg: list[str]) -> None: + async def on_ping(self, server_msg: list[str]) -> None: """Sending a PING answer to requestor Args: @@ -974,8 +975,8 @@ class Inspircd(IProtocol): # Réponse a un CTCP VERSION try: - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(server_msg[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(server_msg[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = server_msg[4].replace(':', '') if nickname is None: @@ -983,10 +984,10 @@ class Inspircd(IProtocol): if arg == '\x01PING': recieved_unixtime = int(server_msg[5].replace('\x01','')) - current_unixtime = self._Utils.get_unixtime() + current_unixtime = self._ctx.Utils.get_unixtime() ping_response = current_unixtime - recieved_unixtime - # self._Irc.send2socket(f':{dnickname} NOTICE {nickname} :\x01PING {ping_response} secs\x01') + # self._ctx.Irc.send2socket(f':{dnickname} NOTICE {nickname} :\x01PING {ping_response} secs\x01') self.send_notice( nick_from=dnickname, nick_to=nickname, @@ -995,9 +996,9 @@ class Inspircd(IProtocol): return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_version_msg(self, server_msg: list[str]) -> None: + async def on_version_msg(self, server_msg: list[str]) -> None: """Handle version coming from the server Args: @@ -1005,24 +1006,24 @@ class Inspircd(IProtocol): """ try: # ['@label=0073', ':0014E7P06', 'VERSION', 'PyDefender'] - user_obj = self._Irc.User.get_user(self._Utils.clean_uid(server_msg[1])) + user_obj = self._ctx.User.get_user(self._ctx.Utils.clean_uid(server_msg[1])) if user_obj is None: return None - response_351 = f"{self._Config.SERVICE_NAME.capitalize()}-{self._Config.CURRENT_VERSION} {self._Config.SERVICE_HOST} {self.name}" - self.send2socket(f':{self._Config.SERVICE_HOST} 351 {user_obj.nickname} {response_351}') + response_351 = f"{self._ctx.Config.SERVICE_NAME.capitalize()}-{self._ctx.Config.CURRENT_VERSION} {self._ctx.Config.SERVICE_HOST} {self.name}" + await self.send2socket(f':{self._ctx.Config.SERVICE_HOST} 351 {user_obj.nickname} {response_351}') - modules = self._Irc.ModuleUtils.get_all_available_modules() + modules = self._ctx.ModuleUtils.get_all_available_modules() response_005 = ' | '.join(modules) - self.send2socket(f':{self._Config.SERVICE_HOST} 005 {user_obj.nickname} {response_005} are supported by this server') + await self.send2socket(f':{self._ctx.Config.SERVICE_HOST} 005 {user_obj.nickname} {response_005} are supported by this server') return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") - def on_sasl(self, server_msg: list[str]) -> Optional['MSasl']: + async def on_sasl(self, server_msg: list[str]) -> Optional['MSasl']: """Handle SASL coming from a server Args: @@ -1034,12 +1035,12 @@ class Inspircd(IProtocol): # [':97K', 'ENCAP', '98K', 'SASL', '97KAAAAAF', '*', 'H', '172.18.128.1', '172.18.128.1', 'P'] # [':97K', 'ENCAP', '98K', 'SASL', '97KAAAAAF', '*', 'S', 'PLAIN'] # [':97K', 'ENCAP', '98K', 'SASL', '97KAAAAAP', 'irc.inspircd.local', 'C', 'YWRzefezfzefzefzefzefzefzefzezak='] - # [':irc.local.org', 'SASL', 'defender-dev.deb.biz.st', '0014ZZH1F', 'S', 'EXTERNAL', 'zzzzzzzkey'] - # [':irc.local.org', 'SASL', 'defender-dev.deb.biz.st', '00157Z26U', 'C', 'sasakey=='] - # [':irc.local.org', 'SASL', 'defender-dev.deb.biz.st', '00157Z26U', 'D', 'A'] - psasl = self._Irc.Sasl + # [':irc.local.org', 'SASL', 'async defender-dev.deb.biz.st', '0014ZZH1F', 'S', 'EXTERNAL', 'zzzzzzzkey'] + # [':irc.local.org', 'SASL', 'async defender-dev.deb.biz.st', '00157Z26U', 'C', 'sasakey=='] + # [':irc.local.org', 'SASL', 'async defender-dev.deb.biz.st', '00157Z26U', 'D', 'A'] + psasl = self._ctx.Sasl sasl_enabled = True # Should be False - for smod in self._Settings.SMOD_MODULES: + for smod in self._ctx.Settings.SMOD_MODULES: if smod.name == 'sasl': sasl_enabled = True break @@ -1051,7 +1052,7 @@ class Inspircd(IProtocol): client_uid = scopy[4] if len(scopy) >= 6 else None # sasl_obj = None sasl_message_type = scopy[6] if len(scopy) >= 6 else None - psasl.insert_sasl_client(self._Irc.Loader.Definition.MSasl(client_uid=client_uid)) + psasl.insert_sasl_client(self._ctx.Definition.MSasl(client_uid=client_uid)) sasl_obj = psasl.get_sasl_obj(client_uid) if sasl_obj is None: @@ -1069,15 +1070,15 @@ class Inspircd(IProtocol): sasl_obj.mechanisme = str(scopy[7]) if sasl_obj.mechanisme == "PLAIN": - self.send2socket(f":{self._Config.SERVEUR_ID} SASL {self._Config.SERVEUR_HOSTNAME} {sasl_obj.client_uid} C +") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} SASL {self._ctx.Config.SERVEUR_HOSTNAME} {sasl_obj.client_uid} C +") elif sasl_obj.mechanisme == "EXTERNAL": if str(scopy[7]) == "+": return None sasl_obj.fingerprint = str(scopy[8]) - self.send2socket(f":{self._Config.SERVEUR_ID} SASL {self._Config.SERVEUR_HOSTNAME} {sasl_obj.client_uid} C +") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} SASL {self._ctx.Config.SERVEUR_HOSTNAME} {sasl_obj.client_uid} C +") - self.on_sasl_authentication_process(sasl_obj) + await self.on_sasl_authentication_process(sasl_obj) return sasl_obj case 'C': @@ -1090,31 +1091,31 @@ class Inspircd(IProtocol): sasl_obj.username = username sasl_obj.password = password - self.on_sasl_authentication_process(sasl_obj) + await self.on_sasl_authentication_process(sasl_obj) return sasl_obj elif sasl_obj.mechanisme == "EXTERNAL": sasl_obj.message_type = sasl_message_type - self.on_sasl_authentication_process(sasl_obj) + await self.on_sasl_authentication_process(sasl_obj) return sasl_obj except Exception as err: - self._Logs.error(f'General Error: {err}', exc_info=True) + self._ctx.Logs.error(f'General Error: {err}', exc_info=True) - def on_sasl_authentication_process(self, sasl_model: 'MSasl'): + async def on_sasl_authentication_process(self, sasl_model: 'MSasl'): s = sasl_model - server_id = self._Config.SERVEUR_ID - main_server_hostname = self._Settings.MAIN_SERVER_HOSTNAME - db_admin_table = self._Config.TABLE_ADMIN + server_id = self._ctx.Config.SERVEUR_ID + main_server_hostname = self._ctx.Settings.MAIN_SERVER_HOSTNAME + db_admin_table = self._ctx.Config.TABLE_ADMIN if sasl_model: - def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: + async def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: if fingerprint: mes_donnees = {'fingerprint': fingerprint} query = f"SELECT user, level, language FROM {db_admin_table} WHERE fingerprint = :fingerprint" else: - mes_donnees = {'user': username, 'password': self._Utils.hash_password(password)} + mes_donnees = {'user': username, 'password': self._ctx.Utils.hash_password(password)} query = f"SELECT user, level, language FROM {db_admin_table} WHERE user = :user AND password = :password" - result = self._Base.db_execute_query(query, mes_donnees) + result = await self._ctx.Base.db_execute_query(query, mes_donnees) user_from_db = result.fetchone() if user_from_db: return {'user': user_from_db[0], 'level': user_from_db[1], 'language': user_from_db[2]} @@ -1123,37 +1124,37 @@ class Inspircd(IProtocol): if s.message_type == 'C' and s.mechanisme == 'PLAIN': # Connection via PLAIN - admin_info = db_get_admin_info(username=s.username, password=s.password) + admin_info = await db_get_admin_info(username=s.username, password=s.password) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.language = admin_info.get('language', 'EN') - self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D S") - self.send2socket(f":{server_id} SASL {s.username} :SASL authentication successful") + await self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D S") + await self.send2socket(f":{server_id} SASL {s.username} :SASL authentication successful") else: - self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D F") - self.send2socket(f":{server_id} SASL {s.username} :SASL authentication failed") + await self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D F") + await self.send2socket(f":{server_id} SASL {s.username} :SASL authentication failed") elif s.message_type == 'S' and s.mechanisme == 'EXTERNAL': # Connection using fingerprints - admin_info = db_get_admin_info(fingerprint=s.fingerprint) + admin_info = await db_get_admin_info(fingerprint=s.fingerprint) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.username = admin_info.get('user', None) s.language = admin_info.get('language', 'EN') - self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D S") - self.send2socket(f":{server_id} SASL {s.username} :SASL authentication successful") + await self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D S") + await self.send2socket(f":{server_id} SASL {s.username} :SASL authentication successful") else: # "904 :SASL authentication failed" - self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D F") - self.send2socket(f":{server_id} SASL {s.username} :SASL authentication failed") + await self.send2socket(f":{server_id} SASL {main_server_hostname} {s.client_uid} D F") + await self.send2socket(f":{server_id} SASL {s.username} :SASL authentication failed") - def on_error(self, server_msg: list[str]) -> None: - self._Logs.debug(f"{server_msg}") + async def on_error(self, server_msg: list[str]) -> None: + self._ctx.Logs.debug(f"{server_msg}") - def on_metedata(self, server_msg: list[str]) -> None: + async def on_metedata(self, server_msg: list[str]) -> None: """_summary_ Args: @@ -1162,33 +1163,33 @@ class Inspircd(IProtocol): # [':97K', 'METADATA', '97KAAAAAA', 'ssl_cert', ':vTrSe', 'fingerprint90753683519522875', # '/C=FR/OU=Testing/O=Test', 'Sasl/CN=localhost', '/C=FR/OU=Testing/O=Test', 'Sasl/CN=localhost'] scopy = server_msg.copy() - dnickname = self._Config.SERVICE_NICKNAME - dchanlog = self._Config.SERVICE_CHANLOG - green = self._Config.COLORS.green - nogc = self._Config.COLORS.nogc + dnickname = self._ctx.Config.SERVICE_NICKNAME + dchanlog = self._ctx.Config.SERVICE_CHANLOG + green = self._ctx.Config.COLORS.green + nogc = self._ctx.Config.COLORS.nogc if 'ssl_cert' in scopy: fingerprint = scopy[5] uid = scopy[2] - user_obj = self._Irc.User.get_user(uid) + user_obj = self._ctx.User.get_user(uid) if user_obj: user_obj.fingerprint = fingerprint - if self._Irc.Admin.db_auth_admin_via_fingerprint(fingerprint, uid): - admin = self._Irc.Admin.get_admin(uid) + if await self._ctx.Admin.db_auth_admin_via_fingerprint(fingerprint, uid): + admin = self._ctx.Admin.get_admin(uid) account = admin.account if admin else '' - self.send_priv_msg(nick_from=dnickname, + await self.send_priv_msg(nick_from=dnickname, msg=tr("[ %sSASL AUTO AUTH%s ] - %s (%s) is now connected successfuly to %s", green, nogc, user_obj.nickname, account, dnickname), channel=dchanlog) - self.send_notice(nick_from=dnickname, nick_to=user_obj.nickname, msg=tr("Successfuly connected to %s", dnickname)) + await self.send_notice(nick_from=dnickname, nick_to=user_obj.nickname, msg=tr("Successfuly connected to %s", dnickname)) - def on_kick(self, server_msg: list[str]) -> None: + async def on_kick(self, server_msg: list[str]) -> None: ... # ------------------------------------------------------------------------ # COMMON IRC PARSER # ------------------------------------------------------------------------ - def parse_uid(self, server_msg: list[str]) -> Optional['MUser']: + async def parse_uid(self, server_msg: list[str]) -> Optional['MUser']: """Parse UID and return dictionary. >>> [':97K', 'UID', '97KAAAAAC', '1762113659', 'adator_', '172.18.128.1', '172.18.128.1', '...', '...', '172.18.128.1', '1762113659', '+', ':...'] Args: @@ -1196,9 +1197,9 @@ class Inspircd(IProtocol): """ scopy = server_msg.copy() uid = scopy[2] - return self._User.get_user(uid) + return self._ctx.User.get_user(uid) - def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]: + async def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]: """Parse quit and return dictionary. >>> [':97KAAAAAB', 'QUIT', ':Quit:', 'this', 'is', 'my', 'reason', 'to', 'quit'] Args: @@ -1212,14 +1213,14 @@ class Inspircd(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - user_obj = self._User.get_user(self._Utils.clean_uid(scopy[0])) + user_obj = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[0])) tmp_reason = scopy[3:] tmp_reason[0] = tmp_reason[0].replace(':', '') reason = ' '.join(tmp_reason) return user_obj, reason - def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]: + async def parse_nick(self, server_msg: list[str]) -> tuple[Optional['MUser'], str, str]: """Parse nick changes. >>> [':97KAAAAAC', 'NICK', 'testinspir', '1757360740'] @@ -1233,12 +1234,12 @@ class Inspircd(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - user_obj = self._User.get_user(self._User.clean_uid(scopy[0])) + user_obj = self._ctx.User.get_user(self._ctx.User.clean_uid(scopy[0])) newnickname = scopy[2] timestamp = scopy[3] return user_obj, newnickname, timestamp - def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]: + async def parse_privmsg(self, server_msg: list[str]) -> tuple[Optional['MUser'], Optional['MUser'], Optional['MChannel'], str]: """Parse PRIVMSG message. >>> [':97KAAAAAE', 'PRIVMSG', '#welcome', ':This', 'is', 'my', 'public', 'message'] >>> [':97KAAAAAF', 'PRIVMSG', '98KAAAAAB', ':My','Message','...'] @@ -1253,9 +1254,9 @@ class Inspircd(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - sender = self._User.get_user(self._Utils.clean_uid(scopy[0])) - reciever = self._User.get_user(self._Utils.clean_uid(scopy[2])) - channel = self._Channel.get_channel(scopy[2]) if self._Channel.is_valid_channel(scopy[2]) else None + sender = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[0])) + reciever = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[2])) + channel = self._ctx.Channel.get_channel(scopy[2]) if self._ctx.Channel.is_valid_channel(scopy[2]) else None tmp_message = scopy[3:] tmp_message = tmp_message[0].replace(':', '') @@ -1267,7 +1268,7 @@ class Inspircd(IProtocol): # IRC SENDER METHODS # ------------------------------------------------------------------------ - def send_mode_chan(self, channel_name: str, channel_mode: str) -> None: + async def send_mode_chan(self, channel_name: str, channel_mode: str) -> None: """_summary_ Args: @@ -1276,7 +1277,7 @@ class Inspircd(IProtocol): """ ... - def send_gline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: + async def send_gline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: """Send a gline command to the server Args: @@ -1289,7 +1290,7 @@ class Inspircd(IProtocol): """ ... - def send_sajoin(self, nick_to_sajoin: str, channel_name: str) -> None: + async def send_sajoin(self, nick_to_sajoin: str, channel_name: str) -> None: """_summary_ Args: @@ -1298,7 +1299,7 @@ class Inspircd(IProtocol): """ ... - def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None: + async def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None: """_summary_ Args: @@ -1307,7 +1308,7 @@ class Inspircd(IProtocol): """ ... - def send_svs2mode(self, nickname: str, user_mode: str) -> None: + async def send_svs2mode(self, nickname: str, user_mode: str) -> None: """_summary_ Args: @@ -1316,7 +1317,7 @@ class Inspircd(IProtocol): """ ... - def send_svsjoin(self, nick_to_part: str, channels: list[str], keys: list[str]) -> None: + async def send_svsjoin(self, nick_to_part: str, channels: list[str], keys: list[str]) -> None: """_summary_ Args: @@ -1326,7 +1327,7 @@ class Inspircd(IProtocol): """ ... - def send_svslogin(self, client_uid: str, user_account: str) -> None: + async def send_svslogin(self, client_uid: str, user_account: str) -> None: """Log a client into his account. Args: @@ -1335,7 +1336,7 @@ class Inspircd(IProtocol): """ ... - def send_svslogout(self, client_obj: 'MClient') -> None: + async def send_svslogout(self, client_obj: 'MClient') -> None: """Logout a client from his account Args: @@ -1343,7 +1344,7 @@ class Inspircd(IProtocol): """ ... - def send_svsmode(self, nickname: str, user_mode: str) -> None: + async def send_svsmode(self, nickname: str, user_mode: str) -> None: """_summary_ Args: @@ -1352,7 +1353,7 @@ class Inspircd(IProtocol): """ ... - def send_svspart(self, nick_to_part: str, channels: list[str], reason: str) -> None: + async def send_svspart(self, nick_to_part: str, channels: list[str], reason: str) -> None: """_summary_ Args: @@ -1362,7 +1363,7 @@ class Inspircd(IProtocol): """ ... - def on_md(self, server_msg: list[str]) -> None: + async def on_md(self, server_msg: list[str]) -> None: """Handle MD responses [':001', 'MD', 'client', '001MYIZ03', 'certfp', ':d1235648...'] Args: @@ -1370,7 +1371,7 @@ class Inspircd(IProtocol): """ ... - def on_mode(self, server_msg: list[str]) -> None: + async def on_mode(self, server_msg: list[str]) -> None: """Handle mode coming from a server Args: @@ -1378,7 +1379,7 @@ class Inspircd(IProtocol): """ ... - def on_reputation(self, server_msg: list[str]) -> None: + async def on_reputation(self, server_msg: list[str]) -> None: """Handle REPUTATION coming from a server Args: @@ -1386,7 +1387,7 @@ class Inspircd(IProtocol): """ ... - def on_smod(self, server_msg: list[str]) -> None: + async def on_smod(self, server_msg: list[str]) -> None: """Handle SMOD message coming from the server Args: @@ -1394,7 +1395,7 @@ class Inspircd(IProtocol): """ ... - def on_svs2mode(self, server_msg: list[str]) -> None: + async def on_svs2mode(self, server_msg: list[str]) -> None: """Handle svs2mode coming from a server >>> [':00BAAAAAG', 'SVS2MODE', '001U01R03', '-r'] @@ -1403,7 +1404,7 @@ class Inspircd(IProtocol): """ ... - def on_eos(self, server_msg: list[str]) -> None: + async def on_eos(self, server_msg: list[str]) -> None: """Handle EOS coming from a server Args: @@ -1411,7 +1412,7 @@ class Inspircd(IProtocol): """ ... - def on_sethost(self, server_msg: list[str]) -> None: + async def on_sethost(self, server_msg: list[str]) -> None: """On SETHOST command Args: diff --git a/core/classes/protocols/unreal6.py b/core/classes/protocols/unreal6.py index 154d286..b6dc9ef 100644 --- a/core/classes/protocols/unreal6.py +++ b/core/classes/protocols/unreal6.py @@ -36,12 +36,12 @@ class Unrealircd6(IProtocol): return index, token.upper() if log: - self._Logs.debug(f"[IRCD LOGS] You need to handle this response: {cmd}") + self._ctx.Logs.debug(f"[IRCD LOGS] You need to handle this response: {cmd}") return -1, None def register_command(self) -> None: - m = self._Irc.Loader.Definition.MIrcdCommand + m = self._ctx.Definition.MIrcdCommand self.Handler.register(m(command_name="PING", func=self.on_server_ping)) self.Handler.register(m(command_name="UID", func=self.on_uid)) self.Handler.register(m(command_name="QUIT", func=self.on_quit)) @@ -107,30 +107,30 @@ class Unrealircd6(IProtocol): print_log (bool): True print log message in the console """ try: - with self._Base.lock: - self._Irc.writer.write(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[0])) - await self._Irc.writer.drain() + async with self._ctx.Settings.AILOCK: + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[0])) + await self._ctx.Irc.writer.drain() if print_log: - self._Logs.debug(f'<< {message}') + self._ctx.Logs.debug(f'<< {message}') except UnicodeDecodeError as ude: - self._Logs.error(f'Decode Error try iso-8859-1 - {ude} - {message}') - self._Irc.writer.write(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[1],'replace')) - await self._Irc.writer.drain() + self._ctx.Logs.error(f'Decode Error try iso-8859-1 - {ude} - {message}') + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[1],'replace')) + await self._ctx.Irc.writer.drain() except UnicodeEncodeError as uee: - self._Logs.error(f'Encode Error try iso-8859-1 - {uee} - {message}') - self._Irc.writer.write(f"{message}\r\n".encode(self._Config.SERVEUR_CHARSET[1],'replace')) - await self._Irc.writer.drain() + self._ctx.Logs.error(f'Encode Error try iso-8859-1 - {uee} - {message}') + self._ctx.Irc.writer.write(f"{message}\r\n".encode(self._ctx.Config.SERVEUR_CHARSET[1],'replace')) + await self._ctx.Irc.writer.drain() except AssertionError as ae: - self._Logs.warning(f'Assertion Error {ae} - message: {message}') + self._ctx.Logs.warning(f'Assertion Error {ae} - message: {message}') except SSLEOFError as soe: - self._Logs.error(f"SSLEOFError: {soe} - {message}") + self._ctx.Logs.error(f"SSLEOFError: {soe} - {message}") except SSLError as se: - self._Logs.error(f"SSLError: {se} - {message}") + self._ctx.Logs.error(f"SSLError: {se} - {message}") except OSError as oe: - self._Logs.error(f"OSError: {oe} - {message}") + self._ctx.Logs.error(f"OSError: {oe} - {message}") except AttributeError as ae: - self._Logs.critical(f"Attribute Error: {ae}") + self._ctx.Logs.critical(f"Attribute Error: {ae}") async def send_priv_msg(self, nick_from: str, msg: str, channel: str = None, nick_to: str = None): """Sending PRIVMSG to a channel or to a nickname by batches @@ -142,12 +142,12 @@ class Unrealircd6(IProtocol): nick_to (str, optional): The reciever nickname. Defaults to None. """ try: - batch_size = self._Config.BATCH_SIZE - user_from = self._Irc.User.get_user(nick_from) - user_to = self._Irc.User.get_user(nick_to) if not nick_to is None else None + batch_size = self._ctx.Config.BATCH_SIZE + user_from = self._ctx.User.get_user(nick_from) + user_to = self._ctx.User.get_user(nick_to) if not nick_to is None else None if user_from is None: - self._Logs.error(f"The sender nickname [{nick_from}] do not exist") + self._ctx.Logs.error(f"The sender nickname [{nick_from}] do not exist") return None if not channel is None: @@ -161,8 +161,8 @@ class Unrealircd6(IProtocol): await self.send2socket(f":{nick_from} PRIVMSG {user_to.uid} :{batch}") except Exception as err: - self._Logs.error(f"General Error: {err}") - self._Logs.error(f"General Error: {nick_from} - {channel} - {nick_to}") + self._ctx.Logs.error(f"General Error: {err}") + self._ctx.Logs.error(f"General Error: {nick_from} - {channel} - {nick_to}") async def send_notice(self, nick_from: str, nick_to: str, msg: str) -> None: """Sending NOTICE by batches @@ -173,12 +173,12 @@ class Unrealircd6(IProtocol): nick_to (str): The reciever nickname """ try: - batch_size = self._Config.BATCH_SIZE - user_from = self._Irc.User.get_user(nick_from) - user_to = self._Irc.User.get_user(nick_to) + batch_size = self._ctx.Config.BATCH_SIZE + user_from = self._ctx.User.get_user(nick_from) + user_to = self._ctx.User.get_user(nick_to) if user_from is None or user_to is None: - self._Logs.error(f"The sender [{nick_from}] or the Reciever [{nick_to}] do not exist") + self._ctx.Logs.error(f"The sender [{nick_from}] or the Reciever [{nick_to}] do not exist") return None for i in range(0, len(str(msg)), batch_size): @@ -186,31 +186,31 @@ class Unrealircd6(IProtocol): await self.send2socket(f":{user_from.uid} NOTICE {user_to.uid} :{batch}") except Exception as err: - self._Logs.error(f"General Error: {err}") + self._ctx.Logs.error(f"General Error: {err}") async def send_link(self): """Créer le link et envoyer les informations nécessaires pour la connexion au serveur. """ - service_id = self._Config.SERVICE_ID - service_nickname = self._Config.SERVICE_NICKNAME - service_username = self._Config.SERVICE_USERNAME - service_realname = self._Config.SERVICE_REALNAME - service_channel_log = self._Config.SERVICE_CHANLOG - service_info = self._Config.SERVICE_INFO - service_smodes = self._Config.SERVICE_SMODES - service_cmodes = self._Config.SERVICE_CMODES - # service_umodes = self._Config.SERVICE_UMODES - service_hostname = self._Config.SERVICE_HOST - service_name = self._Config.SERVICE_NAME + service_id = self._ctx.Config.SERVICE_ID + service_nickname = self._ctx.Config.SERVICE_NICKNAME + service_username = self._ctx.Config.SERVICE_USERNAME + service_realname = self._ctx.Config.SERVICE_REALNAME + service_channel_log = self._ctx.Config.SERVICE_CHANLOG + service_info = self._ctx.Config.SERVICE_INFO + service_smodes = self._ctx.Config.SERVICE_SMODES + service_cmodes = self._ctx.Config.SERVICE_CMODES + # service_umodes = self._ctx.Config.SERVICE_UMODES + service_hostname = self._ctx.Config.SERVICE_HOST + service_name = self._ctx.Config.SERVICE_NAME protocolversion = self.protocol_version - server_password = self._Config.SERVEUR_PASSWORD - server_link = self._Config.SERVEUR_LINK - server_id = self._Config.SERVEUR_ID + server_password = self._ctx.Config.SERVEUR_PASSWORD + server_link = self._ctx.Config.SERVEUR_LINK + server_id = self._ctx.Config.SERVEUR_ID - version = self._Config.CURRENT_VERSION - unixtime = self._Utils.get_unixtime() + version = self._ctx.Config.CURRENT_VERSION + unixtime = self._ctx.Utils.get_unixtime() await self.send2socket(f":{server_id} PASS :{server_password}", print_log=False) await self.send2socket(f":{server_id} PROTOCTL SID NOQUIT NICKv2 SJOIN SJ3 NICKIP TKLEXT2 NEXTBANS CLK EXTSWHOIS MLOCK MTAGS") @@ -225,7 +225,7 @@ class Unrealircd6(IProtocol): await self.send2socket(f":{server_id} TKL + Q * {service_nickname} {service_hostname} 0 {unixtime} :Reserved for services") await self.send2socket(f":{service_id} MODE {service_channel_log} {service_cmodes}") - self._Logs.debug(f'>> {__name__} Link information sent to the server') + self._ctx.Logs.debug(f'>> {__name__} Link information sent to the server') async def send_gline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: """Send a gline command to the server @@ -240,7 +240,7 @@ class Unrealircd6(IProtocol): """ # TKL + G user host set_by expire_timestamp set_at_timestamp :reason - await self.send2socket(f":{self._Config.SERVEUR_ID} TKL + G {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL + G {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") return None @@ -250,10 +250,10 @@ class Unrealircd6(IProtocol): Args: newnickname (str): New nickname of the server """ - await self.send2socket(f":{self._Config.SERVICE_NICKNAME} NICK {newnickname}") + await self.send2socket(f":{self._ctx.Config.SERVICE_NICKNAME} NICK {newnickname}") - user_obj = self._Irc.User.get_user(self._Config.SERVICE_NICKNAME) - self._Irc.User.update_nickname(user_obj.uid, newnickname) + user_obj = self._ctx.User.get_user(self._ctx.Config.SERVICE_NICKNAME) + self._ctx.User.update_nickname(user_obj.uid, newnickname) return None async def send_set_mode(self, modes: str, *, nickname: Optional[str] = None, channel_name: Optional[str] = None, params: Optional[str] = None) -> None: @@ -265,31 +265,31 @@ class Unrealircd6(IProtocol): channel_name (Optional[str]): The channel name params (Optional[str]): Parameters like password. """ - service_id = self._Config.SERVICE_ID + service_id = self._ctx.Config.SERVICE_ID if modes[0] not in ['+', '-']: - self._Logs.error(f"[MODE ERROR] The mode you have provided is missing the sign: {modes}") + self._ctx.Logs.error(f"[MODE ERROR] The mode you have provided is missing the sign: {modes}") return None if nickname and channel_name: # :98KAAAAAB MODE #services +o defenderdev - if not self._Irc.Channel.is_valid_channel(channel_name): - self._Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") + if not self._ctx.Channel.is_valid_channel(channel_name): + self._ctx.Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") return None await self.send2socket(f":{service_id} MODE {channel_name} {modes} {nickname}") return None - + if nickname and channel_name is None: await self.send2socket(f":{service_id} MODE {nickname} {modes}") return None - + if nickname is None and channel_name: - if not self._Irc.Channel.is_valid_channel(channel_name): - self._Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") + if not self._ctx.Channel.is_valid_channel(channel_name): + self._ctx.Logs.error(f"[MODE ERROR] The channel is not valid: {channel_name}") return None - await self.send2socket(f":{service_id} MODE {channel_name} {modes} {params}") + await self.send2socket(f":{service_id} MODE {channel_name} {modes}") if params is None else await self.send2socket(f":{service_id} MODE {channel_name} {modes} {params}") return None - + return None async def send_squit(self, server_id: str, server_link: str, reason: str) -> None: @@ -302,20 +302,20 @@ class Unrealircd6(IProtocol): async def send_ungline(self, nickname:str, hostname: str) -> None: - await self.send2socket(f":{self._Config.SERVEUR_ID} TKL - G {nickname} {hostname} {self._Config.SERVICE_NICKNAME}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL - G {nickname} {hostname} {self._ctx.Config.SERVICE_NICKNAME}") return None async def send_kline(self, nickname: str, hostname: str, set_by: str, expire_timestamp: int, set_at_timestamp: int, reason: str) -> None: # TKL + k user host set_by expire_timestamp set_at_timestamp :reason - await self.send2socket(f":{self._Config.SERVEUR_ID} TKL + k {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL + k {nickname} {hostname} {set_by} {expire_timestamp} {set_at_timestamp} :{reason}") return None async def send_unkline(self, nickname:str, hostname: str) -> None: - await self.send2socket(f":{self._Config.SERVEUR_ID} TKL - K {nickname} {hostname} {self._Config.SERVICE_NICKNAME}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} TKL - K {nickname} {hostname} {self._ctx.Config.SERVICE_NICKNAME}") return None @@ -325,15 +325,15 @@ class Unrealircd6(IProtocol): Args: channel (str): Channel to join """ - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None - await self.send2socket(f":{self._Config.SERVEUR_ID} SJOIN {self._Utils.get_unixtime()} {channel} {self._Config.SERVICE_UMODES} :{self._Config.SERVICE_ID}") - await self.send2socket(f":{self._Config.SERVICE_ID} MODE {channel} {self._Config.SERVICE_UMODES} {self._Config.SERVICE_ID}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} SJOIN {self._ctx.Utils.get_unixtime()} {channel} {self._ctx.Config.SERVICE_UMODES} :{self._ctx.Config.SERVICE_ID}") + await self.send2socket(f":{self._ctx.Config.SERVICE_ID} MODE {channel} {self._ctx.Config.SERVICE_UMODES} {self._ctx.Config.SERVICE_ID}") # Add defender to the channel uids list - self._Irc.Channel.insert(self._Irc.Loader.Definition.MChannel(name=channel, uids=[self._Config.SERVICE_ID])) + self._ctx.Channel.insert(self._ctx.Definition.MChannel(name=channel, uids=[self._ctx.Config.SERVICE_ID])) return None async def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None: @@ -345,20 +345,20 @@ class Unrealircd6(IProtocol): """ try: - user_obj = self._Irc.User.get_user(uidornickname=nick_to_sapart) - chan_obj = self._Irc.Channel.get_channel(channel_name) - service_uid = self._Config.SERVICE_ID + user_obj = self._ctx.User.get_user(uidornickname=nick_to_sapart) + chan_obj = self._ctx.Channel.get_channel(channel_name) + service_uid = self._ctx.Config.SERVICE_ID if user_obj is None or chan_obj is None: return None await self.send2socket(f":{service_uid} SAPART {user_obj.nickname} {chan_obj.name}") - self._Irc.Channel.delete_user_from_channel(chan_obj.name, user_obj.uid) + self._ctx.Channel.delete_user_from_channel(chan_obj.name, user_obj.uid) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def send_sajoin(self, nick_to_sajoin: str, channel_name: str) -> None: """_summary_ @@ -369,9 +369,9 @@ class Unrealircd6(IProtocol): """ try: - user_obj = self._Irc.User.get_user(uidornickname=nick_to_sajoin) - chan_obj = self._Irc.Channel.get_channel(channel_name) - service_uid = self._Config.SERVICE_ID + user_obj = self._ctx.User.get_user(uidornickname=nick_to_sajoin) + chan_obj = self._ctx.Channel.get_channel(channel_name) + service_uid = self._ctx.Config.SERVICE_ID if user_obj is None: # User not exist: leave @@ -379,53 +379,53 @@ class Unrealircd6(IProtocol): if chan_obj is None: # Channel not exist - if not self._Irc.Channel.is_valid_channel(channel_name): + if not self._ctx.Channel.is_valid_channel(channel_name): # Incorrect channel: leave return None # Create the new channel with the uid - new_chan_obj = self._Irc.Loader.Definition.MChannel(name=channel_name, uids=[user_obj.uid]) - self._Irc.Channel.insert(new_chan_obj) + new_chan_obj = self._ctx.Definition.MChannel(name=channel_name, uids=[user_obj.uid]) + self._ctx.Channel.insert(new_chan_obj) await self.send2socket(f":{service_uid} SAJOIN {user_obj.nickname} {new_chan_obj.name}") else: - self._Irc.Channel.add_user_to_a_channel(channel_name=channel_name, uid=user_obj.uid) + self._ctx.Channel.add_user_to_a_channel(channel_name=channel_name, uid=user_obj.uid) await self.send2socket(f":{service_uid} SAJOIN {user_obj.nickname} {chan_obj.name}") return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def send_svspart(self, nick_to_part: str, channels: list[str], reason: str) -> None: - user_obj = self._Irc.User.get_user(nick_to_part) + user_obj = self._ctx.User.get_user(nick_to_part) if user_obj is None: - self._Logs.debug(f"[SVSPART] The nickname {nick_to_part} do not exist!") + self._ctx.Logs.debug(f"[SVSPART] The nickname {nick_to_part} do not exist!") return None - channels_list = ','.join([channel for channel in channels if self._Irc.Channel.is_valid_channel(channel)]) - service_id = self._Config.SERVICE_ID + channels_list = ','.join([channel for channel in channels if self._ctx.Channel.is_valid_channel(channel)]) + service_id = self._ctx.Config.SERVICE_ID await self.send2socket(f':{service_id} SVSPART {user_obj.nickname} {channels_list} {reason}') return None async def send_svsjoin(self, nick_to_part: str, channels: list[str], keys: list[str]) -> None: - user_obj = self._Irc.User.get_user(nick_to_part) + user_obj = self._ctx.User.get_user(nick_to_part) if user_obj is None: - self._Logs.debug(f"[SVSJOIN] The nickname {nick_to_part} do not exist!") + self._ctx.Logs.debug(f"[SVSJOIN] The nickname {nick_to_part} do not exist!") return None - channels_list = ','.join([channel for channel in channels if self._Irc.Channel.is_valid_channel(channel)]) + channels_list = ','.join([channel for channel in channels if self._ctx.Channel.is_valid_channel(channel)]) keys_list = ','.join([key for key in keys]) - service_id = self._Config.SERVICE_ID + service_id = self._ctx.Config.SERVICE_ID await self.send2socket(f':{service_id} SVSJOIN {user_obj.nickname} {channels_list} {keys_list}') return None async def send_svsmode(self, nickname: str, user_mode: str) -> None: try: - user_obj = self._Irc.User.get_user(uidornickname=nickname) - service_uid = self._Config.SERVICE_ID + user_obj = self._ctx.User.get_user(uidornickname=nickname) + service_uid = self._ctx.Config.SERVICE_ID if user_obj is None: return None @@ -433,16 +433,16 @@ class Unrealircd6(IProtocol): await self.send2socket(f':{service_uid} SVSMODE {nickname} {user_mode}') # Update new mode - self._Irc.User.update_mode(user_obj.uid, user_mode) + self._ctx.User.update_mode(user_obj.uid, user_mode) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def send_svs2mode(self, nickname: str, user_mode: str) -> None: try: - user_obj = self._Irc.User.get_user(uidornickname=nickname) - service_uid = self._Config.SERVICE_ID + user_obj = self._ctx.User.get_user(uidornickname=nickname) + service_uid = self._ctx.Config.SERVICE_ID if user_obj is None: return None @@ -450,11 +450,11 @@ class Unrealircd6(IProtocol): await self.send2socket(f':{service_uid} SVS2MODE {nickname} {user_mode}') # Update new mode - self._Irc.User.update_mode(user_obj.uid, user_mode) + self._ctx.User.update_mode(user_obj.uid, user_mode) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def send_svslogin(self, client_uid: str, user_account: str) -> None: """Log a client into his account. @@ -464,9 +464,9 @@ class Unrealircd6(IProtocol): user_account (str): The account of the user """ try: - await self.send2socket(f":{self._Irc.Config.SERVEUR_LINK} SVSLOGIN {self._Settings.MAIN_SERVER_HOSTNAME} {client_uid} {user_account}") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SVSLOGIN {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {client_uid} {user_account}") except Exception as err: - self._Logs.error(f'General Error: {err}') + self._ctx.Logs.error(f'General Error: {err}') async def send_svslogout(self, client_obj: 'MClient') -> None: """Logout a client from his account @@ -477,11 +477,11 @@ class Unrealircd6(IProtocol): try: c_uid = client_obj.uid c_nickname = client_obj.nickname - await self.send2socket(f":{self._Irc.Config.SERVEUR_LINK} SVSLOGIN {self._Settings.MAIN_SERVER_HOSTNAME} {c_uid} 0") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SVSLOGIN {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {c_uid} 0") self.send_svs2mode(c_nickname, '-r') except Exception as err: - self._Logs.error(f'General Error: {err}') + self._ctx.Logs.error(f'General Error: {err}') async def send_quit(self, uid: str, reason: str, print_log: bool = True) -> None: """Send quit message @@ -493,18 +493,18 @@ class Unrealircd6(IProtocol): reason (str): The reason for the quit print_log (bool): Print the log """ - user_obj = self._Irc.User.get_user(uidornickname=uid) - reputation_obj = self._Irc.Reputation.get_reputation(uidornickname=uid) + user_obj = self._ctx.User.get_user(uidornickname=uid) + reputation_obj = self._ctx.Reputation.get_reputation(uidornickname=uid) if not user_obj is None: await self.send2socket(f":{user_obj.uid} QUIT :{reason}", print_log=print_log) - self._Irc.User.delete(user_obj.uid) + self._ctx.User.delete(user_obj.uid) if not reputation_obj is None: - self._Irc.Reputation.delete(reputation_obj.uid) + self._ctx.Reputation.delete(reputation_obj.uid) - if not self._Irc.Channel.delete_user_from_all_channel(uid): - self._Logs.error(f"The UID [{uid}] has not been deleted from all channels") + if not self._ctx.Channel.delete_user_from_all_channel(uid): + self._ctx.Logs.error(f"The UID [{uid}] has not been deleted from all channels") return None @@ -524,28 +524,28 @@ class Unrealircd6(IProtocol): print_log (bool, optional): print logs if true. Defaults to True. """ # {self.Config.SERVEUR_ID} UID - # {clone.nickname} 1 {self._Utils.get_unixtime()} {clone.username} {clone.hostname} {clone.uid} * {clone.umodes} {clone.vhost} * {self.Base.encode_ip(clone.remote_ip)} :{clone.realname} + # {clone.nickname} 1 {self._ctx.Utils.get_unixtime()} {clone.username} {clone.hostname} {clone.uid} * {clone.umodes} {clone.vhost} * {self.Base.encode_ip(clone.remote_ip)} :{clone.realname} try: - unixtime = self._Utils.get_unixtime() - encoded_ip = self._Base.encode_ip(remote_ip) + unixtime = self._ctx.Utils.get_unixtime() + encoded_ip = self._ctx.Base.encode_ip(remote_ip) # Create the user - self._Irc.User.insert( - self._Irc.Loader.Definition.MUser( + self._ctx.User.insert( + self._ctx.Definition.MUser( uid=uid, nickname=nickname, username=username, realname=realname,hostname=hostname, umodes=umodes, vhost=vhost, remote_ip=remote_ip ) ) - uid_msg = f":{self._Config.SERVEUR_ID} UID {nickname} 1 {unixtime} {username} {hostname} {uid} * {umodes} {vhost} * {encoded_ip} :{realname}" + uid_msg = f":{self._ctx.Config.SERVEUR_ID} UID {nickname} 1 {unixtime} {username} {hostname} {uid} * {umodes} {vhost} * {encoded_ip} :{realname}" await self.send2socket(uid_msg, print_log=print_log) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def send_join_chan(self, uidornickname: str, channel: str, password: str = None, print_log: bool = True) -> None: """Joining a channel @@ -557,34 +557,34 @@ class Unrealircd6(IProtocol): print_log (bool, optional): Write logs. Defaults to True. """ - user_obj = self._Irc.User.get_user(uidornickname) + user_obj = self._ctx.User.get_user(uidornickname) pwd_channel = password if not password is None else '' if user_obj is None: return None - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None await self.send2socket(f":{user_obj.uid} JOIN {channel} {pwd_channel}", print_log=print_log) - if uidornickname == self._Config.SERVICE_NICKNAME or uidornickname == self._Config.SERVICE_ID: - await self.send2socket(f":{self._Config.SERVICE_ID} MODE {channel} {self._Config.SERVICE_UMODES} {self._Config.SERVICE_ID}") + if uidornickname == self._ctx.Config.SERVICE_NICKNAME or uidornickname == self._ctx.Config.SERVICE_ID: + await self.send2socket(f":{self._ctx.Config.SERVICE_ID} MODE {channel} {self._ctx.Config.SERVICE_UMODES} {self._ctx.Config.SERVICE_ID}") # Add defender to the channel uids list - self._Irc.Channel.insert(self._Irc.Loader.Definition.MChannel(name=channel, uids=[user_obj.uid])) + self._ctx.Channel.insert(self._ctx.Definition.MChannel(name=channel, uids=[user_obj.uid])) # Set the automode to the user if 'r' not in user_obj.umodes and 'o' not in user_obj.umodes: return None db_data: dict[str, str] = {"nickname": user_obj.nickname, "channel": channel} - db_query = self._Base.db_execute_query("SELECT id, mode FROM command_automode WHERE nickname = :nickname AND channel = :channel", db_data) + db_query = await self._ctx.Base.db_execute_query("SELECT id, mode FROM command_automode WHERE nickname = :nickname AND channel = :channel", db_data) db_result = db_query.fetchone() if db_result is not None: id_cmd_automode, mode = db_result - await self.send2socket(f":{self._Config.SERVICE_ID} MODE {channel} {mode} {user_obj.nickname}") + await self.send2socket(f":{self._ctx.Config.SERVICE_ID} MODE {channel} {mode} {user_obj.nickname}") return None @@ -597,35 +597,35 @@ class Unrealircd6(IProtocol): print_log (bool, optional): Write logs. Defaults to True. """ - u = self._Irc.User.get_user(uidornickname) + u = self._ctx.User.get_user(uidornickname) if u is None: - self._Logs.error(f"The user [{uidornickname}] is not valid") + self._ctx.Logs.error(f"The user [{uidornickname}] is not valid") return None - if not self._Irc.Channel.is_valid_channel(channel): - self._Logs.error(f"The channel [{channel}] is not valid") + if not self._ctx.Channel.is_valid_channel(channel): + self._ctx.Logs.error(f"The channel [{channel}] is not valid") return None await self.send2socket(f":{u.uid} PART {channel}", print_log=print_log) # Add defender to the channel uids list - self._Irc.Channel.delete_user_from_channel(channel, u.uid) + self._ctx.Channel.delete_user_from_channel(channel, u.uid) return None async def send_mode_chan(self, channel_name: str, channel_mode: str) -> None: - channel = self._Irc.Channel.is_valid_channel(channel_name) + channel = self._ctx.Channel.is_valid_channel(channel_name) if not channel: - self._Logs.error(f'The channel [{channel_name}] is not correct') + self._ctx.Logs.error(f'The channel [{channel_name}] is not correct') return None - await self.send2socket(f":{self._Config.SERVICE_NICKNAME} MODE {channel_name} {channel_mode}") + await self.send2socket(f":{self._ctx.Config.SERVICE_NICKNAME} MODE {channel_name} {channel_mode}") return None async def send_raw(self, raw_command: str) -> None: - await self.send2socket(f":{self._Config.SERVICE_NICKNAME} {raw_command}") + await self.send2socket(f":{self._ctx.Config.SERVICE_NICKNAME} {raw_command}") return None @@ -644,7 +644,7 @@ class Unrealircd6(IProtocol): scopy.pop(0) uid = scopy[7] - return self._User.get_user(uid) + return self._ctx.User.get_user(uid) def parse_quit(self, server_msg: list[str]) -> tuple[Optional['MUser'], str]: """Parse quit and return dictionary. @@ -659,7 +659,7 @@ class Unrealircd6(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - user_obj = self._User.get_user(self._Utils.clean_uid(scopy[0])) + user_obj = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[0])) tmp_reason = scopy[3:] tmp_reason[0] = tmp_reason[0].replace(':', '') reason = ' '.join(tmp_reason) @@ -682,7 +682,7 @@ class Unrealircd6(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - user_obj = self._User.get_user(self._User.clean_uid(scopy[0])) + user_obj = self._ctx.User.get_user(self._ctx.User.clean_uid(scopy[0])) newnickname = scopy[2] timestamp = scopy[3] return user_obj, newnickname, timestamp @@ -702,9 +702,9 @@ class Unrealircd6(IProtocol): if scopy[0].startswith('@'): scopy.pop(0) - sender = self._User.get_user(self._Utils.clean_uid(scopy[0])) - reciever = self._User.get_user(self._Utils.clean_uid(scopy[2])) - channel = self._Channel.get_channel(scopy[2]) if self._Channel.is_valid_channel(scopy[2]) else None + sender = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[0])) + reciever = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[2])) + channel = self._ctx.Channel.get_channel(scopy[2]) if self._ctx.Channel.is_valid_channel(scopy[2]) else None tmp_message = scopy[3:] tmp_message[0] = tmp_message[0].replace(':', '') @@ -729,19 +729,19 @@ class Unrealircd6(IProtocol): uid_user_to_edit = scopy[2] umode = scopy[3] - u = self._Irc.User.get_user(uid_user_to_edit) + u = self._ctx.User.get_user(uid_user_to_edit) if u is None: return None - if self._Irc.User.update_mode(u.uid, umode): + if self._ctx.User.update_mode(u.uid, umode): return None return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_mode(self, server_msg: list[str]) -> None: """Handle mode coming from a server @@ -764,22 +764,22 @@ class Unrealircd6(IProtocol): try: # [':adator_', 'UMODE2', '-iwx'] scopy = server_msg.copy() - u = self._Irc.User.get_user(str(scopy[0]).lstrip(':')) + u = self._ctx.User.get_user(str(scopy[0]).lstrip(':')) user_mode = scopy[2] if u is None: # If user is not created return None # TODO : User object should be able to update user modes - if self._Irc.User.update_mode(u.uid, user_mode): + if self._ctx.User.update_mode(u.uid, user_mode): return None return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_quit(self, server_msg: list[str]) -> None: """Handle quit coming from a server @@ -792,18 +792,18 @@ class Unrealircd6(IProtocol): scopy = server_msg.copy() uid_who_quit = str(scopy[1]).lstrip(':') - self._Irc.Channel.delete_user_from_all_channel(uid_who_quit) - self._Irc.User.delete(uid_who_quit) - self._Irc.Client.delete(uid_who_quit) - self._Irc.Reputation.delete(uid_who_quit) - self._Irc.Admin.delete(uid_who_quit) + self._ctx.Channel.delete_user_from_all_channel(uid_who_quit) + self._ctx.User.delete(uid_who_quit) + self._ctx.Client.delete(uid_who_quit) + self._ctx.Reputation.delete(uid_who_quit) + self._ctx.Admin.delete(uid_who_quit) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_squit(self, server_msg: list[str]) -> None: """Handle squit coming from a server @@ -815,15 +815,15 @@ class Unrealircd6(IProtocol): scopy = server_msg.copy() server_hostname = scopy[2] uid_to_delete = None - for s_user in self._Irc.User.UID_DB: + for s_user in self._ctx.User.UID_DB: if s_user.hostname == server_hostname and 'S' in s_user.umodes: uid_to_delete = s_user.uid if uid_to_delete is None: return None - self._Irc.User.delete(uid_to_delete) - self._Irc.Channel.delete_user_from_all_channel(uid_to_delete) + self._ctx.User.delete(uid_to_delete) + self._ctx.Channel.delete_user_from_all_channel(uid_to_delete) return None @@ -858,9 +858,9 @@ class Unrealircd6(IProtocol): if user_modes is None or prefix is None or host_server_id is None: return None - self._Config.HSID = host_server_id - self._Settings.PROTOCTL_USER_MODES = list(user_modes) - self._Settings.PROTOCTL_PREFIX = list(prefix) + self._ctx.Config.HSID = host_server_id + self._ctx.Settings.PROTOCTL_USER_MODES = list(user_modes) + self._ctx.Settings.PROTOCTL_PREFIX = list(prefix) return None @@ -877,17 +877,17 @@ class Unrealircd6(IProtocol): uid = str(server_msg[1]).lstrip(':') newnickname = server_msg[3] - self._Irc.User.update_nickname(uid, newnickname) - self._Irc.Client.update_nickname(uid, newnickname) - self._Irc.Admin.update_nickname(uid, newnickname) - self._Irc.Reputation.update(uid, newnickname) + self._ctx.User.update_nickname(uid, newnickname) + self._ctx.Client.update_nickname(uid, newnickname) + self._ctx.Admin.update_nickname(uid, newnickname) + self._ctx.Reputation.update(uid, newnickname) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_sjoin(self, server_msg: list[str]) -> None: """Handle sjoin coming from a server @@ -924,13 +924,13 @@ class Unrealircd6(IProtocol): # Boucle qui va ajouter l'ensemble des users (UID) for i in range(start_boucle, len(scopy)): parsed_uid = str(scopy[i]) - clean_uid = self._Utils.clean_uid(parsed_uid) + clean_uid = self._ctx.Utils.clean_uid(parsed_uid) if not clean_uid is None and len(clean_uid) == 9: list_users.append(clean_uid) if list_users: - self._Irc.Channel.insert( - self._Irc.Loader.Definition.MChannel( + self._ctx.Channel.insert( + self._ctx.Definition.MChannel( name=channel, uids=list_users ) @@ -938,9 +938,9 @@ class Unrealircd6(IProtocol): return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_part(self, server_msg: list[str]) -> None: """Handle part coming from a server @@ -952,13 +952,13 @@ class Unrealircd6(IProtocol): # ['@unrealircd.org', ':001EPFBRD', 'PART', '#welcome', ':WEB', 'IRC', 'Paris'] uid = str(server_msg[1]).lstrip(':') channel = str(server_msg[3]).lower() - self._Irc.Channel.delete_user_from_channel(channel, uid) + self._ctx.Channel.delete_user_from_channel(channel, uid) return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_eos(self, server_msg: list[str]) -> None: """Handle EOS coming from a server @@ -970,71 +970,71 @@ class Unrealircd6(IProtocol): # [':001', 'EOS'] server_msg_copy = server_msg.copy() hsid = str(server_msg_copy[0]).replace(':','') - if hsid == self._Config.HSID: - if self._Config.DEFENDER_INIT == 1: - current_version = self._Config.CURRENT_VERSION - latest_version = self._Config.LATEST_VERSION - if self._Base.check_for_new_version(False): + if hsid == self._ctx.Config.HSID: + if self._ctx.Config.DEFENDER_INIT == 1: + current_version = self._ctx.Config.CURRENT_VERSION + latest_version = self._ctx.Config.LATEST_VERSION + if self._ctx.Base.check_for_new_version(False): version = f'{current_version} >>> {latest_version}' else: version = f'{current_version}' print(f"################### DEFENDER ###################") print(f"# SERVICE CONNECTE ") - print(f"# SERVEUR : {self._Config.SERVEUR_IP} ") - print(f"# PORT : {self._Config.SERVEUR_PORT} ") - print(f"# SSL : {self._Config.SERVEUR_SSL} ") - print(f"# SSL VER : {self._Config.SSL_VERSION} ") - print(f"# NICKNAME : {self._Config.SERVICE_NICKNAME} ") - print(f"# CHANNEL : {self._Config.SERVICE_CHANLOG} ") + print(f"# SERVEUR : {self._ctx.Config.SERVEUR_IP} ") + print(f"# PORT : {self._ctx.Config.SERVEUR_PORT} ") + print(f"# SSL : {self._ctx.Config.SERVEUR_SSL} ") + print(f"# SSL VER : {self._ctx.Config.SSL_VERSION} ") + print(f"# NICKNAME : {self._ctx.Config.SERVICE_NICKNAME} ") + print(f"# CHANNEL : {self._ctx.Config.SERVICE_CHANLOG} ") print(f"# VERSION : {version} ") print(f"################################################") - self._Logs.info(f"################### DEFENDER ###################") - self._Logs.info(f"# SERVICE CONNECTE ") - self._Logs.info(f"# SERVEUR : {self._Config.SERVEUR_IP} ") - self._Logs.info(f"# PORT : {self._Config.SERVEUR_PORT} ") - self._Logs.info(f"# SSL : {self._Config.SERVEUR_SSL} ") - self._Logs.info(f"# SSL VER : {self._Config.SSL_VERSION} ") - self._Logs.info(f"# NICKNAME : {self._Config.SERVICE_NICKNAME} ") - self._Logs.info(f"# CHANNEL : {self._Config.SERVICE_CHANLOG} ") - self._Logs.info(f"# VERSION : {version} ") - self._Logs.info(f"################################################") + self._ctx.Logs.info(f"################### DEFENDER ###################") + self._ctx.Logs.info(f"# SERVICE CONNECTE ") + self._ctx.Logs.info(f"# SERVEUR : {self._ctx.Config.SERVEUR_IP} ") + self._ctx.Logs.info(f"# PORT : {self._ctx.Config.SERVEUR_PORT} ") + self._ctx.Logs.info(f"# SSL : {self._ctx.Config.SERVEUR_SSL} ") + self._ctx.Logs.info(f"# SSL VER : {self._ctx.Config.SSL_VERSION} ") + self._ctx.Logs.info(f"# NICKNAME : {self._ctx.Config.SERVICE_NICKNAME} ") + self._ctx.Logs.info(f"# CHANNEL : {self._ctx.Config.SERVICE_CHANLOG} ") + self._ctx.Logs.info(f"# VERSION : {version} ") + self._ctx.Logs.info(f"################################################") - await self.send_sjoin(self._Config.SERVICE_CHANLOG) + await self.send_sjoin(self._ctx.Config.SERVICE_CHANLOG) - if self._Base.check_for_new_version(False): + if self._ctx.Base.check_for_new_version(False): await self.send_priv_msg( - nick_from=self._Config.SERVICE_NICKNAME, + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f" New Version available {version}", - channel=self._Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) # Initialisation terminé aprés le premier PING await self.send_priv_msg( - nick_from=self._Config.SERVICE_NICKNAME, - msg=tr("[ %sINFORMATION%s ] >> %s is ready!", self._Config.COLORS.green, self._Config.COLORS.nogc, self._Config.SERVICE_NICKNAME), - channel=self._Config.SERVICE_CHANLOG + nick_from=self._ctx.Config.SERVICE_NICKNAME, + msg=tr("[ %sINFORMATION%s ] >> %s is ready!", self._ctx.Config.COLORS.green, self._ctx.Config.COLORS.nogc, self._ctx.Config.SERVICE_NICKNAME), + channel=self._ctx.Config.SERVICE_CHANLOG ) - self._Config.DEFENDER_INIT = 0 + self._ctx.Config.DEFENDER_INIT = 0 # Send EOF to other modules - for module in self._Irc.ModuleUtils.model_get_loaded_modules().copy(): + for module in self._ctx.ModuleUtils.model_get_loaded_modules().copy(): module.class_instance.cmd(server_msg_copy) # Join saved channels & load existing modules - await self._Irc.join_saved_channels() - await self._Irc.ModuleUtils.db_load_all_existing_modules(self._Irc) + await self._ctx.Channel.db_join_saved_channels() + await self._ctx.ModuleUtils.db_load_all_existing_modules() - await self.send2socket(f":{self._Config.SERVEUR_ID} SMOD :L:Defender:1.0.0 :L:Command:1.0.0") + await self.send2socket(f":{self._ctx.Config.SERVEUR_ID} SMOD :L:Defender:1.0.0 :L:Command:1.0.0") return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except KeyError as ke: - self._Logs.error(f"{__name__} - Key Error: {ke}") + self._ctx.Logs.error(f"{__name__} - Key Error: {ke}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}", exc_info=True) async def on_reputation(self, server_msg: list[str]) -> None: """Handle REPUTATION coming from a server @@ -1045,27 +1045,27 @@ class Unrealircd6(IProtocol): try: # :001 REPUTATION 127.0.0.1 118 server_msg_copy = server_msg.copy() - self._Irc.first_connexion_ip = server_msg_copy[2] - self._Irc.first_score = 0 + self._ctx.Irc.first_connexion_ip = server_msg_copy[2] + self._ctx.Irc.first_score = 0 if str(server_msg_copy[3]).find('*') != -1: # If * available, it means that an ircop changed the repurtation score # means also that the user exist will try to update all users with same IP - self._Irc.first_score = int(str(server_msg_copy[3]).replace('*','')) - for user in self._Irc.User.UID_DB: - if user.remote_ip == self._Irc.first_connexion_ip: - user.score_connexion = self._Irc.first_score + self._ctx.Irc.first_score = int(str(server_msg_copy[3]).replace('*','')) + for user in self._ctx.User.UID_DB: + if user.remote_ip == self._ctx.Irc.first_connexion_ip: + user.score_connexion = self._ctx.Irc.first_score else: - self._Irc.first_score = int(server_msg_copy[3]) + self._ctx.Irc.first_score = int(server_msg_copy[3]) # Possibilité de déclancher les bans a ce niveau. except IndexError as ie: - self._Logs.error(f'Index Error {__name__}: {ie}') + self._ctx.Logs.error(f'Index Error {__name__}: {ie}') except ValueError as ve: - self._Irc.first_score = 0 - self._Logs.error(f'Value Error {__name__}: {ve}', exc_info=True) + self._ctx.Irc.first_score = 0 + self._ctx.Logs.error(f'Value Error {__name__}: {ve}', exc_info=True) except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_uid(self, server_msg: list[str]) -> None: """Handle uid message coming from the server @@ -1087,7 +1087,7 @@ class Unrealircd6(IProtocol): hostname = str(scopy[7]) umodes = str(scopy[10]) vhost = str(scopy[11]) - remote_ip = '127.0.0.1' if 'S' in umodes else self._Base.decode_ip(str(scopy[13])) + remote_ip = '127.0.0.1' if 'S' in umodes else self._ctx.Base.decode_ip(str(scopy[13])) # extract realname realname = ' '.join(scopy[14:]).lstrip(':') @@ -1106,10 +1106,10 @@ class Unrealircd6(IProtocol): pattern = r'^.*tls_cipher=([^;]+).*$' tlsc_match = match(pattern, scopy[0]) tls_cipher = tlsc_match.group(1) if tlsc_match else None - score_connexion = self._Irc.first_score + score_connexion = self._ctx.Irc.first_score - self._Irc.User.insert( - self._Irc.Loader.Definition.MUser( + self._ctx.User.insert( + self._ctx.Definition.MUser( uid=uid, nickname=nickname, username=username, @@ -1129,22 +1129,22 @@ class Unrealircd6(IProtocol): ) # Auto Auth admin via fingerprint - dnickname = self._Config.SERVICE_NICKNAME - dchanlog = self._Config.SERVICE_CHANLOG - green = self._Config.COLORS.green - red = self._Config.COLORS.red - nogc = self._Config.COLORS.nogc + dnickname = self._ctx.Config.SERVICE_NICKNAME + dchanlog = self._ctx.Config.SERVICE_CHANLOG + green = self._ctx.Config.COLORS.green + red = self._ctx.Config.COLORS.red + nogc = self._ctx.Config.COLORS.nogc - # for module in self._Irc.ModuleUtils.model_get_loaded_modules().copy(): + # for module in self._ctx.ModuleUtils.model_get_loaded_modules().copy(): # module.class_instance.cmd(serverMsg) # SASL authentication # ['@s2s-md/..', ':001', 'UID', 'adator__', '0', '1755987444', '...', 'desktop-h1qck20.mshome.net', '001XLTT0U', '0', '+iwxz', '*', 'Clk-EC2256B2.mshome.net', 'rBKAAQ==', ':...'] - sasl_obj = self._Irc.Sasl.get_sasl_obj(uid) + sasl_obj = self._ctx.Sasl.get_sasl_obj(uid) if sasl_obj: if sasl_obj.auth_success: - self._Irc.insert_db_admin(sasl_obj.client_uid, sasl_obj.username, sasl_obj.level, sasl_obj.language) + self._ctx.Irc.insert_db_admin(sasl_obj.client_uid, sasl_obj.username, sasl_obj.level, sasl_obj.language) await self.send_priv_msg(nick_from=dnickname, msg=tr("[ %sSASL AUTH%s ] - %s (%s) is now connected successfuly to %s", green, nogc, nickname, sasl_obj.username, dnickname), channel=dchanlog) @@ -1156,12 +1156,12 @@ class Unrealircd6(IProtocol): await self.send_notice(nick_from=dnickname, nick_to=nickname, msg=tr("Wrong password!")) # Delete sasl object! - self._Irc.Sasl.delete_sasl_client(uid) + self._ctx.Sasl.delete_sasl_client(uid) return None # If no sasl authentication then auto connect via fingerprint - if self._Irc.Admin.db_auth_admin_via_fingerprint(fingerprint, uid): - admin = self._Irc.Admin.get_admin(uid) + if await self._ctx.Admin.db_auth_admin_via_fingerprint(fingerprint, uid): + admin = self._ctx.Admin.get_admin(uid) account = admin.account if admin else '' await self.send_priv_msg(nick_from=dnickname, msg=tr("[ %sFINGERPRINT AUTH%s ] - %s (%s) is now connected successfuly to %s", green, nogc, nickname, account, dnickname), @@ -1170,9 +1170,9 @@ class Unrealircd6(IProtocol): return None except IndexError as ie: - self._Logs.error(f"{__name__} - Index Error: {ie}") + self._ctx.Logs.error(f"{__name__} - Index Error: {ie}") except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_privmsg(self, server_msg: list[str]) -> None: """Handle PRIVMSG message coming from the server @@ -1189,31 +1189,31 @@ class Unrealircd6(IProtocol): cmd.pop(0) get_uid_or_nickname = str(cmd[0].replace(':','')) - user_trigger = self._Irc.User.get_nickname(get_uid_or_nickname) - pattern = fr'(:\{self._Config.SERVICE_PREFIX})(.*)$' + user_trigger = self._ctx.User.get_nickname(get_uid_or_nickname) + pattern = fr'(:\{self._ctx.Config.SERVICE_PREFIX})(.*)$' hcmds = search(pattern, ' '.join(cmd)) # va matcher avec tout les caractéres aprés le . if hcmds: # Commande qui commencent par le point liste_des_commandes = list(hcmds.groups()) convert_to_string = ' '.join(liste_des_commandes) arg = convert_to_string.split() - arg.remove(f':{self._Config.SERVICE_PREFIX}') - if not self._Irc.Commands.is_command_exist(arg[0]): - self._Logs.debug(f"This command {arg[0]} is not available") + arg.remove(f':{self._ctx.Config.SERVICE_PREFIX}') + if not self._ctx.Commands.is_command_exist(arg[0]): + self._ctx.Logs.debug(f"This command {arg[0]} is not available") await self.send_notice( - nick_from=self._Config.SERVICE_NICKNAME, + nick_from=self._ctx.Config.SERVICE_NICKNAME, nick_to=user_trigger, - msg=f"This command [{self._Config.COLORS.bold}{arg[0]}{self._Config.COLORS.bold}] is not available" + msg=f"This command [{self._ctx.Config.COLORS.bold}{arg[0]}{self._ctx.Config.COLORS.bold}] is not available" ) return None cmd_to_send = convert_to_string.replace(':','') - self._Base.log_cmd(user_trigger, cmd_to_send) + await self._ctx.Base.log_cmd(user_trigger, cmd_to_send) - fromchannel = str(cmd[2]).lower() if self._Irc.Channel.is_valid_channel(cmd[2]) else None - await self._Irc.hcmds(user_trigger, fromchannel, arg, cmd) + fromchannel = str(cmd[2]).lower() if self._ctx.Channel.is_valid_channel(cmd[2]) else None + await self._ctx.Irc.hcmds(user_trigger, fromchannel, arg, cmd) - if cmd[2] == self._Config.SERVICE_ID: + if cmd[2] == self._ctx.Config.SERVICE_ID: pattern = fr'^:.*?:(.*)$' hcmds = search(pattern, ' '.join(cmd)) @@ -1237,26 +1237,26 @@ class Unrealircd6(IProtocol): await self.on_ping(srv_msg) return None - if not self._Irc.Commands.is_command_exist(arg[0]): - self._Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") + if not self._ctx.Commands.is_command_exist(arg[0]): + self._ctx.Logs.debug(f"This command {arg[0]} sent by {user_trigger} is not available") return None cmd_to_send = convert_to_string.replace(':','') - self._Base.log_cmd(user_trigger, cmd_to_send) + await self._ctx.Base.log_cmd(user_trigger, cmd_to_send) fromchannel = None if len(arg) >= 2: - fromchannel = str(arg[1]).lower() if self._Irc.Channel.is_valid_channel(arg[1]) else None + fromchannel = str(arg[1]).lower() if self._ctx.Channel.is_valid_channel(arg[1]) else None - await self._Irc.hcmds(user_trigger, fromchannel, arg, cmd) + await self._ctx.Irc.hcmds(user_trigger, fromchannel, arg, cmd) return None except KeyError as ke: - self._Logs.error(f"Key Error: {ke}") + self._ctx.Logs.error(f"Key Error: {ke}") except AttributeError as ae: - self._Logs.error(f"Attribute Error: {ae}") + self._ctx.Logs.error(f"Attribute Error: {ae}", exc_info=True) except Exception as err: - self._Logs.error(f"General Error: {err} - {srv_msg}" , exc_info=True) + self._ctx.Logs.error(f"General Error: {err} - {srv_msg}" , exc_info=True) async def on_server_ping(self, server_msg: list[str]) -> None: """Send a PONG message to the server @@ -1266,11 +1266,11 @@ class Unrealircd6(IProtocol): """ try: scopy = server_msg.copy() - await self.send2socket(' '.join(scopy).replace('PING', 'PONG'), print_log=True) + await self.send2socket(' '.join(scopy).replace('PING', 'PONG'), print_log=False) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_server(self, server_msg: list[str]) -> None: """_summary_ @@ -1281,9 +1281,9 @@ class Unrealircd6(IProtocol): try: # ['SERVER', 'irc.local.org', '1', ':U6100-Fhn6OoE-001', 'Local', 'Server'] scopy = server_msg.copy() - self._Irc.Settings.MAIN_SERVER_HOSTNAME = scopy[1] + self._ctx.Settings.MAIN_SERVER_HOSTNAME = scopy[1] except Exception as err: - self._Logs.error(f'General Error: {err}') + self._ctx.Logs.error(f'General Error: {err}') async def on_version(self, server_msg: list[str]) -> None: """Sending Server Version to the server @@ -1295,19 +1295,19 @@ class Unrealircd6(IProtocol): # Réponse a un CTCP VERSION try: scopy = server_msg.copy() - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(scopy[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(scopy[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = scopy[4].replace(':', '') if nickname is None: return None if arg == '\x01VERSION\x01': - await self.send2socket(f':{dnickname} NOTICE {nickname} :\x01VERSION Service {self._Config.SERVICE_NICKNAME} V{self._Config.CURRENT_VERSION}\x01') + await self.send2socket(f':{dnickname} NOTICE {nickname} :\x01VERSION Service {self._ctx.Config.SERVICE_NICKNAME} V{self._ctx.Config.CURRENT_VERSION}\x01') return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_time(self, server_msg: list[str]) -> None: """Sending TIME answer to a requestor @@ -1319,10 +1319,10 @@ class Unrealircd6(IProtocol): # Réponse a un CTCP VERSION try: scopy = server_msg.copy() - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(scopy[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(scopy[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = scopy[4].replace(':', '') - current_datetime = self._Utils.get_sdatetime() + current_datetime = self._ctx.Utils.get_sdatetime() if nickname is None: return None @@ -1332,7 +1332,7 @@ class Unrealircd6(IProtocol): return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_ping(self, server_msg: list[str]) -> None: """Sending a PING answer to requestor @@ -1344,30 +1344,30 @@ class Unrealircd6(IProtocol): # Réponse a un CTCP VERSION try: scopy = server_msg.copy() - nickname = self._Irc.User.get_nickname(self._Utils.clean_uid(scopy[1])) - dnickname = self._Config.SERVICE_NICKNAME + nickname = self._ctx.User.get_nickname(self._ctx.Utils.clean_uid(scopy[1])) + dnickname = self._ctx.Config.SERVICE_NICKNAME arg = scopy[4].replace(':', '') if nickname is None: - self._Logs.debug(scopy) + self._ctx.Logs.debug(scopy) return None if arg == '\x01PING': recieved_unixtime = int(scopy[5].replace('\x01','')) - current_unixtime = self._Utils.get_unixtime() + current_unixtime = self._ctx.Utils.get_unixtime() ping_response = current_unixtime - recieved_unixtime - # self._Irc.send2socket(f':{dnickname} NOTICE {nickname} :\x01PING {ping_response} secs\x01') + # self._ctx.Irc.send2socket(f':{dnickname} NOTICE {nickname} :\x01PING {ping_response} secs\x01') await self.send_notice( nick_from=dnickname, nick_to=nickname, msg=f"\x01PING {ping_response} secs\x01" ) - self._Logs.debug(scopy) + self._ctx.Logs.debug(scopy) return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_version_msg(self, server_msg: list[str]) -> None: """Handle version coming from the server @@ -1381,25 +1381,25 @@ class Unrealircd6(IProtocol): if '@' in list(scopy[0])[0]: scopy.pop(0) - u = self._Irc.User.get_user(self._Utils.clean_uid(scopy[0])) + u = self._ctx.User.get_user(self._ctx.Utils.clean_uid(scopy[0])) if u is None: return None - response_351 = f"{self._Config.SERVICE_NAME.capitalize()}-{self._Config.CURRENT_VERSION} {self._Config.SERVICE_HOST} {self.name}" - await self.send2socket(f':{self._Config.SERVICE_HOST} 351 {u.nickname} {response_351}') + response_351 = f"{self._ctx.Config.SERVICE_NAME.capitalize()}-{self._ctx.Config.CURRENT_VERSION} {self._ctx.Config.SERVICE_HOST} {self.name}" + await self.send2socket(f':{self._ctx.Config.SERVICE_HOST} 351 {u.nickname} {response_351}') - modules = self._Irc.ModuleUtils.get_all_available_modules() + modules = self._ctx.ModuleUtils.get_all_available_modules() response_005 = ' | '.join(modules) - await self.send2socket(f':{self._Config.SERVICE_HOST} 005 {u.nickname} {response_005} are supported by this server') + await self.send2socket(f':{self._ctx.Config.SERVICE_HOST} 005 {u.nickname} {response_005} are supported by this server') - response_005 = ''.join(self._Settings.PROTOCTL_USER_MODES) - await self.send2socket(f":{self._Config.SERVICE_HOST} 005 {u.nickname} {response_005} are supported by this server") + response_005 = ''.join(self._ctx.Settings.PROTOCTL_USER_MODES) + await self.send2socket(f":{self._ctx.Config.SERVICE_HOST} 005 {u.nickname} {response_005} are supported by this server") return None except Exception as err: - self._Logs.error(f"{__name__} - General Error: {err}") + self._ctx.Logs.error(f"{__name__} - General Error: {err}") async def on_smod(self, server_msg: list[str]) -> None: """Handle SMOD message coming from the server @@ -1414,11 +1414,11 @@ class Unrealircd6(IProtocol): for smod in modules: smod_split = smod.split(':') - smodobj = self._Irc.Loader.Definition.MSModule(type=smod_split[0], name=smod_split[1], version=smod_split[2]) - self._Settings.SMOD_MODULES.append(smodobj) + smodobj = self._ctx.Definition.MSModule(type=smod_split[0], name=smod_split[1], version=smod_split[2]) + self._ctx.Settings.SMOD_MODULES.append(smodobj) except Exception as err: - self._Logs.error(f'General Error: {err}') + self._ctx.Logs.error(f'General Error: {err}') async def on_sasl(self, server_msg: list[str]) -> Optional['MSasl']: """Handle SASL coming from a server @@ -1433,9 +1433,9 @@ class Unrealircd6(IProtocol): # [':irc.local.org', 'SASL', 'defender-dev.deb.biz.st', '00157Z26U', 'C', 'sasakey=='] # [':irc.local.org', 'SASL', 'defender-dev.deb.biz.st', '00157Z26U', 'D', 'A'] scopy = server_msg.copy() - psasl = self._Irc.Sasl + psasl = self._ctx.Sasl sasl_enabled = False - for smod in self._Settings.SMOD_MODULES: + for smod in self._ctx.Settings.SMOD_MODULES: if smod.name == 'sasl': sasl_enabled = True break @@ -1445,7 +1445,7 @@ class Unrealircd6(IProtocol): client_uid = scopy[3] if len(scopy) >= 6 else None sasl_message_type = scopy[4] if len(scopy) >= 6 else None - psasl.insert_sasl_client(self._Irc.Loader.Definition.MSasl(client_uid=client_uid)) + psasl.insert_sasl_client(self._ctx.Definition.MSasl(client_uid=client_uid)) sasl_obj = psasl.get_sasl_obj(client_uid) if sasl_obj is None: @@ -1463,13 +1463,13 @@ class Unrealircd6(IProtocol): sasl_obj.mechanisme = str(scopy[5]) if sasl_obj.mechanisme == "PLAIN": - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {sasl_obj.client_uid} C +") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {sasl_obj.client_uid} C +") elif sasl_obj.mechanisme == "EXTERNAL": if str(scopy[5]) == "+": return None sasl_obj.fingerprint = str(scopy[6]) - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {sasl_obj.client_uid} C +") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {sasl_obj.client_uid} C +") self.on_sasl_authentication_process(sasl_obj) return sasl_obj @@ -1493,20 +1493,20 @@ class Unrealircd6(IProtocol): return sasl_obj except Exception as err: - self._Logs.error(f'General Error: {err}', exc_info=True) + self._ctx.Logs.error(f'General Error: {err}', exc_info=True) async def on_sasl_authentication_process(self, sasl_model: 'MSasl') -> None: s = sasl_model if sasl_model: - def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: + async def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: if fingerprint: mes_donnees = {'fingerprint': fingerprint} - query = f"SELECT user, level, language FROM {self._Config.TABLE_ADMIN} WHERE fingerprint = :fingerprint" + query = f"SELECT user, level, language FROM {self._ctx.Config.TABLE_ADMIN} WHERE fingerprint = :fingerprint" else: - mes_donnees = {'user': username, 'password': self._Utils.hash_password(password)} - query = f"SELECT user, level, language FROM {self._Config.TABLE_ADMIN} WHERE user = :user AND password = :password" + mes_donnees = {'user': username, 'password': self._ctx.Utils.hash_password(password)} + query = f"SELECT user, level, language FROM {self._ctx.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" - result = self._Base.db_execute_query(query, mes_donnees) + result = await self._ctx.Base.db_execute_query(query, mes_donnees) user_from_db = result.fetchone() if user_from_db: return {'user': user_from_db[0], 'level': user_from_db[1], 'language': user_from_db[2]} @@ -1515,32 +1515,32 @@ class Unrealircd6(IProtocol): if s.message_type == 'C' and s.mechanisme == 'PLAIN': # Connection via PLAIN - admin_info = db_get_admin_info(username=s.username, password=s.password) + admin_info = await db_get_admin_info(username=s.username, password=s.password) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.language = admin_info.get('language', 'EN') - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") - await self.send2socket(f":{self._Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") else: - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") - await self.send2socket(f":{self._Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") elif s.message_type == 'S' and s.mechanisme == 'EXTERNAL': # Connection using fingerprints - admin_info = db_get_admin_info(fingerprint=s.fingerprint) + admin_info = await db_get_admin_info(fingerprint=s.fingerprint) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.username = admin_info.get('user', None) s.language = admin_info.get('language', 'EN') - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") - await self.send2socket(f":{self._Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") else: # "904 :SASL authentication failed" - await self.send2socket(f":{self._Config.SERVEUR_LINK} SASL {self._Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") - await self.send2socket(f":{self._Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} SASL {self._ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") + await self.send2socket(f":{self._ctx.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") async def on_md(self, server_msg: list[str]) -> None: """Handle MD responses @@ -1556,7 +1556,7 @@ class Unrealircd6(IProtocol): var = str(scopy[4]).lower() value = str(scopy[5]).replace(':', '') - user_obj = self._Irc.User.get_user(uid) + user_obj = self._ctx.User.get_user(uid) if user_obj is None: return None @@ -1569,7 +1569,7 @@ class Unrealircd6(IProtocol): return None except Exception as e: - self._Logs.error(f"General Error: {e}") + self._ctx.Logs.error(f"General Error: {e}") async def on_kick(self, server_msg: list[str]) -> None: """When a user is kicked out from a channel @@ -1583,7 +1583,7 @@ class Unrealircd6(IProtocol): channel = scopy[3] # Delete the user from the channel. - self._Irc.Channel.delete_user_from_channel(channel, uid) + self._ctx.Channel.delete_user_from_channel(channel, uid) return None async def on_sethost(self, server_msg: list[str]) -> None: @@ -1594,7 +1594,7 @@ class Unrealircd6(IProtocol): server_msg (list[str]): _description_ """ scopy = server_msg.copy() - uid = self._User.clean_uid(scopy[0]) + uid = self._ctx.User.clean_uid(scopy[0]) vhost = scopy[2].lstrip(':') - user = self._User.get_user(uid) + user = self._ctx.User.get_user(uid) user.vhost = vhost diff --git a/core/definition.py b/core/definition.py index 72f9062..6d9ef95 100644 --- a/core/definition.py +++ b/core/definition.py @@ -3,6 +3,7 @@ from json import dumps from dataclasses import dataclass, field, asdict, fields, replace from typing import Literal, Any, Optional from os import sep +from core.classes.interfaces.imodule import IModule @dataclass class MainModel: @@ -354,7 +355,7 @@ class MCommand(MainModel): class MModule(MainModel): module_name: str = None class_name: str = None - class_instance: Optional[Any] = None + class_instance: Optional[IModule] = None @dataclass class DefenderModuleHeader(MainModel): diff --git a/core/irc.py b/core/irc.py index 5469a2b..ff19528 100644 --- a/core/irc.py +++ b/core/irc.py @@ -1,7 +1,5 @@ import asyncio -import sys import socket -import ssl import re import time from ssl import SSLSocket @@ -29,61 +27,25 @@ class Irc: self.signal: bool = True - # Loader class - self.Loader = loader - - # Load the configuration - self.Config = self.Loader.Config - - # Load Main utils functions - self.Utils = self.Loader.Utils + # Load Context class (Loader) + self.ctx = loader # Date et heure de la premiere connexion de Defender - self.defender_connexion_datetime = self.Config.DEFENDER_CONNEXION_DATETIME + self.defender_connexion_datetime = self.ctx.Config.DEFENDER_CONNEXION_DATETIME # Lancer toutes les 30 secondes des actions de nettoyages - self.beat = self.Config.DEFENDER_HEARTBEAT_FREQUENCY + self.beat = self.ctx.Config.DEFENDER_HEARTBEAT_FREQUENCY # Heartbeat active - self.hb_active = self.Config.DEFENDER_HEARTBEAT + self.hb_active = self.ctx.Config.DEFENDER_HEARTBEAT # ID du serveur qui accueil le service ( Host Serveur Id ) - self.HSID = self.Config.HSID + self.HSID = self.ctx.Config.HSID # Charset utiliser pour décoder/encoder les messages - self.CHARSET = self.Config.SERVEUR_CHARSET + self.CHARSET = self.ctx.Config.SERVEUR_CHARSET """0: utf-8 | 1: iso-8859-1""" - # Use Base Instance - self.Base = self.Loader.Base - - # Logger - self.Logs = self.Loader.Logs - - # Get Settings. - self.Settings = self.Base.Settings - - # Use User Instance - self.User = self.Loader.User - - # Use Admin Instance - self.Admin = self.Loader.Admin - - # Use Client Instance - self.Client = self.Loader.Client - - # Use Channel Instance - self.Channel = self.Loader.Channel - - # Use Reputation Instance - self.Reputation = self.Loader.Reputation - - # Use Module Utils - self.ModuleUtils = self.Loader.ModuleUtils - - # Use Main Sasl module - self.Sasl = self.Loader.Sasl - self.autolimit_started: bool = False """This variable is to make sure the thread is not running""" @@ -94,7 +56,7 @@ class Irc: self.first_connexion_ip: str = None # Load Commands Utils - self.Commands = self.Loader.Commands + # self.Commands = self.Loader.Commands """Command utils""" self.build_command(0, 'core', 'help', 'This provide the help') @@ -102,8 +64,8 @@ class Irc: self.build_command(0, 'core', 'copyright', 'Give some information about the IRC Service') self.build_command(0, 'core', 'uptime', 'Give you since when the service is connected') self.build_command(0, 'core', 'firstauth', 'First authentication of the Service') - self.build_command(0, 'core', 'register', f'Register your nickname /msg {self.Config.SERVICE_NICKNAME} REGISTER ') - self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.Config.SERVICE_NICKNAME} IDENTIFY ') + self.build_command(0, 'core', 'register', f'Register your nickname /msg {self.ctx.Config.SERVICE_NICKNAME} REGISTER ') + self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.ctx.Config.SERVICE_NICKNAME} IDENTIFY ') self.build_command(0, 'core', 'logout', 'Reverse the effect of the identify command') self.build_command(1, 'core', 'load', 'Load an existing module') self.build_command(1, 'core', 'unload', 'Unload a module') @@ -113,6 +75,7 @@ class Irc: self.build_command(2, 'core', 'show_modules', 'Display a list of loaded modules') self.build_command(2, 'core', 'show_timers', 'Display active timers') self.build_command(2, 'core', 'show_threads', 'Display active threads in the system') + self.build_command(2, 'core', 'show_asyncio', 'Display active asyncio') self.build_command(2, 'core', 'show_channels', 'Display a list of active channels') self.build_command(2, 'core', 'show_users', 'Display a list of connected users') self.build_command(2, 'core', 'show_clients', 'Display a list of connected clients') @@ -138,23 +101,21 @@ class Irc: self.reader: Optional[asyncio.StreamReader] = None self.writer: Optional[asyncio.StreamWriter] = None - self.Base.create_thread(func=self.heartbeat, func_args=(self.beat, )) + self.ctx.Base.create_asynctask(self.heartbeat(self.beat)) async def connect(self): - if self.Config.SERVEUR_SSL: - self.reader, self.writer = await asyncio.open_connection(self.Config.SERVEUR_IP, self.Config.SERVEUR_PORT, ssl=self.Utils.get_ssl_context()) + if self.ctx.Config.SERVEUR_SSL: + self.reader, self.writer = await asyncio.open_connection(self.ctx.Config.SERVEUR_IP, self.ctx.Config.SERVEUR_PORT, ssl=self.ctx.Utils.get_ssl_context()) else: - self.reader, self.writer = await asyncio.open_connection(self.Config.SERVEUR_IP, self.Config.SERVEUR_PORT) + self.reader, self.writer = await asyncio.open_connection(self.ctx.Config.SERVEUR_IP, self.ctx.Config.SERVEUR_PORT) self.init_service_user() - self.Protocol: 'IProtocol' = self.Loader.PFactory.get() + self.Protocol: 'IProtocol' = self.ctx.PFactory.get() self.Protocol.register_command() await self.Protocol.send_link() - async def listen(self): - while self.signal: data = await self.reader.readuntil(b'\r\n') await self.send_response(data.splitlines()) @@ -166,104 +127,22 @@ class Irc: ############################################## # CONNEXION IRC # ############################################## - def init_irc(self) -> None: - """Create a socket and connect to irc server - - Args: - ircInstance (Irc): Instance of Irc object. - """ - try: - self.init_service_user() - self.Utils.create_socket(self) - self.__connect_to_irc() - - except AssertionError as ae: - self.Logs.critical(f'Assertion error: {ae}') def init_service_user(self) -> None: - self.User.insert(self.Loader.Definition.MUser( - uid=self.Config.SERVICE_ID, - nickname=self.Config.SERVICE_NICKNAME, - username=self.Config.SERVICE_USERNAME, - realname=self.Config.SERVICE_REALNAME, - hostname=self.Config.SERVICE_HOST, - umodes=self.Config.SERVICE_SMODES + self.ctx.User.insert(self.ctx.Definition.MUser( + uid=self.ctx.Config.SERVICE_ID, + nickname=self.ctx.Config.SERVICE_NICKNAME, + username=self.ctx.Config.SERVICE_USERNAME, + realname=self.ctx.Config.SERVICE_REALNAME, + hostname=self.ctx.Config.SERVICE_HOST, + umodes=self.ctx.Config.SERVICE_SMODES )) return None - def __connect_to_irc(self) -> None: - try: - self.init_service_user() - self.Protocol: 'IProtocol' = self.Loader.PFactory.get() - self.Protocol.register_command() - self.Protocol.send_link() # Etablir le link en fonction du protocol choisi - self.signal = True # Une variable pour initier la boucle infinie - # self.join_saved_channels() # Join existing channels - # self.ModuleUtils.db_load_all_existing_modules(self) - - while self.signal: - try: - if self.Config.DEFENDER_RESTART == 1: - rehash.restart_service(self) - - # 4072 max what the socket can grab - buffer_size = self.IrcSocket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) - data_in_bytes = self.IrcSocket.recv(buffer_size) - eol = True - if data_in_bytes[-2:] != b"\r\n": - eol = False - - while not eol: - new_data = self.IrcSocket.recv(buffer_size) - data_in_bytes += new_data - if data_in_bytes[-2:] == eol: - eol = False - - # while count_bytes > 4070: - # # If the received message is > 4070 then loop and add the value to the variable - # new_data = self.IrcSocket.recv(buffer_size) - # data_in_bytes += new_data - # count_bytes = len(new_data) - - data = data_in_bytes.splitlines(True) - - if not data: - break - - self.send_response(data) - - except ssl.SSLEOFError as soe: - self.Logs.error(f"SSLEOFError __connect_to_irc: {soe} - {data}") - except ssl.SSLError as se: - self.Logs.error(f"SSLError __connect_to_irc: {se} - {data}") - sys.exit(-1) - except OSError as oe: - self.Logs.error(f"SSLError __connect_to_irc: {oe} {oe.errno}") - if oe.errno == 10053: - sys.exit(-1) - except (socket.error, ConnectionResetError): - self.Logs.debug("Connexion reset") - - self.IrcSocket.shutdown(socket.SHUT_RDWR) - self.IrcSocket.close() - self.Logs.info("-- Fermeture de Defender ...") - sys.exit(0) - - except AssertionError as ae: - self.Logs.error(f'AssertionError: {ae}') - except ValueError as ve: - self.Logs.error(f'ValueError: {ve}') - except ssl.SSLEOFError as soe: - self.Logs.error(f"SSLEOFError: {soe}") - except AttributeError as atte: - self.Logs.critical(f"AttributeError: {atte}", exc_info=True) - except Exception as e: - self.Logs.critical(f"General Error: {e}", exc_info=True) - async def join_saved_channels(self) -> None: """## Joining saved channels""" - exec_query = self.Base.db_execute_query(f'SELECT distinct channel_name FROM {self.Config.TABLE_CHANNEL}') + exec_query = await self.ctx.Base.db_execute_query(f'SELECT distinct channel_name FROM {self.ctx.Config.TABLE_CHANNEL}') result_query = exec_query.fetchall() if result_query: @@ -281,18 +160,18 @@ class Irc: for data in responses: response = data.decode(self.CHARSET[1],'replace').split() await self.cmd(response) - self.Logs.error(f'UnicodeEncodeError: {ue}') - self.Logs.error(response) + self.ctx.Logs.error(f'UnicodeEncodeError: {ue}') + self.ctx.Logs.error(response) except UnicodeDecodeError as ud: for data in responses: response = data.decode(self.CHARSET[1],'replace').split() await self.cmd(response) - self.Logs.error(f'UnicodeDecodeError: {ud}') - self.Logs.error(response) + self.ctx.Logs.error(f'UnicodeDecodeError: {ud}') + self.ctx.Logs.error(response) except AssertionError as ae: - self.Logs.error(f"Assertion error : {ae}") + self.ctx.Logs.error(f"Assertion error : {ae}") def unload(self) -> None: # This is only to reference the method @@ -312,7 +191,7 @@ class Irc: command_description (str): The description of the command """ # Build Model. - self.Commands.build(self.Loader.Definition.MCommand(module_name, command_name, command_description, level)) + self.ctx.Commands.build(self.ctx.Definition.MCommand(module_name, command_name, command_description, level)) return None @@ -320,10 +199,10 @@ class Irc: # Check if the nickname is an admin p = self.Protocol - admin_obj = self.Admin.get_admin(nickname) - dnickname = self.Config.SERVICE_NICKNAME - color_nogc = self.Config.COLORS.nogc - color_black = self.Config.COLORS.black + admin_obj = self.ctx.Admin.get_admin(nickname) + dnickname = self.ctx.Config.SERVICE_NICKNAME + color_nogc = self.ctx.Config.COLORS.nogc + color_black = self.ctx.Config.COLORS.black current_level = 0 if admin_obj is not None: @@ -334,7 +213,7 @@ class Irc: line = "-"*75 await p.send_notice(nick_from=dnickname,nick_to=nickname, msg=header) await p.send_notice(nick_from=dnickname,nick_to=nickname, msg=f" {line}") - for cmd in self.Commands.get_commands_by_level(current_level): + for cmd in self.ctx.Commands.get_commands_by_level(current_level): if module is None or cmd.module_name.lower() == module.lower(): await p.send_notice( nick_from=dnickname, @@ -344,18 +223,18 @@ class Irc: return None - def on_sasl_authentication_process(self, sasl_model: 'MSasl') -> bool: + async def on_sasl_authentication_process(self, sasl_model: 'MSasl') -> bool: s = sasl_model if sasl_model: - def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: + async def db_get_admin_info(*, username: Optional[str] = None, password: Optional[str] = None, fingerprint: Optional[str] = None) -> Optional[dict[str, Any]]: if fingerprint: mes_donnees = {'fingerprint': fingerprint} - query = f"SELECT user, level, language FROM {self.Config.TABLE_ADMIN} WHERE fingerprint = :fingerprint" + query = f"SELECT user, level, language FROM {self.ctx.Config.TABLE_ADMIN} WHERE fingerprint = :fingerprint" else: - mes_donnees = {'user': username, 'password': self.Utils.hash_password(password)} - query = f"SELECT user, level, language FROM {self.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" + mes_donnees = {'user': username, 'password': self.ctx.Utils.hash_password(password)} + query = f"SELECT user, level, language FROM {self.ctx.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" - result = self.Base.db_execute_query(query, mes_donnees) + result = await self.ctx.Base.db_execute_query(query, mes_donnees) user_from_db = result.fetchone() if user_from_db: return {'user': user_from_db[0], 'level': user_from_db[1], 'language': user_from_db[2]} @@ -364,32 +243,32 @@ class Irc: if s.message_type == 'C' and s.mechanisme == 'PLAIN': # Connection via PLAIN - admin_info = db_get_admin_info(username=s.username, password=s.password) + admin_info = await db_get_admin_info(username=s.username, password=s.password) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.language = admin_info.get('language', 'EN') - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} SASL {self.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} SASL {self.ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") else: - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} SASL {self.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} SASL {self.ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") elif s.message_type == 'S' and s.mechanisme == 'EXTERNAL': # Connection using fingerprints - admin_info = db_get_admin_info(fingerprint=s.fingerprint) + admin_info = await db_get_admin_info(fingerprint=s.fingerprint) if admin_info is not None: s.auth_success = True s.level = admin_info.get('level', 0) s.username = admin_info.get('user', None) s.language = admin_info.get('language', 'EN') - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} SASL {self.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} SASL {self.ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D S") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} 903 {s.username} :SASL authentication successful") else: # "904 :SASL authentication failed" - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} SASL {self.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") - self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} SASL {self.ctx.Settings.MAIN_SERVER_HOSTNAME} {s.client_uid} D F") + await self.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_LINK} 904 {s.username} :SASL authentication failed") def get_defender_uptime(self) -> str: """Savoir depuis quand Defender est connecté @@ -403,7 +282,7 @@ class Irc: return uptime - def heartbeat(self, beat: float) -> None: + async def heartbeat(self, beat: float) -> None: """Execute certaines commandes de nettoyage toutes les x secondes x étant définit a l'initialisation de cette class (self.beat) @@ -411,17 +290,17 @@ class Irc: beat (float): Nombre de secondes entre chaque exécution """ while self.hb_active: - time.sleep(beat) - self.Base.execute_periodic_action() + await asyncio.sleep(beat) + self.ctx.Base.execute_periodic_action() def insert_db_admin(self, uid: str, account: str, level: int, language: str) -> None: - user_obj = self.User.get_user(uid) + user_obj = self.ctx.User.get_user(uid) if user_obj is None: return None - self.Admin.insert( - self.Loader.Definition.MAdmin( + self.ctx.Admin.insert( + self.ctx.Definition.MAdmin( **user_obj.to_dict(), language=language, account=account, @@ -433,15 +312,15 @@ class Irc: def delete_db_admin(self, uid:str) -> None: - if self.Admin.get_admin(uid) is None: + if self.ctx.Admin.get_admin(uid) is None: return None - if not self.Admin.delete(uid): - self.Logs.critical(f'UID: {uid} was not deleted') + if not self.ctx.Admin.delete(uid): + self.ctx.Logs.critical(f'UID: {uid} was not deleted') return None - def create_defender_user(self, sender: str, new_admin: str, new_level: int, new_password: str) -> bool: + async def create_defender_user(self, sender: str, new_admin: str, new_level: int, new_password: str) -> bool: """Create a new admin user for defender Args: @@ -455,50 +334,50 @@ class Irc: """ # > addaccess [nickname] [level] [password] - dnick = self.Config.SERVICE_NICKNAME + dnick = self.ctx.Config.SERVICE_NICKNAME p = self.Protocol - get_user = self.User.get_user(new_admin) - level = self.Base.convert_to_int(new_level) + get_user = self.ctx.User.get_user(new_admin) + level = self.ctx.Base.convert_to_int(new_level) password = new_password if get_user is None: response = tr("The nickname (%s) is not currently connected! please create a new admin when the nickname is connected to the network!", new_admin) - p.send_notice(dnick, sender, response) - self.Logs.debug(f"New admin {new_admin} sent by {sender} is not connected") + await p.send_notice(dnick, sender, response) + self.ctx.Logs.debug(f"New admin {new_admin} sent by {sender} is not connected") return False if level is None or level > 4 or level == 0: - p.send_notice(dnick, sender, tr("The level (%s) must be a number from 1 to 4", level)) - self.Logs.debug(f"Level must a number between 1 to 4 (sent by {sender})") + await p.send_notice(dnick, sender, tr("The level (%s) must be a number from 1 to 4", level)) + self.ctx.Logs.debug(f"Level must a number between 1 to 4 (sent by {sender})") return False nickname = get_user.nickname hostname = get_user.hostname vhost = get_user.vhost - spassword = self.Loader.Utils.hash_password(password) + spassword = self.ctx.Utils.hash_password(password) # Check if the user already exist - if not self.Admin.db_is_admin_exist(nickname): - mes_donnees = {'datetime': self.Utils.get_sdatetime(), 'user': nickname, 'password': spassword, 'hostname': hostname, 'vhost': vhost, 'level': level, 'language': self.Config.LANG} - self.Base.db_execute_query(f'''INSERT INTO {self.Config.TABLE_ADMIN} + if not self.ctx.Admin.db_is_admin_exist(nickname): + mes_donnees = {'datetime': self.ctx.Utils.get_sdatetime(), 'user': nickname, 'password': spassword, 'hostname': hostname, 'vhost': vhost, 'level': level, 'language': self.ctx.Config.LANG} + await self.ctx.Base.db_execute_query(f'''INSERT INTO {self.ctx.Config.TABLE_ADMIN} (createdOn, user, password, hostname, vhost, level, language) VALUES (:datetime, :user, :password, :hostname, :vhost, :level, :language) ''', mes_donnees) - p.send_notice(dnick, sender, tr("New admin (%s) has been added with level %s", nickname, level)) - self.Logs.info(f"A new admin ({nickname}) has been created by {sender}!") + await p.send_notice(dnick, sender, tr("New admin (%s) has been added with level %s", nickname, level)) + self.ctx.Logs.info(f"A new admin ({nickname}) has been created by {sender}!") return True else: - p.send_notice(dnick, sender, tr("The nickname (%s) Already exist!", nickname)) - self.Logs.info(f"The nickname {nickname} already exist! (sent by {sender})") + await p.send_notice(dnick, sender, tr("The nickname (%s) Already exist!", nickname)) + self.ctx.Logs.info(f"The nickname {nickname} already exist! (sent by {sender})") return False async def thread_check_for_new_version(self, fromuser: str) -> None: - dnickname = self.Config.SERVICE_NICKNAME + dnickname = self.ctx.Config.SERVICE_NICKNAME - if self.Base.check_for_new_version(True): - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" New Version available : {self.Config.CURRENT_VERSION} >>> {self.Config.LATEST_VERSION}") + if self.ctx.Base.check_for_new_version(True): + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" New Version available : {self.ctx.Config.CURRENT_VERSION} >>> {self.ctx.Config.LATEST_VERSION}") await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" Please run (git pull origin main) in the current folder") else: await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" You have the latest version of defender") @@ -514,29 +393,29 @@ class Irc: try: original_response: list[str] = data.copy() if len(original_response) < 2: - self.Logs.warning(f'Size ({str(len(original_response))}) - {original_response}') + self.ctx.Logs.warning(f'Size ({str(len(original_response))}) - {original_response}') return None - self.Logs.debug(f">> {self.Utils.hide_sensitive_data(original_response)}") + self.ctx.Logs.debug(f">> {self.ctx.Utils.hide_sensitive_data(original_response)}") pos, parsed_protocol = self.Protocol.get_ircd_protocol_poisition(cmd=original_response, log=True) - modules = self.ModuleUtils.model_get_loaded_modules().copy() + modules = self.ctx.ModuleUtils.model_get_loaded_modules().copy() for parsed in self.Protocol.Handler.get_ircd_commands(): if parsed.command_name.upper() == parsed_protocol: await parsed.func(original_response) for module in modules: - module.class_instance.cmd(original_response) + await module.class_instance.cmd(original_response) if self.ctx.Utils.is_coroutinefunction(module.class_instance.cmd) else module.class_instance.cmd(original_response) # if len(original_response) > 2: # if original_response[2] != 'UID': # # Envoyer la commande aux classes dynamiquement chargées - # for module in self.ModuleUtils.model_get_loaded_modules().copy(): + # for module in self.ctx.ModuleUtils.model_get_loaded_modules().copy(): # module.class_instance.cmd(original_response) except IndexError as ie: - self.Logs.error(f"IndexError: {ie}") + self.ctx.Logs.error(f"IndexError: {ie}") except Exception as err: - self.Logs.error(f"General Error: {err}", exc_info=True) + self.ctx.Logs.error(f"General Error: {err}", exc_info=True) async def hcmds(self, user: str, channel: Union[str, None], cmd: list, fullcmd: list = []) -> None: """Create @@ -550,38 +429,38 @@ class Irc: Returns: None: Nothing to return """ - u = self.User.get_user(user) + u = self.ctx.User.get_user(user) """The User Object""" if u is None: return None - c = self.Client.get_Client(u.uid) + c = self.ctx.Client.get_Client(u.uid) """The Client Object""" fromuser = u.nickname uid = u.uid - self.Settings.current_admin = self.Admin.get_admin(user) # set Current admin if any. + self.ctx.Settings.current_admin = self.ctx.Admin.get_admin(user) # set Current admin if any. - RED = self.Config.COLORS.red - GREEN = self.Config.COLORS.green - BLACK = self.Config.COLORS.black - NOGC = self.Config.COLORS.nogc + RED = self.ctx.Config.COLORS.red + GREEN = self.ctx.Config.COLORS.green + BLACK = self.ctx.Config.COLORS.black + NOGC = self.ctx.Config.COLORS.nogc # Defender information - dnickname = self.Config.SERVICE_NICKNAME # Defender nickname - dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log + dnickname = self.ctx.Config.SERVICE_NICKNAME # Defender nickname + dchanlog = self.ctx.Config.SERVICE_CHANLOG # Defender chan log if len(cmd) > 0: command = str(cmd[0]).lower() else: return False - if not self.Commands.is_client_allowed_to_run_command(fromuser, command): + if not self.ctx.Commands.is_client_allowed_to_run_command(fromuser, command): command = 'notallowed' # Envoyer la commande aux classes dynamiquement chargées if command != 'notallowed': - for module in self.ModuleUtils.DB_MODULES: + for module in self.ctx.ModuleUtils.DB_MODULES: await module.class_instance.hcmds(user, channel, cmd, fullcmd) match command: @@ -602,7 +481,7 @@ class Irc: ) except IndexError as ie: - self.Logs.error(f'{ie}') + self.ctx.Logs.error(f'{ie}') case 'deauth': @@ -610,13 +489,13 @@ class Irc: uid_to_deauth = uid self.delete_db_admin(uid_to_deauth) - self.Protocol.send_priv_msg( + await self.Protocol.send_priv_msg( msg=tr("[ %s%s%s ] - %s has been disconnected from %s", RED, current_command, NOGC, fromuser, dnickname), nick_from=dnickname, channel=dchanlog ) - self.Protocol.send_notice(dnickname, fromuser, tr("You have been successfully disconnected from %s", dnickname)) + await self.Protocol.send_notice(dnickname, fromuser, tr("You have been successfully disconnected from %s", dnickname)) return None case 'firstauth': @@ -627,22 +506,22 @@ class Irc: current_command = str(cmd[0]) if current_nickname is None: - self.Logs.critical(f"This nickname [{fromuser}] don't exist") + self.ctx.Logs.critical(f"This nickname [{fromuser}] don't exist") return None if len(cmd) < 3: - self.Protocol.send_notice(dnickname,fromuser, tr("Syntax. /msg %s %s [OWNER_NICKNAME] [OWNER_PASSWORD]", self.Config.SERVICE_NICKNAME, current_command)) + await self.Protocol.send_notice(dnickname,fromuser, tr("Syntax. /msg %s %s [OWNER_NICKNAME] [OWNER_PASSWORD]", self.ctx.Config.SERVICE_NICKNAME, current_command)) return None - query = f"SELECT count(id) as c FROM {self.Config.TABLE_ADMIN}" - result = self.Base.db_execute_query(query) + query = f"SELECT count(id) as c FROM {self.ctx.Config.TABLE_ADMIN}" + result = await self.ctx.Base.db_execute_query(query) result_db = result.fetchone() if result_db[0] > 0: - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=tr("You can't use this command anymore ! Please use [%sauth] instead", self.Config.SERVICE_PREFIX) + msg=tr("You can't use this command anymore ! Please use [%sauth] instead", self.ctx.Config.SERVICE_PREFIX) ) return None @@ -651,12 +530,12 @@ class Irc: cmd_password = str(cmd[2]) # Credentials coming from the Configuration - config_owner = self.Config.OWNER - config_password = self.Config.PASSWORD + config_owner = self.ctx.Config.OWNER + config_password = self.ctx.Config.PASSWORD if cmd_owner != config_owner: - self.Logs.critical(f"The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !") - self.Protocol.send_notice( + self.ctx.Logs.critical(f"The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !") + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=tr("The nickname sent [%s] is different than the one set in the configuration file !", cmd_owner) @@ -664,52 +543,52 @@ class Irc: return None if cmd_owner == config_owner and cmd_password == config_password: - self.Base.db_create_first_admin() - self.insert_db_admin(current_uid, cmd_owner, 5, self.Config.LANG) - self.Protocol.send_priv_msg( + await self.ctx.Base.db_create_first_admin() + self.insert_db_admin(current_uid, cmd_owner, 5, self.ctx.Config.LANG) + await self.Protocol.send_priv_msg( msg=tr("[%s %s %s] - %s is now connected to %s", GREEN, current_command.upper(), NOGC, fromuser, dnickname), nick_from=dnickname, channel=dchanlog ) - self.Protocol.send_notice(dnickname, fromuser, tr("Successfuly connected to %s", dnickname)) + await self.Protocol.send_notice(dnickname, fromuser, tr("Successfuly connected to %s", dnickname)) else: - self.Protocol.send_priv_msg( + await self.Protocol.send_priv_msg( msg=tr("[ %s %s %s ] - %s provided a wrong password!", RED, current_command.upper(), NOGC, current_nickname), nick_from=dnickname, channel=dchanlog ) - self.Protocol.send_notice(dnickname, fromuser, tr("Wrong password!")) + await self.Protocol.send_notice(dnickname, fromuser, tr("Wrong password!")) case 'auth': # Syntax. !auth nickname password if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [password]") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [password]") return None user_to_log = cmd[1] password = cmd[2] current_client = u - admin_obj = self.Admin.get_admin(fromuser) + admin_obj = self.ctx.Admin.get_admin(fromuser) if current_client is None: # This case should never happen - self.Protocol.send_priv_msg(nick_from=dnickname, + await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {RED}{str(command).upper()} FAIL{NOGC} ] - Nickname {fromuser} is trying to connect to defender wrongly", channel=dchanlog) return None if admin_obj: - self.Protocol.send_priv_msg(nick_from=dnickname, + await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {GREEN}{str(command).upper()}{NOGC} ] - {fromuser} is already connected to {dnickname}", channel=dchanlog) - self.Protocol.send_notice(dnickname, fromuser, tr("You are already connected to %s", dnickname)) + await self.Protocol.send_notice(dnickname, fromuser, tr("You are already connected to %s", dnickname)) return None - mes_donnees = {'user': user_to_log, 'password': self.Loader.Utils.hash_password(password)} - query = f"SELECT id, user, level, language FROM {self.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" - result = self.Base.db_execute_query(query, mes_donnees) + mes_donnees = {'user': user_to_log, 'password': self.ctx.Utils.hash_password(password)} + query = f"SELECT id, user, level, language FROM {self.ctx.Config.TABLE_ADMIN} WHERE user = :user AND password = :password" + result = await self.ctx.Base.db_execute_query(query, mes_donnees) user_from_db = result.fetchone() if user_from_db: @@ -717,54 +596,54 @@ class Irc: level = int(user_from_db[2]) language = str(user_from_db[3]) self.insert_db_admin(current_client.uid, account, level, language) - self.Protocol.send_priv_msg(nick_from=dnickname, + await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {GREEN}{str(command).upper()} SUCCESS{NOGC} ] - {current_client.nickname} ({account}) est désormais connecté a {dnickname}", channel=dchanlog) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=tr("Successfuly connected to %s", dnickname)) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=tr("Successfuly connected to %s", dnickname)) return None else: - self.Protocol.send_priv_msg(nick_from=dnickname, + await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {RED}{str(command).upper()} FAIL{NOGC} ] - {current_client.nickname} a tapé un mauvais mot de pass", channel=dchanlog) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=tr("Wrong password!")) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=tr("Wrong password!")) return None case 'addaccess': try: # .addaccess adator 5 password if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Right command : /msg {dnickname} addaccess [nickname] [level] [password]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"level: from 1 to 4") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Right command : /msg {dnickname} addaccess [nickname] [level] [password]") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"level: from 1 to 4") return None new_admin = str(cmd[1]) - level = self.Base.int_if_possible(cmd[2]) + level = self.ctx.Base.int_if_possible(cmd[2]) password = str(cmd[3]) self.create_defender_user(fromuser, new_admin, level, password) return None except IndexError as ie: - self.Logs.error(f'_hcmd addaccess: {ie}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} addaccess [nickname] [level] [password]") + self.ctx.Logs.error(f'_hcmd addaccess: {ie}') + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} addaccess [nickname] [level] [password]") except TypeError as te: - self.Logs.error(f'_hcmd addaccess: out of index : {te}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} addaccess [nickname] [level] [password]") + self.ctx.Logs.error(f'_hcmd addaccess: out of index : {te}') + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} addaccess [nickname] [level] [password]") case 'editaccess': # .editaccess [USER] [NEW_PASSWORD] [LEVEL] try: if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Right command : /msg {dnickname} editaccess [nickname] [NEWPASSWORD] [NEWLEVEL]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"level: from 1 to 4") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Right command : /msg {dnickname} editaccess [nickname] [NEWPASSWORD] [NEWLEVEL]") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"level: from 1 to 4") return None user_to_edit = cmd[1] - user_password = self.Loader.Utils.hash_password(cmd[2]) + user_password = self.ctx.Utils.hash_password(cmd[2]) - get_admin = self.Admin.get_admin(fromuser) + get_admin = self.ctx.Admin.get_admin(fromuser) if get_admin is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {fromuser} has no Admin access") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {fromuser} has no Admin access") return None current_user = fromuser @@ -777,40 +656,40 @@ class Irc: user_new_level = get_admin.level if user_new_level > 5: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Maximum authorized level is 5") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Maximum authorized level is 5") return None # Rechercher le user dans la base de données. mes_donnees = {'user': user_to_edit} - query = f"SELECT user, level FROM {self.Config.TABLE_ADMIN} WHERE user = :user" - result = self.Base.db_execute_query(query, mes_donnees) + query = f"SELECT user, level FROM {self.ctx.Config.TABLE_ADMIN} WHERE user = :user" + result = await self.ctx.Base.db_execute_query(query, mes_donnees) isUserExist = result.fetchone() if not isUserExist is None: if current_user_level < int(isUserExist[1]): - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You are not allowed to edit this access") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You are not allowed to edit this access") return None if current_user_level == int(isUserExist[1]) and current_user != user_to_edit: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You can't edit access of a user with same level") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You can't edit access of a user with same level") return None # Le user existe dans la base de données data_to_update = {'user': user_to_edit, 'password': user_password, 'level': user_new_level} - sql_update = f"UPDATE {self.Config.TABLE_ADMIN} SET level = :level, password = :password WHERE user = :user" - exec_query = self.Base.db_execute_query(sql_update, data_to_update) + sql_update = f"UPDATE {self.ctx.Config.TABLE_ADMIN} SET level = :level, password = :password WHERE user = :user" + exec_query = await self.ctx.Base.db_execute_query(sql_update, data_to_update) if exec_query.rowcount > 0: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" User {user_to_edit} has been modified with level {str(user_new_level)}") - self.Admin.update_level(user_to_edit, user_new_level) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" User {user_to_edit} has been modified with level {str(user_new_level)}") + self.ctx.Admin.update_level(user_to_edit, user_new_level) else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Impossible de modifier l'utilisateur {str(user_new_level)}") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Impossible de modifier l'utilisateur {str(user_new_level)}") except TypeError as te: - self.Logs.error(f"Type error : {te}") + self.ctx.Logs.error(f"Type error : {te}") except ValueError as ve: - self.Logs.error(f"Value Error : {ve}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.Config.SERVICE_PREFIX}editaccess [USER] [NEWPASSWORD] [NEWLEVEL]") + self.ctx.Logs.error(f"Value Error : {ve}") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.ctx.Config.SERVICE_PREFIX}editaccess [USER] [NEWPASSWORD] [NEWLEVEL]") case 'delaccess': # .delaccess [USER] [CONFIRMUSER] @@ -818,18 +697,18 @@ class Irc: user_confirmation = cmd[2] if user_to_del != user_confirmation: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer") - self.Logs.warning(f':{dnickname} NOTICE {fromuser} : Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer') + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer") + self.ctx.Logs.warning(f':{dnickname} NOTICE {fromuser} : Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer') return None if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{self.Config.SERVICE_PREFIX}delaccess [USER] [CONFIRMUSER]") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{self.ctx.Config.SERVICE_PREFIX}delaccess [USER] [CONFIRMUSER]") return None - get_admin = self.Admin.get_admin(fromuser) + get_admin = self.ctx.Admin.get_admin(fromuser) if get_admin is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {fromuser} has no admin access") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {fromuser} has no admin access") return None current_user = fromuser @@ -838,82 +717,82 @@ class Irc: # Rechercher le user dans la base de données. mes_donnees = {'user': user_to_del} - query = f"SELECT user, level FROM {self.Config.TABLE_ADMIN} WHERE user = :user" - result = self.Base.db_execute_query(query, mes_donnees) + query = f"SELECT user, level FROM {self.ctx.Config.TABLE_ADMIN} WHERE user = :user" + result = await self.ctx.Base.db_execute_query(query, mes_donnees) info_user = result.fetchone() if not info_user is None: level_user_to_del = info_user[1] if current_user_level <= level_user_to_del: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are not allowed to delete this access") - self.Logs.warning(f':{dnickname} NOTICE {fromuser} : You are not allowed to delete this access') + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are not allowed to delete this access") + self.ctx.Logs.warning(f':{dnickname} NOTICE {fromuser} : You are not allowed to delete this access') return None data_to_delete = {'user': user_to_del} - sql_delete = f"DELETE FROM {self.Config.TABLE_ADMIN} WHERE user = :user" - exec_query = self.Base.db_execute_query(sql_delete, data_to_delete) + sql_delete = f"DELETE FROM {self.ctx.Config.TABLE_ADMIN} WHERE user = :user" + exec_query = await self.ctx.Base.db_execute_query(sql_delete, data_to_delete) if exec_query.rowcount > 0: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"User {user_to_del} has been deleted !") - self.Admin.delete(user_to_del) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"User {user_to_del} has been deleted !") + self.ctx.Admin.delete(user_to_del) else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Impossible de supprimer l'utilisateur.") - self.Logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Impossible de supprimer l'utilisateur.") + self.ctx.Logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.") case 'cert': # Syntax !cert try: if len(cmd) < 2: - self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert add") - self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert del") + await self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert add") + await self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert del") return None - admin_obj = self.Admin.get_admin(fromuser) + admin_obj = self.ctx.Admin.get_admin(fromuser) param = cmd[1] # add or del match param: case 'add': if admin_obj: if admin_obj.fingerprint is not None: - query = f'UPDATE {self.Config.TABLE_ADMIN} SET fingerprint = :fingerprint WHERE user = :user' - r = self.Base.db_execute_query(query, {'fingerprint': admin_obj.fingerprint, 'user': admin_obj.account}) + query = f'UPDATE {self.ctx.Config.TABLE_ADMIN} SET fingerprint = :fingerprint WHERE user = :user' + r = await self.ctx.Base.db_execute_query(query, {'fingerprint': admin_obj.fingerprint, 'user': admin_obj.account}) if r.rowcount > 0: - self.Protocol.send_notice(dnickname, fromuser, f'[ {GREEN}CERT{NOGC} ] Your new fingerprint has been attached to your account. {admin_obj.fingerprint}') + await self.Protocol.send_notice(dnickname, fromuser, f'[ {GREEN}CERT{NOGC} ] Your new fingerprint has been attached to your account. {admin_obj.fingerprint}') else: - self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] Impossible to add your fingerprint.{admin_obj.fingerprint}') + await self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] Impossible to add your fingerprint.{admin_obj.fingerprint}') else: - self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] There is no fingerprint to add.') + await self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] There is no fingerprint to add.') case 'del': if admin_obj: - query = f"UPDATE {self.Config.TABLE_ADMIN} SET fingerprint = :fingerprint WHERE user =:user" - r = self.Base.db_execute_query(query, {'fingerprint': None, 'user': admin_obj.account}) + query = f"UPDATE {self.ctx.Config.TABLE_ADMIN} SET fingerprint = :fingerprint WHERE user =:user" + r = await self.ctx.Base.db_execute_query(query, {'fingerprint': None, 'user': admin_obj.account}) if r.rowcount > 0: - self.Protocol.send_notice(dnickname, fromuser, f'[ {GREEN}CERT{NOGC} ] Your fingerprint has been removed from your account. {admin_obj.fingerprint}') + await self.Protocol.send_notice(dnickname, fromuser, f'[ {GREEN}CERT{NOGC} ] Your fingerprint has been removed from your account. {admin_obj.fingerprint}') else: - self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] Impossible to remove your fingerprint.{admin_obj.fingerprint}') + await self.Protocol.send_notice(dnickname, fromuser, f'[ {RED}CERT{NOGC} ] Impossible to remove your fingerprint.{admin_obj.fingerprint}') case _: - self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert add") - self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert del") + await self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert add") + await self.Protocol.send_notice(dnickname, fromuser, f"Right command : /msg {dnickname} cert del") return None except Exception as e: - self.Logs.error(e) + self.ctx.Logs.error(e) case 'register': # Syntax. Register PASSWORD EMAIL try: if len(cmd) < 3: - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ' + msg=f'/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ' ) return None password = cmd[1] email = cmd[2] - if not self.Base.is_valid_email(email_to_control=email): - self.Protocol.send_notice( + if not self.ctx.Base.is_valid_email(email_to_control=email): + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg='The email is not valid. You must provide a valid email address (first.name@email.extension)' @@ -923,34 +802,34 @@ class Irc: user_obj = u if user_obj is None: - self.Logs.error(f"Nickname ({fromuser}) doesn't exist, it is impossible to register this nickname") + self.ctx.Logs.error(f"Nickname ({fromuser}) doesn't exist, it is impossible to register this nickname") return None # If the account already exist. - if self.Client.db_is_account_exist(fromuser): - self.Protocol.send_notice( + if self.ctx.Client.db_is_account_exist(fromuser): + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=f"Your account already exist, please try to login instead /msg {self.Config.SERVICE_NICKNAME} IDENTIFY " + msg=f"Your account already exist, please try to login instead /msg {self.ctx.Config.SERVICE_NICKNAME} IDENTIFY " ) return None # If the account doesn't exist then insert into database data_to_record = { - 'createdOn': self.Utils.get_sdatetime(), 'account': fromuser, + 'createdOn': self.ctx.Utils.get_sdatetime(), 'account': fromuser, 'nickname': user_obj.nickname, 'hostname': user_obj.hostname, 'vhost': user_obj.vhost, 'realname': user_obj.realname, 'email': email, - 'password': self.Loader.Utils.hash_password(password=password), 'level': 0 + 'password': self.ctx.Utils.hash_password(password=password), 'level': 0 } - insert_to_db = self.Base.db_execute_query(f""" - INSERT INTO {self.Config.TABLE_CLIENT} + insert_to_db = await self.ctx.Base.db_execute_query(f""" + INSERT INTO {self.ctx.Config.TABLE_CLIENT} (createdOn, account, nickname, hostname, vhost, realname, email, password, level) VALUES (:createdOn, :account, :nickname, :hostname, :vhost, :realname, :email, :password, :level) """, data_to_record) if insert_to_db.rowcount > 0: - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"You have register your nickname successfully" @@ -959,84 +838,84 @@ class Irc: return None except ValueError as ve: - self.Logs.error(f"Value Error : {ve}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.Config.SERVICE_PREFIX}{command.upper()} ") + self.ctx.Logs.error(f"Value Error : {ve}") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.ctx.Config.SERVICE_PREFIX}{command.upper()} ") case 'identify': # Identify ACCOUNT PASSWORD try: if len(cmd) < 3: - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ' + msg=f'/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ' ) return None account = str(cmd[1]) # account - encrypted_password = self.Loader.Utils.hash_password(cmd[2]) + encrypted_password = self.ctx.Utils.hash_password(cmd[2]) user_obj = u client_obj = c if client_obj is not None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are already logged in") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are already logged in") return None - db_query = f"SELECT account FROM {self.Config.TABLE_CLIENT} WHERE account = :account AND password = :password" + db_query = f"SELECT account FROM {self.ctx.Config.TABLE_CLIENT} WHERE account = :account AND password = :password" db_param = {'account': account, 'password': encrypted_password} - exec_query = self.Base.db_execute_query(db_query, db_param) + exec_query = await self.ctx.Base.db_execute_query(db_query, db_param) result_query = exec_query.fetchone() if result_query: account = result_query[0] - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are now logged in") - client = self.Loader.Definition.MClient(**user_obj.to_dict(), account=account) - self.Client.insert(client) - self.Protocol.send_svslogin(user_obj.uid, account) - self.Protocol.send_svs2mode(nickname=fromuser, user_mode='+r') + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are now logged in") + client = self.ctx.Definition.MClient(**user_obj.to_dict(), account=account) + self.ctx.Client.insert(client) + await self.Protocol.send_svslogin(user_obj.uid, account) + await self.Protocol.send_svs2mode(nickname=fromuser, user_mode='+r') else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Wrong password or account") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Wrong password or account") return None except ValueError as ve: - self.Logs.error(f"Value Error: {ve}") - self.Protocol.send_notice( + self.ctx.Logs.error(f"Value Error: {ve}") + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ' + msg=f'/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ' ) except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}") case 'logout': try: # LOGOUT if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") return None user_obj = u if user_obj is None: - self.Logs.error(f"The User [{fromuser}] is not available in the database") + self.ctx.Logs.error(f"The User [{fromuser}] is not available in the database") return None client_obj = c if client_obj is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nothing to logout. please login first") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nothing to logout. please login first") return None - self.Protocol.send_svslogout(client_obj) - self.Client.delete(user_obj.uid) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You have been logged out successfully") + await self.Protocol.send_svslogout(client_obj) + self.ctx.Client.delete(user_obj.uid) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You have been logged out successfully") except ValueError as ve: - self.Logs.error(f"Value Error: {ve}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") + self.ctx.Logs.error(f"Value Error: {ve}") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") except Exception as err: - self.Logs.error(f"General Error: {err}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") + self.ctx.Logs.error(f"General Error: {err}") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} ") case 'help': # Syntax. !help [module_name] @@ -1052,12 +931,12 @@ class Irc: return None mod_name = str(cmd[1]) - await self.ModuleUtils.load_one_module(self, mod_name, fromuser) + await self.ctx.ModuleUtils.load_one_module(mod_name, fromuser) return None except KeyError as ke: - self.Logs.error(f"Key Error: {ke} - list recieved: {cmd}") + self.ctx.Logs.error(f"Key Error: {ke} - list recieved: {cmd}") except Exception as err: - self.Logs.error(f"General Error: {err} - list recieved: {cmd}", exc_info=True) + self.ctx.Logs.error(f"General Error: {err} - list recieved: {cmd}", exc_info=True) case 'unload': # unload mod_defender @@ -1067,10 +946,10 @@ class Irc: self.Protocol.send_notice(dnickname, fromuser, tr("Syntax. /msg %s %s MODULE_NAME", dnickname, command.upper())) return None module_name = str(cmd[1]).lower() - self.ModuleUtils.unload_one_module(self, module_name, False) + await self.ctx.ModuleUtils.unload_one_module(module_name, False) return None except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}") case 'reload': # reload mod_defender @@ -1081,63 +960,72 @@ class Irc: return None module_name = str(cmd[1]).lower() - await self.ModuleUtils.reload_one_module(self, module_name, fromuser) + await self.ctx.ModuleUtils.reload_one_module(module_name, fromuser) return None except Exception as e: - self.Logs.error(f"Something went wrong with a module you want to reload: {e}") + self.ctx.Logs.error(f"Something went wrong with a module you want to reload: {e}") await self.Protocol.send_priv_msg( nick_from=dnickname, msg=f"Something went wrong with the module: {e}", channel=dchanlog ) - self.ModuleUtils.db_delete_module(module_name) + await self.ctx.ModuleUtils.db_delete_module(module_name) case 'quit': try: final_reason = ' '.join(cmd[1:]) self.hb_active = False - self.Base.shutdown() - self.Base.execute_periodic_action() + await self.ctx.Base.shutdown() + self.ctx.Base.execute_periodic_action() - for chan_name in self.Channel.UID_CHANNEL_DB: + for chan_name in self.ctx.Channel.UID_CHANNEL_DB: # self.Protocol.send_mode_chan(chan_name.name, '-l') - self.Protocol.send_set_mode('-l', channel_name=chan_name.name) + await self.Protocol.send_set_mode('-l', channel_name=chan_name.name) - for client in self.Client.CLIENT_DB: - self.Protocol.send_svslogout(client) + for client in self.ctx.Client.CLIENT_DB: + await self.Protocol.send_svslogout(client) - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"Arrêt du service {dnickname}" ) - self.Protocol.send_squit(server_id=self.Config.SERVEUR_ID, server_link=self.Config.SERVEUR_LINK, reason=final_reason) - self.Logs.info(f'Arrêt du server {dnickname}') - self.Config.DEFENDER_RESTART = 0 self.signal = False + await self.Protocol.send_squit(server_id=self.ctx.Config.SERVEUR_ID, server_link=self.ctx.Config.SERVEUR_LINK, reason=final_reason) + self.ctx.Logs.info(f'Arrêt du server {dnickname}') + self.ctx.Config.DEFENDER_RESTART = 0 + + await self.writer.drain() + self.writer.close() + await self.writer.wait_closed() except IndexError as ie: - self.Logs.error(f'{ie}') + self.ctx.Logs.error(f'{ie}') + except ConnectionResetError as cerr: + if self.writer.is_closing(): + self.ctx.Logs.debug(f"Defender stopped properly! {cerr}") case 'restart': final_reason = ' '.join(cmd[1:]) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{dnickname.capitalize()} is going to restart!") + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{dnickname.capitalize()} is going to restart!") # Set restart status to 1 saying that the service will restart - self.Config.DEFENDER_RESTART = 1 + self.ctx.Config.DEFENDER_RESTART = 1 # set init to 1 saying that the service will be re initiated - self.Config.DEFENDER_INIT = 1 + self.ctx.Config.DEFENDER_INIT = 1 + + await rehash.restart_service(self.ctx) case 'rehash': - rehash.rehash_service(self, fromuser) + await rehash.rehash_service(self.ctx, fromuser) return None case 'show_modules': - self.Logs.debug('List of modules: ' + ', '.join([module.module_name for module in self.ModuleUtils.model_get_loaded_modules()])) - all_modules = self.ModuleUtils.get_all_available_modules() + self.ctx.Logs.debug('List of modules: ' + ', '.join([module.module_name for module in self.ctx.ModuleUtils.model_get_loaded_modules()])) + all_modules = self.ctx.ModuleUtils.get_all_available_modules() loaded = False - results = self.Base.db_execute_query(f'SELECT datetime, user, module_name FROM {self.Config.TABLE_MODULE}') + results = await self.ctx.Base.db_execute_query(f'SELECT datetime, user, module_name FROM {self.ctx.Config.TABLE_MODULE}') results = results.fetchall() for module in all_modules: @@ -1162,15 +1050,15 @@ class Irc: ) case 'show_timers': - if self.Base.running_timers: - for the_timer in self.Base.running_timers: - self.Protocol.send_notice( + if self.ctx.Base.running_timers: + for the_timer in self.ctx.Base.running_timers: + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f">> {the_timer.name} - {the_timer.is_alive()}" ) else: - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg="There is no timers that are running!" @@ -1178,29 +1066,33 @@ class Irc: return None case 'show_threads': - for thread in self.Base.running_threads: + for thread in self.ctx.Base.running_threads: await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f">> {thread.name} ({thread.is_alive()})" ) - - asyncio.create_task(self.new_coro(), name='my_new_coro') - for task in asyncio.all_tasks(): - print(task.get_name()) - print(task) return None + case 'show_asyncio': + for task in asyncio.all_tasks(): + await self.Protocol.send_notice( + nick_from=dnickname, + nick_to=fromuser, + msg=f">> {task.get_name()} (active)" + ) + return None + case 'show_channels': - for chan in self.Channel.UID_CHANNEL_DB: + for chan in self.ctx.Channel.UID_CHANNEL_DB: list_nicknames: list = [] for uid in chan.uids: pattern = fr'[:|@|%|\+|~|\*]*' parsed_UID = re.sub(pattern, '', uid) - list_nicknames.append(self.User.get_nickname(parsed_UID)) + list_nicknames.append(self.ctx.User.get_nickname(parsed_UID)) - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"Channel: {chan.name} - Users: {list_nicknames}" @@ -1208,10 +1100,10 @@ class Irc: return None case 'show_users': - count_users = len(self.User.UID_DB) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Total Connected Users: {count_users}") - for db_user in self.User.UID_DB: - self.Protocol.send_notice( + count_users = len(self.ctx.User.UID_DB) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Total Connected Users: {count_users}") + for db_user in self.ctx.User.UID_DB: + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"UID : {db_user.uid} - isWebirc: {db_user.isWebirc} - isWebSocket: {db_user.isWebsocket} - Nickname: {db_user.nickname} - Connection: {db_user.connexion_datetime}" @@ -1219,10 +1111,10 @@ class Irc: return None case 'show_clients': - count_users = len(self.Client.CLIENT_DB) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Total Connected Clients: {count_users}") - for db_client in self.Client.CLIENT_DB: - self.Protocol.send_notice( + count_users = len(self.ctx.Client.CLIENT_DB) + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Total Connected Clients: {count_users}") + for db_client in self.ctx.Client.CLIENT_DB: + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"UID : {db_client.uid} - isWebirc: {db_client.isWebirc} - isWebSocket: {db_client.isWebsocket} - Nickname: {db_client.nickname} - Account: {db_client.account} - Connection: {db_client.connexion_datetime}" @@ -1230,8 +1122,8 @@ class Irc: return None case 'show_admins': - for db_admin in self.Admin.UID_ADMIN_DB: - self.Protocol.send_notice( + for db_admin in self.ctx.Admin.UID_ADMIN_DB: + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"UID : {db_admin.uid} - Nickname: {db_admin.nickname} - Account: {db_admin.account} - Level: {db_admin.level} - Language: {db_admin.language} - Connection: {db_admin.connexion_datetime}" @@ -1239,8 +1131,8 @@ class Irc: return None case 'show_configuration': - for key, value in self.Config.to_dict().items(): - self.Protocol.send_notice( + for key, value in self.ctx.Config.to_dict().items(): + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f'{key} = {value}' @@ -1248,9 +1140,9 @@ class Irc: return None case 'show_cache': - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The cache is currently contains {self.Settings.get_cache_size()} value(s).") - for key, value in self.Settings.show_cache().items(): - self.Protocol.send_notice( + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The cache is currently contains {self.ctx.Settings.get_cache_size()} value(s).") + for key, value in self.ctx.Settings.show_cache().items(): + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"Key : {key} - Value: {value}" @@ -1258,15 +1150,15 @@ class Irc: return None case 'clear_cache': - cache_size = self.Settings.get_cache_size() + cache_size = self.ctx.Settings.get_cache_size() if cache_size > 0: - self.Settings.clear_cache() - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{cache_size} value(s) has been cleared from the cache.") + self.ctx.Settings.clear_cache() + await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{cache_size} value(s) has been cleared from the cache.") return None case 'uptime': uptime = self.get_defender_uptime() - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=uptime @@ -1274,51 +1166,47 @@ class Irc: return None case 'copyright': - self.Protocol.send_notice( + await self.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, - msg=f">> Defender V{self.Config.CURRENT_VERSION} Developped by adator®." + msg=f">> Defender V{self.ctx.Config.CURRENT_VERSION} Developped by adator®." ) return None case 'checkversion': - self.Base.create_thread(self.thread_check_for_new_version, (fromuser, )) + self.ctx.Base.create_asynctask(self.thread_check_for_new_version(fromuser)) return None case 'raw': raw_command = ' '.join(cmd[1:]) - self.Protocol.send_raw(raw_command) + await self.Protocol.send_raw(raw_command) return None case 'print_vars': with open('users.txt', 'w') as fw: i = 1 - for u in self.User.UID_DB: + for u in self.ctx.User.UID_DB: w = fw.write(u.to_dict().__str__() + "\n") - self.Logs.debug(f" {i} - chars written {w}") + self.ctx.Logs.debug(f" {i} - chars written {w}") i += 1 - self.Protocol.send_priv_msg(dnickname, "Data written in users.txt file", dchanlog) + await self.Protocol.send_priv_msg(dnickname, "Data written in users.txt file", dchanlog) with open('modules.txt', 'w') as fw: i = 1 - for u in self.ModuleUtils.DB_MODULE_HEADERS: + for u in self.ctx.ModuleUtils.DB_MODULE_HEADERS: w = fw.write(u.to_dict().__str__() + "\n") - self.Logs.debug(f" {i} - chars written {w}") + self.ctx.Logs.debug(f" {i} - chars written {w}") i += 1 - self.Protocol.send_priv_msg(dnickname, "Data written in modules.txt file", dchanlog) + await self.Protocol.send_priv_msg(dnickname, "Data written in modules.txt file", dchanlog) return None case 'start_rpc': - self.Loader.RpcServer.start_server() + self.ctx.Base.create_asynctask(self.ctx.RpcServer.start_server()) case 'stop_rpc': - self.Loader.RpcServer.stop_server() + self.ctx.Base.create_asynctask(self.ctx.RpcServer.stop_server()) case _: pass - async def new_coro(self): - self.Logs.debug("Creating new coro") - await asyncio.sleep(5) - self.Logs.debug("End of the coro") \ No newline at end of file diff --git a/core/loader.py b/core/loader.py index c254552..611fc9f 100644 --- a/core/loader.py +++ b/core/loader.py @@ -14,6 +14,15 @@ import core.classes.protocols.factory as factory class Loader: + _instance = None + + def __new__(cls, *agrs): + + if cls._instance is None: + cls._instance = super().__new__(cls) + + return cls._instance + def __init__(self): # Load Main Modules @@ -70,10 +79,11 @@ class Loader: self.Irc: irc.Irc = irc.Irc(self) - self.PFactory: factory.ProtocolFactorty = factory.ProtocolFactorty(self.Irc) + self.PFactory: factory.ProtocolFactorty = factory.ProtocolFactorty(self) - self.RpcServer: rpc_mod.JSONRPCServer = rpc_mod.JSONRPCServer(self) - - self.Base.init() + self.RpcServer: rpc_mod.JSonRpcServer = rpc_mod.JSonRpcServer(self) self.Logs.debug(self.Utils.tr("Loader %s success", __name__)) + + async def start(self): + await self.Base.init() diff --git a/core/logs.py b/core/logs.py index 1ed5152..fbf02a7 100644 --- a/core/logs.py +++ b/core/logs.py @@ -15,7 +15,7 @@ class ServiceLogging: self.SERVER_PREFIX = None self.LOGGING_CONSOLE = True - self.LOG_FILTERS: list[str] = [f":{self.SERVER_PREFIX}auth", "['PASS'"] + self.LOG_FILTERS: list[str] = ["PING", f":{self.SERVER_PREFIX}auth", "['PASS'"] self.file_handler = None self.stdout_handler = None diff --git a/core/module.py b/core/module.py index df684dd..4d3b0ee 100644 --- a/core/module.py +++ b/core/module.py @@ -1,9 +1,9 @@ ''' This is the main operational file to handle modules ''' -from pathlib import Path import sys import importlib +from pathlib import Path from types import ModuleType from typing import TYPE_CHECKING, Optional from core.definition import DefenderModuleHeader, MModule @@ -12,6 +12,7 @@ from core.utils import tr if TYPE_CHECKING: from core.loader import Loader from core.irc import Irc + from core.classes.interfaces.imodule import IModule class Module: @@ -19,11 +20,7 @@ class Module: DB_MODULE_HEADERS: list[DefenderModuleHeader] = [] def __init__(self, loader: 'Loader') -> None: - self.__Loader = loader - self.__Base = loader.Base - self.__Logs = loader.Logs - self.__Utils = loader.Utils - self.__Config = loader.Config + self._ctx = loader def get_all_available_modules(self) -> list[str]: """Get list of all main modules @@ -34,7 +31,7 @@ class Module: """ base_path = Path('mods') modules_available = [file.name.replace('.py', '') for file in base_path.rglob('mod_*.py')] - self.__Logs.debug(f"Modules available: {modules_available}") + self._ctx.Logs.debug(f"Modules available: {modules_available}") return modules_available def get_module_information(self, module_name: str) -> tuple[Optional[str], Optional[str], Optional[str]]: @@ -45,14 +42,14 @@ class Module: module_name = module_name.lower() # --> mod_defender module_folder = module_name.split('_')[1].lower() # --> defender class_name = module_name.split('_')[1].capitalize() # --> Defender - self.__Logs.debug(f"Module information Folder: {module_folder}, Name: {module_name}, Class: {class_name}") + self._ctx.Logs.debug(f"Module information Folder: {module_folder}, Name: {module_name}, Class: {class_name}") return module_folder, module_name, class_name def get_module_header(self, module_name: str) -> Optional[DefenderModuleHeader]: for mod_h in self.DB_MODULE_HEADERS: if module_name.lower() == mod_h.name.lower(): - self.__Logs.debug(f"Module Header found: {mod_h}") + self._ctx.Logs.debug(f"Module Header found: {mod_h}") return mod_h return None @@ -68,7 +65,7 @@ class Module: """ mod_header = DefenderModuleHeader(**module_header) if self.get_module_header(mod_header.name) is None: - self.__Logs.debug(f"[MOD_HEADER] The module header has been created! ({mod_header.name} v{mod_header.version})") + self._ctx.Logs.debug(f"[MOD_HEADER] The module header has been created! ({mod_header.name} v{mod_header.version})") self.DB_MODULE_HEADERS.append(mod_header) return True @@ -77,73 +74,74 @@ class Module: def delete_module_header(self, module_name: str) -> bool: mod_header = self.get_module_header(module_name) if mod_header is not None: - self.__Logs.debug(f"[MOD_HEADER] The module header has been deleted ({mod_header.name} v{mod_header.version})") + self._ctx.Logs.debug(f"[MOD_HEADER] The module header has been deleted ({mod_header.name} v{mod_header.version})") self.DB_MODULE_HEADERS.remove(mod_header) return True - self.__Logs.debug(f"[MOD_HEADER ERROR] Impossible to remove the module header ({module_name})") + self._ctx.Logs.debug(f"[MOD_HEADER ERROR] Impossible to remove the module header ({module_name})") return False - async def load_one_module(self, uplink: 'Irc', module_name: str, nickname: str, is_default: bool = False) -> bool: + async def load_one_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool: module_folder, module_name, class_name = self.get_module_information(module_name) if module_folder is None or module_name is None or class_name is None: - self.__Logs.error(f"There is an error with the module name! {module_folder}, {module_name}, {class_name}") + self._ctx.Logs.error(f"There is an error with the module name! {module_folder}, {module_name}, {class_name}") return False if self.is_module_exist_in_sys_module(module_name): - self.__Logs.debug(f"Module [{module_folder}.{module_name}] already loaded!") + self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] already loaded!") if self.model_is_module_exist(module_name): # Si le module existe dans la variable globale retourne False - self.__Logs.debug(f"Module [{module_folder}.{module_name}] exist in the local variable!") - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, - msg=f"Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self.__Config.SERVICE_PREFIX}reload {module_name}", - channel=self.__Config.SERVICE_CHANLOG + self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] exist in the local variable!") + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, + msg=f"Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self._ctx.Config.SERVICE_PREFIX}reload {module_name}", + channel=self._ctx.Config.SERVICE_CHANLOG ) return False - return self.reload_one_module(uplink, module_name, nickname) + return self.reload_one_module(module_name, nickname) # Charger le module try: loaded_module = importlib.import_module(f'mods.{module_folder}.{module_name}') my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe - create_instance_of_the_class = my_class(uplink.Loader) # Créer une nouvelle instance de la classe + create_instance_of_the_class: 'IModule' = my_class(self._ctx) # Créer une nouvelle instance de la classe + await create_instance_of_the_class.load() if self._ctx.Utils.is_coroutinefunction(create_instance_of_the_class.load) else create_instance_of_the_class.load() self.create_module_header(create_instance_of_the_class.MOD_HEADER) except AttributeError as attr: - red = uplink.Config.COLORS.red - nogc = uplink.Config.COLORS.nogc - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + red = self._ctx.Config.COLORS.red + nogc = self._ctx.Config.COLORS.red + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=tr("[%sMODULE ERROR%s] Module %s is facing issues! %s", red, nogc, module_name, attr), - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.error(msg=attr, exc_info=True) + self._ctx.Logs.error(msg=attr, exc_info=True) return False if not hasattr(create_instance_of_the_class, 'cmd'): - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=tr("cmd method is not available in the module (%s)", module_name), - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.critical(f"The Module {module_name} has not been loaded because cmd method is not available") - self.db_delete_module(module_name) + self._ctx.Logs.critical(f"The Module {module_name} has not been loaded because cmd method is not available") + await self.db_delete_module(module_name) return False # Charger la nouvelle class dans la variable globale if self.model_insert_module(MModule(module_name, class_name, create_instance_of_the_class)): # Enregistrer le module dans la base de données - self.db_register_module(module_name, nickname, is_default) - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + await self.db_register_module(module_name, nickname, is_default) + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=tr("Module %s loaded!", module_name), - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.debug(f"Module {class_name} has been loaded") + self._ctx.Logs.debug(f"Module {class_name} has been loaded") return True return False @@ -151,7 +149,7 @@ class Module: def load_all_modules(self) -> bool: ... - async def reload_one_module(self, uplink: 'Irc', module_name: str, nickname: str) -> bool: + async def reload_one_module(self, module_name: str, nickname: str) -> bool: """Reloading one module and insert it into the model as well as the database Args: @@ -163,21 +161,21 @@ class Module: bool: True if the module has been reloaded """ module_folder, module_name, class_name = self.get_module_information(module_name) - red = self.__Config.COLORS.red - nogc = self.__Config.COLORS.nogc + red = self._ctx.Config.COLORS.red + nogc = self._ctx.Config.COLORS.nogc try: if self.is_module_exist_in_sys_module(module_name): module_model = self.model_get_module(module_name) if module_model: self.delete_module_header(module_model.class_instance.MOD_HEADER['name']) - module_model.class_instance.unload() + await module_model.class_instance.unload() if self._ctx.Utils.is_coroutinefunction(module_model.class_instance.unload) else module_model.class_instance.unload() else: - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, - msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] hasn't been reloaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}", - channel=self.__Config.SERVICE_CHANLOG + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, + msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] hasn't been reloaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}", + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.debug(f"Module [{module_folder}.{module_name}] not found! Please use {self.__Config.SERVICE_PREFIX}load {module_name}") + self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] not found! Please use {self._ctx.Config.SERVICE_PREFIX}load {module_name}") return False # reload module dependencies @@ -186,37 +184,38 @@ class Module: the_module = sys.modules[f'mods.{module_folder}.{module_name}'] importlib.reload(the_module) my_class = getattr(the_module, class_name, None) - new_instance = my_class(uplink.Loader) + new_instance: 'IModule' = my_class(self._ctx) + await new_instance.load() if self._ctx.Utils.is_coroutinefunction(new_instance.load) else new_instance.load() self.create_module_header(new_instance.MOD_HEADER) module_model.class_instance = new_instance # Créer le module dans la base de données - self.db_register_module(module_name, nickname) - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + await self.db_register_module(module_name, nickname) + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f"Module [{module_folder}.{module_name}] has been reloaded!", - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.debug(f"Module [{module_folder}.{module_name}] reloaded!") + self._ctx.Logs.debug(f"Module [{module_folder}.{module_name}] reloaded!") return True else: # Module is not loaded! Nothing to reload - self.__Logs.debug(f"[RELOAD MODULE ERROR] [{module_folder}.{module_name}] is not loaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}") - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, - msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] is not loaded! You must use {self.__Config.SERVICE_PREFIX}load {module_name}", - channel=self.__Config.SERVICE_CHANLOG + self._ctx.Logs.debug(f"[RELOAD MODULE ERROR] [{module_folder}.{module_name}] is not loaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}") + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, + msg=f"[ {red}RELOAD MODULE ERROR{nogc} ] Module [{module_folder}.{module_name}] is not loaded! You must use {self._ctx.Config.SERVICE_PREFIX}load {module_name}", + channel=self._ctx.Config.SERVICE_CHANLOG ) return False except (TypeError, AttributeError, KeyError, Exception) as err: - self.__Logs.error(f"[RELOAD MODULE ERROR]: {err}", exc_info=True) - await uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + self._ctx.Logs.error(f"[RELOAD MODULE ERROR]: {err}", exc_info=True) + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f"[RELOAD MODULE ERROR]: {err}", - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.db_delete_module(module_name) + await self.db_delete_module(module_name) def reload_all_modules(self) -> bool: ... @@ -242,12 +241,12 @@ class Module: try: if 'mod_' not in name and 'schemas' not in name: importlib.reload(module) - self.__Logs.debug(f'[LOAD_MODULE] Module {module} success') + self._ctx.Logs.debug(f'[LOAD_MODULE] Module {module} success') except Exception as err: - self.__Logs.error(f'[LOAD_MODULE] Module {module} failed [!] - {err}') + self._ctx.Logs.error(f'[LOAD_MODULE] Module {module} failed [!] - {err}') - def unload_one_module(self, uplink: 'Irc', module_name: str, keep_in_db: bool = True) -> bool: + async def unload_one_module(self, module_name: str, keep_in_db: bool = True) -> bool: """Unload a module Args: @@ -260,23 +259,23 @@ class Module: """ try: # Le nom du module. exemple: mod_defender - red = self.__Config.COLORS.red - nogc = self.__Config.COLORS.nogc + red = self._ctx.Config.COLORS.red + nogc = self._ctx.Config.COLORS.nogc module_folder, module_name, class_name = self.get_module_information(module_name) module = self.model_get_module(module_name) if module is None: - self.__Logs.debug(f"[ UNLOAD MODULE ERROR ] This module {module_name} is not loaded!") - self.db_delete_module(module_name) - uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + self._ctx.Logs.debug(f"[ UNLOAD MODULE ERROR ] This module {module_name} is not loaded!") + await self.db_delete_module(module_name) + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f"[ {red}UNLOAD MODULE ERROR{nogc} ] This module {module_name} is not loaded!", - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) return False if module: self.delete_module_header(module.class_instance.MOD_HEADER['name']) - module.class_instance.unload() + await module.class_instance.unload() if self._ctx.Utils.is_coroutinefunction(module.class_instance.unload) else module.class_instance.unload() self.DB_MODULES.remove(module) # Delete from the sys.modules. @@ -284,25 +283,25 @@ class Module: del sys.modules[f"mods.{module_folder}.{module_name}"] if sys.modules.get(f'mods.{module_folder}.{module_name}'): - self.__Logs.debug(f"Module mods.{module_folder}.{module_name} still in the sys.modules") + self._ctx.Logs.debug(f"Module mods.{module_folder}.{module_name} still in the sys.modules") # Supprimer le module de la base de données if not keep_in_db: - self.db_delete_module(module_name) + await self.db_delete_module(module_name) - uplink.Protocol.send_priv_msg( - nick_from=self.__Config.SERVICE_NICKNAME, + await self._ctx.Irc.Protocol.send_priv_msg( + nick_from=self._ctx.Config.SERVICE_NICKNAME, msg=f"[ UNLOAD MODULE INFO ] Module {module_name} has been unloaded!", - channel=self.__Config.SERVICE_CHANLOG + channel=self._ctx.Config.SERVICE_CHANLOG ) - self.__Logs.debug(f"[ UNLOAD MODULE ] {module_name} has been unloaded!") + self._ctx.Logs.debug(f"[ UNLOAD MODULE ] {module_name} has been unloaded!") return True - self.__Logs.debug(f"[UNLOAD MODULE]: Module {module_name} not found in DB_MODULES variable!") + self._ctx.Logs.debug(f"[UNLOAD MODULE]: Module {module_name} not found in DB_MODULES variable!") return False except Exception as err: - self.__Logs.error(f"General Error: {err}", exc_info=True) + self._ctx.Logs.error(f"General Error: {err}", exc_info=True) return False def unload_all_modules(self) -> bool: @@ -319,9 +318,9 @@ class Module: """ module_folder, module_name, class_name = self.get_module_information(module_name) if "mods." + module_folder + "." + module_name in sys.modules: - self.__Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) found in sys.modules") + self._ctx.Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) found in sys.modules") return True - self.__Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) not found in sys.modules") + self._ctx.Logs.debug(f"[SYS MODULE] (mods.{module_folder}.{module_name}) not found in sys.modules") return False ''' @@ -338,10 +337,10 @@ class Module: """ for module in self.DB_MODULES: if module.module_name.lower() == module_name.lower(): - self.__Logs.debug(f"[MODEL MODULE GET] The module {module_name} has been found in the model DB_MODULES") + self._ctx.Logs.debug(f"[MODEL MODULE GET] The module {module_name} has been found in the model DB_MODULES") return module - self.__Logs.debug(f"[MODEL MODULE GET] The module {module_name} not found in the model DB_MODULES") + self._ctx.Logs.debug(f"[MODEL MODULE GET] The module {module_name} not found in the model DB_MODULES") return None def model_get_loaded_modules(self) -> list[MModule]: @@ -351,7 +350,7 @@ class Module: Returns: list[MModule]: A list of module model object """ - # self.__Logs.debug(f"[MODEL MODULE LOADED MODULES] {len(self.DB_MODULES)} modules found!") + # self._ctx.Logs.debug(f"[MODEL MODULE LOADED MODULES] {len(self.DB_MODULES)} modules found!") return self.DB_MODULES def model_insert_module(self, module_model: MModule) -> bool: @@ -366,17 +365,17 @@ class Module: module = self.model_get_module(module_model.module_name) if module is None: self.DB_MODULES.append(module_model) - self.__Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} has been inserted in the local variable model DB_MODULES") + self._ctx.Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} has been inserted in the local variable model DB_MODULES") return True - self.__Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} already exist in the local variable model DB_MODULES") + self._ctx.Logs.debug(f"[MODEL MODULE INSERT] The module {module_model.module_name} already exist in the local variable model DB_MODULES") return False def model_clear(self) -> None: """Clear DB_MODULES list! """ self.DB_MODULES.clear() - self.__Logs.debug("[MODEL MODULE CLEAR] The local variable model DB_MODULES has been cleared") + self._ctx.Logs.debug("[MODEL MODULE CLEAR] The local variable model DB_MODULES has been cleared") return None def model_is_module_exist(self, module_name: str) -> bool: @@ -389,30 +388,30 @@ class Module: bool: True if the module_name exist """ if self.model_get_module(module_name): - self.__Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} exist in the local model DB_MODULES!") + self._ctx.Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} exist in the local model DB_MODULES!") return True - self.__Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} is not available in the local model DB_MODULES!") + self._ctx.Logs.debug(f"[MODEL MODULE EXIST] The module {module_name} is not available in the local model DB_MODULES!") return False ''' OPERATION DEDICATED TO DATABASE MANAGEMENT ''' - async def db_load_all_existing_modules(self, uplink: 'Irc') -> bool: + async def db_load_all_existing_modules(self) -> bool: """Charge les modules qui existe déja dans la base de données Returns: None: Aucun retour requis, elle charge puis c'est tout """ - self.__Logs.debug("[DB LOAD MODULE] Loading modules from the database!") - result = self.__Base.db_execute_query(f"SELECT module_name FROM {self.__Config.TABLE_MODULE}") + self._ctx.Logs.debug("[DB LOAD MODULE] Loading modules from the database!") + result = await self._ctx.Base.db_execute_query(f"SELECT module_name FROM {self._ctx.Config.TABLE_MODULE}") for r in result.fetchall(): - await self.load_one_module(uplink, r[0], 'sys', True) + await self.load_one_module(r[0], 'sys', True) return True - def db_is_module_exist(self, module_name: str) -> bool: + async def db_is_module_exist(self, module_name: str) -> bool: """Check if the module exist in the database Args: @@ -421,18 +420,18 @@ class Module: Returns: bool: True if the module exist in the database """ - query = f"SELECT id FROM {self.__Config.TABLE_MODULE} WHERE module_name = :module_name" + query = f"SELECT id FROM {self._ctx.Config.TABLE_MODULE} WHERE module_name = :module_name" mes_donnes = {'module_name': module_name.lower()} - results = self.__Base.db_execute_query(query, mes_donnes) + results = await self._ctx.Base.db_execute_query(query, mes_donnes) if results.fetchall(): - self.__Logs.debug(f"[DB MODULE EXIST] The module {module_name} exist in the database!") + self._ctx.Logs.debug(f"[DB MODULE EXIST] The module {module_name} exist in the database!") return True else: - self.__Logs.debug(f"[DB MODULE EXIST] The module {module_name} is not available in the database!") + self._ctx.Logs.debug(f"[DB MODULE EXIST] The module {module_name} is not available in the database!") return False - def db_register_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool: + async def db_register_module(self, module_name: str, nickname: str, is_default: bool = False) -> bool: """Insert a new module in the database Args: @@ -440,49 +439,49 @@ class Module: nickname (str): The user who loaded the module isdefault (int): Is this a default module. Default 0 """ - if not self.db_is_module_exist(module_name): - insert_cmd_query = f"INSERT INTO {self.__Config.TABLE_MODULE} (datetime, user, module_name, isdefault) VALUES (:datetime, :user, :module_name, :isdefault)" - mes_donnees = {'datetime': self.__Utils.get_sdatetime(), 'user': nickname, 'module_name': module_name.lower(), 'isdefault': is_default} - insert = self.__Base.db_execute_query(insert_cmd_query, mes_donnees) + if not await self.db_is_module_exist(module_name): + insert_cmd_query = f"INSERT INTO {self._ctx.Config.TABLE_MODULE} (datetime, user, module_name, isdefault) VALUES (:datetime, :user, :module_name, :isdefault)" + mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'user': nickname, 'module_name': module_name.lower(), 'isdefault': is_default} + insert = await self._ctx.Base.db_execute_query(insert_cmd_query, mes_donnees) if insert.rowcount > 0: - self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} has been inserted to the database!") + self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} has been inserted to the database!") return True else: - self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} not inserted to the database!") + self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} not inserted to the database!") return False - self.__Logs.debug(f"[DB REGISTER MODULE] Module {module_name} already exist in the database! Nothing to insert!") + self._ctx.Logs.debug(f"[DB REGISTER MODULE] Module {module_name} already exist in the database! Nothing to insert!") return False - def db_update_module(self, module_name: str, nickname: str) -> None: + async def db_update_module(self, module_name: str, nickname: str) -> None: """Update the datetime and the user that updated the module Args: module_name (str): The module name to update nickname (str): The nickname who updated the module """ - update_cmd_query = f"UPDATE {self.__Config.TABLE_MODULE} SET datetime = :datetime, LOWER(user) = :user WHERE LOWER(module_name) = :module_name" - mes_donnees = {'datetime': self.__Utils.get_sdatetime(), 'user': nickname.lower(), 'module_name': module_name.lower()} - result = self.__Base.db_execute_query(update_cmd_query, mes_donnees) + update_cmd_query = f"UPDATE {self._ctx.Config.TABLE_MODULE} SET datetime = :datetime, LOWER(user) = :user WHERE LOWER(module_name) = :module_name" + mes_donnees = {'datetime': self._ctx.Utils.get_sdatetime(), 'user': nickname.lower(), 'module_name': module_name.lower()} + result = await self._ctx.Base.db_execute_query(update_cmd_query, mes_donnees) if result.rowcount > 0: - self.__Logs.debug(f"[DB UPDATE MODULE] Module {module_name} has been updated!") + self._ctx.Logs.debug(f"[DB UPDATE MODULE] Module {module_name} has been updated!") return True else: - self.__Logs.debug(f"[DB UPDATE MODULE] Module {module_name} not found! Nothing to update!") + self._ctx.Logs.debug(f"[DB UPDATE MODULE] Module {module_name} not found! Nothing to update!") return False - def db_delete_module(self, module_name:str) -> None: + async def db_delete_module(self, module_name:str) -> None: """Delete a module from the database Args: module_name (str): The module name you want to delete """ - insert_cmd_query = f"DELETE FROM {self.__Config.TABLE_MODULE} WHERE LOWER(module_name) = :module_name" + insert_cmd_query = f"DELETE FROM {self._ctx.Config.TABLE_MODULE} WHERE LOWER(module_name) = :module_name" mes_donnees = {'module_name': module_name.lower()} - delete = self.__Base.db_execute_query(insert_cmd_query, mes_donnees) + delete = await self._ctx.Base.db_execute_query(insert_cmd_query, mes_donnees) if delete.rowcount > 0: - self.__Logs.debug(f"[DB MODULE DELETE] The module {module_name} has been deleted from the dabatase!") + self._ctx.Logs.debug(f"[DB MODULE DELETE] The module {module_name} has been deleted from the dabatase!") return True - self.__Logs.debug(f"[DB MODULE DELETE] The module {module_name} is not available in the database! Nothing to delete!") + self._ctx.Logs.debug(f"[DB MODULE DELETE] The module {module_name} is not available in the database! Nothing to delete!") return False diff --git a/core/utils.py b/core/utils.py index 0abd02d..a887214 100644 --- a/core/utils.py +++ b/core/utils.py @@ -13,6 +13,7 @@ from time import time from random import choice from hashlib import md5, sha3_512 from core.classes.modules.settings import global_settings +from asyncio import iscoroutinefunction if TYPE_CHECKING: from core.irc import Irc @@ -243,3 +244,14 @@ def hide_sensitive_data(srvmsg: list[str]) -> list[str]: except ValueError: return srvmsg + +def is_coroutinefunction(func: Any) -> bool: + """Check if the function is a coroutine or not + + Args: + func (Any): an callable object + + Returns: + bool: True if the function is a coroutine + """ + return iscoroutinefunction(func) \ No newline at end of file diff --git a/defender.py b/defender.py index 9b03d89..c5787bd 100644 --- a/defender.py +++ b/defender.py @@ -13,6 +13,7 @@ from core import install async def main(): from core.loader import Loader loader = Loader() + await loader.start() await loader.Irc.run() if __name__ == "__main__": diff --git a/mods/clone/clone_manager.py b/mods/clone/clone_manager.py index 486795b..7491830 100644 --- a/mods/clone/clone_manager.py +++ b/mods/clone/clone_manager.py @@ -10,7 +10,7 @@ class CloneManager: def __init__(self, uplink: 'Clone'): - self.Logs = uplink.Logs + self.Logs = uplink.ctx.Logs def insert(self, new_clone_object: MClone) -> bool: """Create new Clone object diff --git a/mods/clone/mod_clone.py b/mods/clone/mod_clone.py index 999dd3b..6ae6084 100644 --- a/mods/clone/mod_clone.py +++ b/mods/clone/mod_clone.py @@ -8,6 +8,7 @@ from mods.clone.clone_manager import CloneManager if TYPE_CHECKING: from faker import Faker + from core.loader import Loader class Clone(IModule): @@ -23,7 +24,15 @@ class Clone(IModule): 'core_version':'Defender-6' } - def create_tables(self) -> None: + def __init__(self, context: 'Loader') -> None: + super().__init__(context) + self._mod_config: Optional[schemas.ModConfModel] = None + + @property + def mod_config(self) -> ModConfModel: + return self._mod_config + + async def create_tables(self) -> None: """Methode qui va créer la base de donnée si elle n'existe pas. Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module @@ -39,63 +48,69 @@ class Clone(IModule): ) ''' - # self.Base.db_execute_query(table_channel) + # await self.ctx.Base.db_execute_query(table_channel) return None - def load(self) -> None: - self.ModConfig = self.ModConfModel() + async def load(self) -> None: + + # Variable qui va contenir les options de configuration du module Defender + self._mod_config: schemas.ModConfModel = self.ModConfModel() + + # sync the database with local variable (Mandatory) + await self.sync_db() + self.stop = False self.Schemas = schemas self.Utils = utils self.Threads = thds self.Faker: Optional['Faker'] = self.Utils.create_faker_object('en_GB') self.Clone = CloneManager(self) - metadata = self.Settings.get_cache('UID_CLONE_DB') + metadata = self.ctx.Settings.get_cache('UID_CLONE_DB') if metadata is not None: self.Clone.UID_CLONE_DB = metadata - self.Logs.debug(f"Cache Size = {self.Settings.get_cache_size()}") + self.ctx.Logs.debug(f"Cache Size = {self.ctx.Settings.get_cache_size()}") # Créer les nouvelles commandes du module - self.Irc.build_command(1, self.module_name, 'clone', 'Connect, join, part, kill and say clones') + self.ctx.Irc.build_command(1, self.module_name, 'clone', 'Connect, join, part, kill and say clones') - self.Channel.db_query_channel(action='add', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_sjoin(self.Config.CLONE_CHANNEL) - self.Protocol.send_set_mode('+o', nickname=self.Config.SERVICE_NICKNAME, channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_set_mode('+nts', channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_set_mode('+k', channel_name=self.Config.CLONE_CHANNEL, params=self.Config.CLONE_CHANNEL_PASSWORD) + await self.ctx.Channel.db_query_channel(action='add', module_name=self.module_name, channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_sjoin(self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_set_mode('+o', nickname=self.ctx.Config.SERVICE_NICKNAME, channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_set_mode('+nts', channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_set_mode('+k', channel_name=self.ctx.Config.CLONE_CHANNEL, params=self.ctx.Config.CLONE_CHANNEL_PASSWORD) - def unload(self) -> None: + async def unload(self) -> None: """Cette methode sera executée a chaque désactivation ou rechargement de module """ # Store Clones DB into the global Settings to retrieve it after the reload. - self.Settings.set_cache('UID_CLONE_DB', self.Clone.UID_CLONE_DB) + self.ctx.Settings.set_cache('UID_CLONE_DB', self.Clone.UID_CLONE_DB) - self.Channel.db_query_channel(action='del', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_set_mode('-nts', channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_set_mode('-k', channel_name=self.Config.CLONE_CHANNEL) - self.Protocol.send_part_chan(self.Config.SERVICE_NICKNAME, self.Config.CLONE_CHANNEL) + await self.ctx.Channel.db_query_channel(action='del', module_name=self.module_name, channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_set_mode('-nts', channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_set_mode('-k', channel_name=self.ctx.Config.CLONE_CHANNEL) + await self.ctx.Irc.Protocol.send_part_chan(self.ctx.Config.SERVICE_NICKNAME, self.ctx.Config.CLONE_CHANNEL) - self.Irc.Commands.drop_command_by_module(self.module_name) + self.ctx.Commands.drop_command_by_module(self.module_name) return None - def cmd(self, data:list) -> None: + async def cmd(self, data:list) -> None: try: if not data or len(data) < 2: return None cmd = data.copy() if isinstance(data, list) else list(data).copy() - index, command = self.Irc.Protocol.get_ircd_protocol_poisition(cmd) + index, command = self.ctx.Irc.Protocol.get_ircd_protocol_poisition(cmd) if index == -1: return None match command: case 'PRIVMSG': - self.Utils.handle_on_privmsg(self, cmd) + await self.Utils.handle_on_privmsg(self, cmd) return None case 'QUIT': @@ -105,10 +120,10 @@ class Clone(IModule): return None except Exception as err: - self.Logs.error(f'General Error: {err}', exc_info=True) + self.ctx.Logs.error(f'General Error: {err}', exc_info=True) return None - def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None: + async def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None: try: @@ -117,18 +132,18 @@ class Clone(IModule): command = str(cmd[0]).lower() fromuser = user - dnickname = self.Config.SERVICE_NICKNAME + dnickname = self.ctx.Config.SERVICE_NICKNAME match command: case 'clone': - if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group_name | nickname]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group_name | nickname] #channel") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group_name | nickname] #channel") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]") + if len(cmd) < 2: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group_name | nickname]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group_name | nickname] #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group_name | nickname] #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]") return None option = str(cmd[1]).lower() @@ -143,15 +158,13 @@ class Clone(IModule): group = str(cmd[3]).lower() connection_interval = int(cmd[4]) if len(cmd) == 5 else 0.2 - self.Base.create_thread( - func=self.Threads.thread_connect_clones, - func_args=(self, number_of_clones, group, False, connection_interval) + self.ctx.Base.create_asynctask( + func=self.Threads.coro_connect_clones(self, number_of_clones, group, False, connection_interval) ) - except Exception as err: - self.Logs.error(f'{err}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect [number of clone you want to connect] [Group] [freq]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Exemple /msg {dnickname} clone connect 6 Ambiance") + except IndexError: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect [number of clone you want to connect] [Group] [freq]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Exemple /msg {dnickname} clone connect 6 Ambiance") case 'kill': try: @@ -160,27 +173,26 @@ class Clone(IModule): option = str(cmd[2]) if option.lower() == 'all': - self.Base.create_thread(func=self.Threads.thread_kill_clones, func_args=(self, )) + self.ctx.Base.create_asynctask(func=self.Threads.thread_kill_clones(self)) elif self.Clone.group_exists(option): list_of_clones_in_group = self.Clone.get_clones_from_groupname(option) if len(list_of_clones_in_group) > 0: - self.Logs.debug(f"[Clone Kill Group] - Killing {len(list_of_clones_in_group)} clones in the group {option}") + self.ctx.Logs.debug(f"[Clone Kill Group] - Killing {len(list_of_clones_in_group)} clones in the group {option}") for clone in list_of_clones_in_group: - self.Protocol.send_quit(clone.uid, "Now i am leaving irc but i'll come back soon ...", print_log=False) + await self.ctx.Irc.Protocol.send_quit(clone.uid, "Now i am leaving irc but i'll come back soon ...", print_log=False) self.Clone.delete(clone.uid) else: clone_obj = self.Clone.get_clone(option) if not clone_obj is None: - self.Protocol.send_quit(clone_obj.uid, 'Goood bye', print_log=False) + await self.ctx.Irc.Protocol.send_quit(clone_obj.uid, 'Goood bye', print_log=False) self.Clone.delete(clone_obj.uid) - except Exception as err: - self.Logs.error(f'{err}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]") + except IndexError: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]") case 'join': try: @@ -191,25 +203,24 @@ class Clone(IModule): if option.lower() == 'all': for clone in self.Clone.UID_CLONE_DB: - self.Protocol.send_join_chan(uidornickname=clone.uid, channel=clone_channel_to_join, print_log=False) + await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.uid, channel=clone_channel_to_join, print_log=False) elif self.Clone.group_exists(option): list_of_clones_in_group = self.Clone.get_clones_from_groupname(option) if len(list_of_clones_in_group) > 0: - self.Logs.debug(f"[Clone Join Group] - Joining {len(list_of_clones_in_group)} clones from group {option} in the channel {clone_channel_to_join}") + self.ctx.Logs.debug(f"[Clone Join Group] - Joining {len(list_of_clones_in_group)} clones from group {option} in the channel {clone_channel_to_join}") for clone in list_of_clones_in_group: - self.Protocol.send_join_chan(uidornickname=clone.nickname, channel=clone_channel_to_join, print_log=False) + await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.nickname, channel=clone_channel_to_join, print_log=False) else: if self.Clone.nickname_exists(option): clone_uid = self.Clone.get_clone(option).uid - self.Protocol.send_join_chan(uidornickname=clone_uid, channel=clone_channel_to_join, print_log=False) + await self.ctx.Irc.Protocol.send_join_chan(uidornickname=clone_uid, channel=clone_channel_to_join, print_log=False) - except Exception as err: - self.Logs.error(f'{err}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel") + except IndexError: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel") case 'part': try: @@ -220,67 +231,66 @@ class Clone(IModule): if option.lower() == 'all': for clone in self.Clone.UID_CLONE_DB: - self.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False) + await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False) elif self.Clone.group_exists(option): list_of_clones_in_group = self.Clone.get_clones_from_groupname(option) if len(list_of_clones_in_group) > 0: - self.Logs.debug(f"[Clone Part Group] - Part {len(list_of_clones_in_group)} clones from group {option} from the channel {clone_channel_to_part}") + self.ctx.Logs.debug(f"[Clone Part Group] - Part {len(list_of_clones_in_group)} clones from group {option} from the channel {clone_channel_to_part}") for clone in list_of_clones_in_group: - self.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False) + await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone.uid, channel=clone_channel_to_part, print_log=False) else: if self.Clone.nickname_exists(option): clone_uid = self.Clone.get_uid(option) if not clone_uid is None: - self.Protocol.send_part_chan(uidornickname=clone_uid, channel=clone_channel_to_part, print_log=False) + await self.ctx.Irc.Protocol.send_part_chan(uidornickname=clone_uid, channel=clone_channel_to_part, print_log=False) - except Exception as err: - self.Logs.error(f'{err}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel") + except IndexError: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel") case 'list': try: # Syntax. /msg defender clone list header = f" {'Nickname':<12}| {'Real name':<25}| {'Group name':<15}| {'Connected':<35}" line = "-"*67 - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=header) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=header) + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") group_name = cmd[2] if len(cmd) > 2 else None if group_name is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(self.Clone.UID_CLONE_DB)}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(self.Clone.UID_CLONE_DB)}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") for clone_name in self.Clone.UID_CLONE_DB: - self.Protocol.send_notice( + await self.ctx.Irc.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f" {clone_name.nickname:<12}| {clone_name.realname:<25}| {clone_name.group:<15}| {clone_name.connected:<35}") else: if not self.Clone.group_exists(group_name): - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="This Group name doesn't exist!") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="This Group name doesn't exist!") return None clones = self.Clone.get_clones_from_groupname(group_name) - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(clones)}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Number of connected clones: {len(clones)}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {line}") for clone in clones: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {clone.nickname:<12}| {clone.realname:<25}| {clone.group:<15}| {clone.connected:<35}") - except Exception as err: - self.Logs.error(f'{err}') + except IndexError: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]") case 'say': try: # clone say clone_nickname #channel message clone_name = str(cmd[2]) - clone_channel = str(cmd[3]) if self.Channel.is_valid_channel(str(cmd[3])) else None + clone_channel = str(cmd[3]) if self.ctx.Channel.is_valid_channel(str(cmd[3])) else None final_message = ' '.join(cmd[4:]) if clone_channel is None or not self.Clone.nickname_exists(clone_name): - self.Protocol.send_notice( + await self.ctx.Irc.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone say [clone_nickname] #channel message" @@ -288,24 +298,21 @@ class Clone(IModule): return None if self.Clone.nickname_exists(clone_name): - self.Protocol.send_priv_msg(nick_from=clone_name, msg=final_message, channel=clone_channel) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=clone_name, msg=final_message, channel=clone_channel) - except Exception as err: - self.Logs.error(f'{err}') - self.Protocol.send_notice( + except IndexError: + await self.ctx.Irc.Protocol.send_notice( nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone say [clone_nickname] #channel message" ) case _: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone connect NUMBER GROUP_NAME INTERVAL") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone kill [all | group name | nickname]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone join [all | group name | nickname] #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone part [all | group name | nickname] #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} clone list [group name]") - except IndexError as ie: - self.Logs.error(f'Index Error: {ie}') except Exception as err: - self.Logs.error(f'General Error: {err}') + self.ctx.Logs.error(f'General Error: {err}', exc_info=True) diff --git a/mods/clone/threads.py b/mods/clone/threads.py index c8c216a..e078a05 100644 --- a/mods/clone/threads.py +++ b/mods/clone/threads.py @@ -1,10 +1,11 @@ +import asyncio from typing import TYPE_CHECKING from time import sleep if TYPE_CHECKING: from mods.clone.mod_clone import Clone -def thread_connect_clones(uplink: 'Clone', +async def coro_connect_clones(uplink: 'Clone', number_of_clones:int , group: str = 'Default', auto_remote_ip: bool = False, @@ -27,18 +28,18 @@ def thread_connect_clones(uplink: 'Clone', break if not clone.connected: - uplink.Protocol.send_uid(clone.nickname, clone.username, clone.hostname, clone.uid, clone.umodes, clone.vhost, clone.remote_ip, clone.realname, print_log=False) - uplink.Protocol.send_join_chan(uidornickname=clone.uid, channel=uplink.Config.CLONE_CHANNEL, password=uplink.Config.CLONE_CHANNEL_PASSWORD, print_log=False) + await uplink.ctx.Irc.Protocol.send_uid(clone.nickname, clone.username, clone.hostname, clone.uid, clone.umodes, clone.vhost, clone.remote_ip, clone.realname, print_log=False) + await uplink.ctx.Irc.Protocol.send_join_chan(uidornickname=clone.uid, channel=uplink.ctx.Config.CLONE_CHANNEL, password=uplink.ctx.Config.CLONE_CHANNEL_PASSWORD, print_log=False) - sleep(interval) + await asyncio.sleep(interval) clone.connected = True -def thread_kill_clones(uplink: 'Clone'): +async def thread_kill_clones(uplink: 'Clone'): clone_to_kill = uplink.Clone.UID_CLONE_DB.copy() for clone in clone_to_kill: - uplink.Protocol.send_quit(clone.uid, 'Gooood bye', print_log=False) + await uplink.ctx.Irc.Protocol.send_quit(clone.uid, 'Gooood bye', print_log=False) uplink.Clone.delete(clone.uid) del clone_to_kill diff --git a/mods/clone/utils.py b/mods/clone/utils.py index b371ea1..4b03bb3 100644 --- a/mods/clone/utils.py +++ b/mods/clone/utils.py @@ -125,8 +125,8 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def """ faker = faker_instance - uid = generate_uid_for_clone(faker, uplink.Config.SERVEUR_ID) - umodes = uplink.Config.CLONE_UMODES + uid = generate_uid_for_clone(faker, uplink.ctx.Config.SERVEUR_ID) + umodes = uplink.ctx.Config.CLONE_UMODES # Generate Username username = generate_username_for_clone(faker) @@ -153,7 +153,7 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def checkNickname = uplink.Clone.nickname_exists(nickname) while checkUid: - uid = generate_uid_for_clone(faker, uplink.Config.SERVEUR_ID) + uid = generate_uid_for_clone(faker, uplink.ctx.Config.SERVEUR_ID) checkUid = uplink.Clone.uid_exists(uid=uid) clone = uplink.Schemas.MClone( @@ -174,12 +174,12 @@ def create_new_clone(uplink: 'Clone', faker_instance: 'Faker', group: str = 'Def return True -def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None: +async def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None: - senderObj, recieverObj, channel, message = uplink.Protocol.parse_privmsg(srvmsg) + senderObj, recieverObj, channel, message = uplink.ctx.Irc.Protocol.parse_privmsg(srvmsg) if senderObj is not None: - if senderObj.hostname in uplink.Config.CLONE_LOG_HOST_EXEMPT: + if senderObj.hostname in uplink.ctx.Config.CLONE_LOG_HOST_EXEMPT: return senderMsg = message clone_obj = recieverObj @@ -187,12 +187,12 @@ def handle_on_privmsg(uplink: 'Clone', srvmsg: list[str]) -> None: if clone_obj is None: return - if clone_obj.uid != uplink.Config.SERVICE_ID: + if clone_obj.uid != uplink.ctx.Config.SERVICE_ID: final_message = f"{senderObj.nickname}!{senderObj.username}@{senderObj.hostname} > {senderMsg.lstrip(':')}" - uplink.Protocol.send_priv_msg( + await uplink.ctx.Irc.Protocol.send_priv_msg( nick_from=clone_obj.uid, msg=final_message, - channel=uplink.Config.CLONE_CHANNEL + channel=uplink.ctx.Config.CLONE_CHANNEL ) return None diff --git a/mods/command/mod_command.py b/mods/command/mod_command.py index 083b199..f7a7aaa 100644 --- a/mods/command/mod_command.py +++ b/mods/command/mod_command.py @@ -5,6 +5,7 @@ import mods.command.utils as utils if TYPE_CHECKING: from core.definition import MUser + from core.loader import Loader class Command(IModule): @@ -22,6 +23,14 @@ class Command(IModule): 'core_version':'Defender-6' } + def __init__(self, uplink: 'Loader'): + super().__init__(uplink) + self._mod_config: Optional[Command.ModConfModel] = self.ModConfModel() + + @property + def mod_config(self) -> ModConfModel: + return self._mod_config + def create_tables(self) -> None: """Methode qui va créer la base de donnée si elle n'existe pas. Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module @@ -42,91 +51,87 @@ class Command(IModule): ) ''' - self.Base.db_execute_query(table_automode) + self.ctx.Base.db_execute_query(table_automode) return None def load(self) -> None: # Module Utils self.mod_utils = utils - - # Build the default configuration model (Mandatory) - self.ModConfig = self.ModConfModel() - self.user_to_notice: str = '' self.show_219: bool = True # Register new commands into the protocol new_cmds = {'403', '401', '006', '018', '219', '223'} for c in new_cmds: - self.Irc.Protocol.known_protocol.add(c) + self.ctx.Irc.Protocol.known_protocol.add(c) - self.Irc.build_command(2, self.module_name, 'join', 'Join a channel') - self.Irc.build_command(2, self.module_name, 'assign', 'Assign a user to a role or task') - self.Irc.build_command(2, self.module_name, 'part', 'Leave a channel') - self.Irc.build_command(2, self.module_name, 'unassign', 'Remove a user from a role or task') - self.Irc.build_command(2, self.module_name, 'owner', 'Give channel ownership to a user') - self.Irc.build_command(2, self.module_name, 'deowner', 'Remove channel ownership from a user') - self.Irc.build_command(2, self.module_name, 'protect', 'Protect a user from being kicked') - self.Irc.build_command(2, self.module_name, 'deprotect', 'Remove protection from a user') - self.Irc.build_command(2, self.module_name, 'op', 'Grant operator privileges to a user') - self.Irc.build_command(2, self.module_name, 'deop', 'Remove operator privileges from a user') - self.Irc.build_command(1, self.module_name, 'halfop', 'Grant half-operator privileges to a user') - self.Irc.build_command(1, self.module_name, 'dehalfop', 'Remove half-operator privileges from a user') - self.Irc.build_command(1, self.module_name, 'voice', 'Grant voice privileges to a user') - self.Irc.build_command(1, self.module_name, 'devoice', 'Remove voice privileges from a user') - self.Irc.build_command(1, self.module_name, 'topic', 'Change the topic of a channel') - self.Irc.build_command(2, self.module_name, 'opall', 'Grant operator privileges to all users') - self.Irc.build_command(2, self.module_name, 'deopall', 'Remove operator privileges from all users') - self.Irc.build_command(2, self.module_name, 'devoiceall', 'Remove voice privileges from all users') - self.Irc.build_command(2, self.module_name, 'voiceall', 'Grant voice privileges to all users') - self.Irc.build_command(2, self.module_name, 'ban', 'Ban a user from a channel') - self.Irc.build_command(2, self.module_name, 'automode', 'Automatically set user modes upon join') - self.Irc.build_command(2, self.module_name, 'unban', 'Remove a ban from a user') - self.Irc.build_command(2, self.module_name, 'kick', 'Kick a user from a channel') - self.Irc.build_command(2, self.module_name, 'kickban', 'Kick and ban a user from a channel') - self.Irc.build_command(2, self.module_name, 'umode', 'Set user mode') - self.Irc.build_command(2, self.module_name, 'mode', 'Set channel mode') - self.Irc.build_command(2, self.module_name, 'get_mode', 'Retrieve current channel mode') - self.Irc.build_command(2, self.module_name, 'svsjoin', 'Force a user to join a channel') - self.Irc.build_command(2, self.module_name, 'svspart', 'Force a user to leave a channel') - self.Irc.build_command(2, self.module_name, 'svsnick', 'Force a user to change their nickname') - self.Irc.build_command(2, self.module_name, 'wallops', 'Send a message to all operators') - self.Irc.build_command(2, self.module_name, 'globops', 'Send a global operator message') - self.Irc.build_command(2, self.module_name, 'gnotice', 'Send a global notice') - self.Irc.build_command(2, self.module_name, 'whois', 'Get information about a user') - self.Irc.build_command(2, self.module_name, 'names', 'List users in a channel') - self.Irc.build_command(2, self.module_name, 'invite', 'Invite a user to a channel') - self.Irc.build_command(2, self.module_name, 'inviteme', 'Invite yourself to a channel') - self.Irc.build_command(2, self.module_name, 'sajoin', 'Force yourself into a channel') - self.Irc.build_command(2, self.module_name, 'sapart', 'Force yourself to leave a channel') - self.Irc.build_command(2, self.module_name, 'kill', 'Disconnect a user from the server') - self.Irc.build_command(2, self.module_name, 'gline', 'Ban a user from the entire server') - self.Irc.build_command(2, self.module_name, 'ungline', 'Remove a global server ban') - self.Irc.build_command(2, self.module_name, 'kline', 'Ban a user based on their hostname') - self.Irc.build_command(2, self.module_name, 'unkline', 'Remove a K-line ban') - self.Irc.build_command(2, self.module_name, 'shun', 'Prevent a user from sending messages') - self.Irc.build_command(2, self.module_name, 'unshun', 'Remove a shun from a user') - self.Irc.build_command(2, self.module_name, 'glinelist', 'List all global bans') - self.Irc.build_command(2, self.module_name, 'shunlist', 'List all shunned users') - self.Irc.build_command(2, self.module_name, 'klinelist', 'List all K-line bans') - self.Irc.build_command(3, self.module_name, 'map', 'Show the server network map') + self.ctx.Irc.build_command(2, self.module_name, 'join', 'Join a channel') + self.ctx.Irc.build_command(2, self.module_name, 'assign', 'Assign a user to a role or task') + self.ctx.Irc.build_command(2, self.module_name, 'part', 'Leave a channel') + self.ctx.Irc.build_command(2, self.module_name, 'unassign', 'Remove a user from a role or task') + self.ctx.Irc.build_command(2, self.module_name, 'owner', 'Give channel ownership to a user') + self.ctx.Irc.build_command(2, self.module_name, 'deowner', 'Remove channel ownership from a user') + self.ctx.Irc.build_command(2, self.module_name, 'protect', 'Protect a user from being kicked') + self.ctx.Irc.build_command(2, self.module_name, 'deprotect', 'Remove protection from a user') + self.ctx.Irc.build_command(2, self.module_name, 'op', 'Grant operator privileges to a user') + self.ctx.Irc.build_command(2, self.module_name, 'deop', 'Remove operator privileges from a user') + self.ctx.Irc.build_command(1, self.module_name, 'halfop', 'Grant half-operator privileges to a user') + self.ctx.Irc.build_command(1, self.module_name, 'dehalfop', 'Remove half-operator privileges from a user') + self.ctx.Irc.build_command(1, self.module_name, 'voice', 'Grant voice privileges to a user') + self.ctx.Irc.build_command(1, self.module_name, 'devoice', 'Remove voice privileges from a user') + self.ctx.Irc.build_command(1, self.module_name, 'topic', 'Change the topic of a channel') + self.ctx.Irc.build_command(2, self.module_name, 'opall', 'Grant operator privileges to all users') + self.ctx.Irc.build_command(2, self.module_name, 'deopall', 'Remove operator privileges from all users') + self.ctx.Irc.build_command(2, self.module_name, 'devoiceall', 'Remove voice privileges from all users') + self.ctx.Irc.build_command(2, self.module_name, 'voiceall', 'Grant voice privileges to all users') + self.ctx.Irc.build_command(2, self.module_name, 'ban', 'Ban a user from a channel') + self.ctx.Irc.build_command(2, self.module_name, 'automode', 'Automatically set user modes upon join') + self.ctx.Irc.build_command(2, self.module_name, 'unban', 'Remove a ban from a user') + self.ctx.Irc.build_command(2, self.module_name, 'kick', 'Kick a user from a channel') + self.ctx.Irc.build_command(2, self.module_name, 'kickban', 'Kick and ban a user from a channel') + self.ctx.Irc.build_command(2, self.module_name, 'umode', 'Set user mode') + self.ctx.Irc.build_command(2, self.module_name, 'mode', 'Set channel mode') + self.ctx.Irc.build_command(2, self.module_name, 'get_mode', 'Retrieve current channel mode') + self.ctx.Irc.build_command(2, self.module_name, 'svsjoin', 'Force a user to join a channel') + self.ctx.Irc.build_command(2, self.module_name, 'svspart', 'Force a user to leave a channel') + self.ctx.Irc.build_command(2, self.module_name, 'svsnick', 'Force a user to change their nickname') + self.ctx.Irc.build_command(2, self.module_name, 'wallops', 'Send a message to all operators') + self.ctx.Irc.build_command(2, self.module_name, 'globops', 'Send a global operator message') + self.ctx.Irc.build_command(2, self.module_name, 'gnotice', 'Send a global notice') + self.ctx.Irc.build_command(2, self.module_name, 'whois', 'Get information about a user') + self.ctx.Irc.build_command(2, self.module_name, 'names', 'List users in a channel') + self.ctx.Irc.build_command(2, self.module_name, 'invite', 'Invite a user to a channel') + self.ctx.Irc.build_command(2, self.module_name, 'inviteme', 'Invite yourself to a channel') + self.ctx.Irc.build_command(2, self.module_name, 'sajoin', 'Force yourself into a channel') + self.ctx.Irc.build_command(2, self.module_name, 'sapart', 'Force yourself to leave a channel') + self.ctx.Irc.build_command(2, self.module_name, 'kill', 'Disconnect a user from the server') + self.ctx.Irc.build_command(2, self.module_name, 'gline', 'Ban a user from the entire server') + self.ctx.Irc.build_command(2, self.module_name, 'ungline', 'Remove a global server ban') + self.ctx.Irc.build_command(2, self.module_name, 'kline', 'Ban a user based on their hostname') + self.ctx.Irc.build_command(2, self.module_name, 'unkline', 'Remove a K-line ban') + self.ctx.Irc.build_command(2, self.module_name, 'shun', 'Prevent a user from sending messages') + self.ctx.Irc.build_command(2, self.module_name, 'unshun', 'Remove a shun from a user') + self.ctx.Irc.build_command(2, self.module_name, 'glinelist', 'List all global bans') + self.ctx.Irc.build_command(2, self.module_name, 'shunlist', 'List all shunned users') + self.ctx.Irc.build_command(2, self.module_name, 'klinelist', 'List all K-line bans') + self.ctx.Irc.build_command(3, self.module_name, 'map', 'Show the server network map') def unload(self) -> None: - self.Irc.Commands.drop_command_by_module(self.module_name) + self.ctx.Commands.drop_command_by_module(self.module_name) return None - def cmd(self, data: list[str]) -> None: + async def cmd(self, data: list[str]) -> None: try: - # service_id = self.Config.SERVICE_ID - dnickname = self.Config.SERVICE_NICKNAME - # dchanlog = self.Config.SERVICE_CHANLOG - red = self.Config.COLORS.red - green = self.Config.COLORS.green - bold = self.Config.COLORS.bold - nogc = self.Config.COLORS.nogc + # service_id = self.ctx.Config.SERVICE_ID + dnickname = self.ctx.Config.SERVICE_NICKNAME + # dchanlog = self.ctx.Config.SERVICE_CHANLOG + red = self.ctx.Config.COLORS.red + green = self.ctx.Config.COLORS.green + bold = self.ctx.Config.COLORS.bold + nogc = self.ctx.Config.COLORS.nogc cmd = list(data).copy() - pos, parsed_cmd = self.Irc.Protocol.get_ircd_protocol_poisition(cmd=cmd, log=True) + pos, parsed_cmd = self.ctx.Irc.Protocol.get_ircd_protocol_poisition(cmd=cmd, log=True) if pos == -1: return None @@ -136,31 +141,31 @@ class Command(IModule): case '403' | '401': try: message = ' '.join(cmd[3:]) - self.Protocol.send_notice( + await self.ctx.Irc.Protocol.send_notice( nick_from=dnickname, nick_to=self.user_to_notice, msg=f"[{red}ERROR MSG{nogc}] {message}" ) - self.Logs.error(f"{cmd[1]} - {message}") + self.ctx.Logs.error(f"{cmd[1]} - {message}") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case '006' | '018': try: # [':irc.deb.biz.st', '006', 'Dev-PyDefender', ':`-services.deb.biz.st', '------', '|', 'Users:', '9', '(47.37%)', '[00B]'] # [':irc.deb.biz.st', '018', 'Dev-PyDefender', ':4', 'servers', 'and', '19', 'users,', 'average', '4.75', 'users', 'per', 'server'] message = ' '.join(cmd[3:]) - self.Protocol.send_notice( + await self.ctx.Irc.Protocol.send_notice( nick_from=dnickname, nick_to=self.user_to_notice, msg=f"[{green}SERVER MSG{nogc}] {message}" ) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case '219': try: @@ -174,16 +179,16 @@ class Command(IModule): match type_of_stats: case 's': - self.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No shun") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No shun") case 'G': - self.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No gline") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No gline") case 'k': - self.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No kline") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg="No kline") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case '223': try: @@ -193,23 +198,23 @@ class Command(IModule): author = str(cmd[7]) reason = ' '.join(cmd[8:]) - self.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname,nick_to=self.user_to_notice, msg=f"{bold}Author{nogc}: {author} - {bold}Host{nogc}: {host} - {bold}Reason{nogc}: {reason}" ) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'SJOIN': # ['@msgid=yldTlbwAGbzCGUcCIHi3ku;time=2024-11-11T17:56:24.297Z', ':001', 'SJOIN', '1728815963', '#znc', ':001LQ0L0C'] # Check if the user has an automode try: - user_uid = self.User.clean_uid(cmd[5]) - userObj: MUser = self.User.get_user(user_uid) - channel_name = cmd[4] if self.Channel.is_valid_channel(cmd[4]) else None - client_obj = self.Client.get_Client(user_uid) + user_uid = self.ctx.User.clean_uid(cmd[5]) + userObj: MUser = self.ctx.User.get_user(user_uid) + channel_name = cmd[4] if self.ctx.Channel.is_valid_channel(cmd[4]) else None + client_obj = self.ctx.Client.get_Client(user_uid) nickname = userObj.nickname if userObj is not None else None if client_obj is not None: @@ -218,31 +223,31 @@ class Command(IModule): if userObj is None: return None - if 'r' not in userObj.umodes and 'o' not in userObj.umodes and not self.Client.is_exist(userObj.uid): + if 'r' not in userObj.umodes and 'o' not in userObj.umodes and not self.ctx.Client.is_exist(userObj.uid): return None db_data: dict[str, str] = {"nickname": nickname.lower(), "channel": channel_name.lower()} - db_query = self.Base.db_execute_query("SELECT id, mode FROM command_automode WHERE LOWER(nickname) = :nickname AND LOWER(channel) = :channel", db_data) + db_query = await self.ctx.Base.db_execute_query("SELECT id, mode FROM command_automode WHERE LOWER(nickname) = :nickname AND LOWER(channel) = :channel", db_data) db_result = db_query.fetchone() if db_result: id, mode = db_result - self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {channel_name} {mode} {userObj.nickname}") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVICE_ID} MODE {channel_name} {mode} {userObj.nickname}") except KeyError as ke: - self.Logs.error(f"Key Error: {err}") + self.ctx.Logs.error(f"Key Error: {err}") case _: pass except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}", exc_info=True) - def hcmds(self, uidornickname: str, channel_name: Optional[str], cmd: list, fullcmd: list = []): + async def hcmds(self, uidornickname: str, channel_name: Optional[str], cmd: list, fullcmd: list = []): command = str(cmd[0]).lower() - dnickname = self.Config.SERVICE_NICKNAME - service_id = self.Config.SERVICE_ID - dchanlog = self.Config.SERVICE_CHANLOG + dnickname = self.ctx.Config.SERVICE_NICKNAME + service_id = self.ctx.Config.SERVICE_ID + dchanlog = self.ctx.Config.SERVICE_CHANLOG self.user_to_notice = uidornickname fromuser = uidornickname fromchannel = channel_name @@ -251,365 +256,365 @@ class Command(IModule): case 'automode': try: - self.mod_utils.set_automode(self, cmd, fromuser) + await self.mod_utils.set_automode(self, cmd, fromuser) except IndexError: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(self.Loader.Settings.PROTOCTL_PREFIX)}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(self.ctx.Settings.PROTOCTL_PREFIX)}") except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}") case 'deopall': try: - self.mod_utils.set_deopall(self, fromchannel) + await self.mod_utils.set_deopall(self, fromchannel) except Exception as err: - self.Logs.error(f'Unknown Error: {str(err)}') + self.ctx.Logs.error(f'Unknown Error: {str(err)}') case 'devoiceall': try: - self.mod_utils.set_devoiceall(self, fromchannel) + await self.mod_utils.set_devoiceall(self, fromchannel) except Exception as err: - self.Logs.error(f'Unknown Error: {str(err)}') + self.ctx.Logs.error(f'Unknown Error: {str(err)}') case 'voiceall': try: - self.mod_utils.set_mode_to_all(self, fromchannel, '+', 'v') + await self.mod_utils.set_mode_to_all(self, fromchannel, '+', 'v') except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'opall': try: - self.mod_utils.set_mode_to_all(self, fromchannel, '+', 'o') + await self.mod_utils.set_mode_to_all(self, fromchannel, '+', 'o') except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'op': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+o') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+o') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} op [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} op [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'deop': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-o') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-o') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} deop [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} deop [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'owner': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+q') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+q') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} owner [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} owner [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'deowner': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-q') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-q') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} deowner [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} deowner [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'protect': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+a') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+a') except IndexError as e: - self.Logs.warning(f'_hcmd DEOWNER: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") + self.ctx.Logs.warning(f'_hcmd DEOWNER: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'deprotect': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-a') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-a') except IndexError as e: - self.Logs.warning(f'_hcmd DEOWNER: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") + self.ctx.Logs.warning(f'_hcmd DEOWNER: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'halfop': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+h') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+h') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'dehalfop': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-h') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-h') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} dehalfop [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} dehalfop [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'voice': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+v') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '+v') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} voice [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} voice [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'devoice': try: - self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-v') + await self.mod_utils.set_operation(self, cmd, fromchannel, fromuser, '-v') except IndexError as e: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} devoice [#SALON] [NICKNAME]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} devoice [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'ban': try: - self.mod_utils.set_ban(self, cmd, '+', fromuser) + await self.mod_utils.set_ban(self, cmd, '+', fromuser) except IndexError as e: - self.Logs.warning(f'_hcmd BAN: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") + self.ctx.Logs.warning(f'_hcmd BAN: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'unban': try: - self.mod_utils.set_ban(self, cmd, '-', fromuser) + await self.mod_utils.set_ban(self, cmd, '-', fromuser) except IndexError as e: - self.Logs.warning(f'_hcmd UNBAN: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") + self.ctx.Logs.warning(f'_hcmd UNBAN: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'kick': try: - self.mod_utils.set_kick(self, cmd, fromuser) + await self.mod_utils.set_kick(self, cmd, fromuser) except IndexError as e: - self.Logs.warning(f'_hcmd KICK: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME] [REASON]") + self.ctx.Logs.warning(f'_hcmd KICK: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME] [REASON]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'kickban': try: - self.mod_utils.set_kickban(self, cmd, fromuser) + await self.mod_utils.set_kickban(self, cmd, fromuser) except IndexError as e: - self.Logs.warning(f'_hcmd KICKBAN: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME] [REASON]") + self.ctx.Logs.warning(f'_hcmd KICKBAN: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME] [REASON]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'join' | 'assign': try: - self.mod_utils.set_assign_channel_to_service(self, cmd, fromuser) + await self.mod_utils.set_assign_channel_to_service(self, cmd, fromuser) except IndexError as ie: - self.Logs.debug(f'{ie}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") + self.ctx.Logs.debug(f'{ie}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'part' | 'unassign': try: # Syntax. !part #channel - self.mod_utils.set_unassign_channel_to_service(self, cmd, fromuser) + await self.mod_utils.set_unassign_channel_to_service(self, cmd, fromuser) except IndexError as ie: - self.Logs.debug(f'{ie}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") + self.ctx.Logs.debug(f'{ie}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'topic': try: if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") return None chan = str(cmd[1]) - if not self.Channel.is_valid_channel(chan): - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") + if not self.ctx.Channel.is_valid_channel(chan): + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") return None topic_msg = ' '.join(cmd[2:]).strip() if topic_msg: - self.Protocol.send2socket(f':{dnickname} TOPIC {chan} :{topic_msg}') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} TOPIC {chan} :{topic_msg}') else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the topic") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the topic") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'wallops': try: if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} WALLOPS THE_WALLOPS_MESSAGE") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} WALLOPS THE_WALLOPS_MESSAGE") return None wallops_msg = ' '.join(cmd[1:]).strip() if wallops_msg: - self.Protocol.send2socket(f':{dnickname} WALLOPS {wallops_msg} ({dnickname})') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} WALLOPS {wallops_msg} ({dnickname})') else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the wallops message") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the wallops message") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'globops': try: if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} GLOBOPS THE_GLOBOPS_MESSAGE") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} GLOBOPS THE_GLOBOPS_MESSAGE") return None globops_msg = ' '.join(cmd[1:]).strip() if globops_msg: - self.Protocol.send2socket(f':{dnickname} GLOBOPS {globops_msg} ({dnickname})') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} GLOBOPS {globops_msg} ({dnickname})') else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the globops message") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the globops message") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'gnotice': try: if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} THE_GLOBAL_NOTICE_MESSAGE") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} THE_GLOBAL_NOTICE_MESSAGE") return None gnotice_msg = ' '.join(cmd[1:]).strip() if gnotice_msg: - self.Protocol.send_notice(nick_from=dnickname, nick_to='$*.*', msg=f"[{self.Config.COLORS.red}GLOBAL NOTICE{self.Config.COLORS.nogc}] {gnotice_msg}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to='$*.*', msg=f"[{self.ctx.Config.COLORS.red}GLOBAL NOTICE{self.ctx.Config.COLORS.nogc}] {gnotice_msg}") else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the global notice message") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the global notice message") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'whois': try: self.user_to_notice = fromuser if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME") return None nickname = str(cmd[1]) - if self.User.get_nickname(nickname) is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME") + if self.ctx.User.get_nickname(nickname) is None: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME") return None - self.Protocol.send2socket(f':{dnickname} WHOIS {nickname}') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} WHOIS {nickname}') except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'names': try: if len(cmd) == 1: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #CHANNEL") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #CHANNEL") return None chan = str(cmd[1]) - if not self.Channel.is_valid_channel(chan): - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel") + if not self.ctx.Channel.is_valid_channel(chan): + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel") return None - self.Protocol.send2socket(f':{dnickname} NAMES {chan}') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} NAMES {chan}') except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'invite': try: if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") return None nickname = str(cmd[1]) chan = str(cmd[2]) - if not self.Channel.is_valid_channel(chan): - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") + if not self.ctx.Channel.is_valid_channel(chan): + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") return None - if self.User.get_nickname(nickname) is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") + if self.ctx.User.get_nickname(nickname) is None: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") return None - self.Protocol.send2socket(f':{dnickname} INVITE {nickname} {chan}') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} INVITE {nickname} {chan}') except KeyError as ke: - self.Logs.error(f"KeyError: {ke}") + self.ctx.Logs.error(f"KeyError: {ke}") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'inviteme': try: if len(cmd) == 0: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()}") return None - self.Protocol.send2socket(f':{dnickname} INVITE {fromuser} {self.Config.SERVICE_CHANLOG}') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} INVITE {fromuser} {self.ctx.Config.SERVICE_CHANLOG}') except KeyError as ke: - self.Logs.error(f"KeyError: {ke}") + self.ctx.Logs.error(f"KeyError: {ke}") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'map': try: self.user_to_notice = fromuser - self.Protocol.send2socket(f':{dnickname} MAP') + await self.ctx.Irc.Protocol.send2socket(f':{dnickname} MAP') except KeyError as ke: - self.Logs.error(f"KeyError: {ke}") + self.ctx.Logs.error(f"KeyError: {ke}") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'umode': try: # .umode nickname +mode if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [NICKNAME] [+/-]mode") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [NICKNAME] [+/-]mode") return None nickname = str(cmd[1]) umode = str(cmd[2]) - self.Protocol.send_svsmode(nickname=nickname, user_mode=umode) + await self.ctx.Irc.Protocol.send_svsmode(nickname=nickname, user_mode=umode) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'mode': # .mode #channel +/-mode @@ -617,100 +622,100 @@ class Command(IModule): try: if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") return None if fromchannel is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") return None if len(cmd) == 2: channel_mode = cmd[1] - if self.Channel.is_valid_channel(fromchannel): - self.Protocol.send2socket(f":{dnickname} MODE {fromchannel} {channel_mode}") + if self.ctx.Channel.is_valid_channel(fromchannel): + await self.ctx.Irc.Protocol.send2socket(f":{dnickname} MODE {fromchannel} {channel_mode}") else: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : Channel [{fromchannel}] is not correct should start with #") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : Channel [{fromchannel}] is not correct should start with #") return None if len(cmd) == 3: provided_channel = cmd[1] channel_mode = cmd[2] - self.Protocol.send2socket(f":{service_id} MODE {provided_channel} {channel_mode}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {provided_channel} {channel_mode}") return None except IndexError as e: - self.Logs.warning(f'_hcmd OP: {str(e)}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") + self.ctx.Logs.warning(f'_hcmd OP: {str(e)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} {command.upper()} [#CHANNEL] [+/-]mode") except Exception as err: - self.Logs.warning(f'Unknown Error: {str(err)}') + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'get_mode': try: - self.Protocol.send2socket(f'MODE {fromchannel}') + await self.ctx.Irc.Protocol.send2socket(f'MODE {fromchannel}') except Exception as err: - self.Logs.error(f"General Error {err}") + self.ctx.Logs.error(f"General Error {err}") case 'svsjoin': try: # SVSJOIN [,..] [key1[,key2[..]]] if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") return None nickname = str(cmd[1]) channels = str(cmd[2]).split(',') keys = str(cmd[3]).split(',') - self.Protocol.send_svsjoin(nickname, channels, keys) + await self.ctx.Irc.Protocol.send_svsjoin(nickname, channels, keys) except IndexError as ke: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") - self.Logs.error(ke) + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSJOIN [,..] [key1[,key2[..]]]") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'svspart': try: # SVSPART [,..] [] if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") return None nickname = str(cmd[1]) channels = str(cmd[2]).split(',') reason = ' '.join(cmd[3:]) - self.Protocol.send_svspart(nickname, channels, reason) + await self.ctx.Irc.Protocol.send_svspart(nickname, channels, reason) except IndexError as ke: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") - self.Logs.error(ke) + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSPART [,..] []") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'svsnick': try: # .svsnick nickname newnickname nickname = str(cmd[1]) newnickname = str(cmd[2]) - unixtime = self.MainUtils.get_unixtime() + unixtime = self.ctx.Utils.get_unixtime() - if self.User.get_nickname(nickname) is None: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" This nickname do not exist") + if self.ctx.User.get_nickname(nickname) is None: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" This nickname do not exist") return None if len(cmd) != 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") return None - self.Protocol.send2socket(f':{self.Config.SERVEUR_ID} SVSNICK {nickname} {newnickname} {unixtime}') + await self.ctx.Irc.Protocol.send2socket(f':{self.ctx.Config.SERVEUR_ID} SVSNICK {nickname} {newnickname} {unixtime}') except IndexError as ke: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") - self.Logs.error(ke) + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname newnickname") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'sajoin': try: @@ -718,78 +723,78 @@ class Command(IModule): nickname = str(cmd[1]) channel = str(cmd[2]) if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") return None - self.Protocol.send_sajoin(nick_to_sajoin=nickname, channel_name=channel) + await self.ctx.Irc.Protocol.send_sajoin(nick_to_sajoin=nickname, channel_name=channel) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'sapart': try: # .sapart nickname #channel if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") return None nickname = str(cmd[1]) channel = str(cmd[2]) - self.Protocol.send_sapart(nick_to_sapart=nickname, channel_name=channel) + await self.ctx.Irc.Protocol.send_sapart(nick_to_sapart=nickname, channel_name=channel) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") - self.Logs.error(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") + self.ctx.Logs.error(f'Unknown Error: {str(err)}') case 'kill': try: # 'kill', 'gline', 'ungline', 'shun', 'unshun' # .kill nickname reason if len(cmd) < 3: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname reason") return None nickname = str(cmd[1]) kill_reason = ' '.join(cmd[2:]) - self.Protocol.send2socket(f":{service_id} KILL {nickname} {kill_reason} ({self.Config.COLORS.red}{dnickname}{self.Config.COLORS.nogc})") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} KILL {nickname} {kill_reason} ({self.ctx.Config.COLORS.red}{dnickname}{self.ctx.Config.COLORS.nogc})") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSNICK nickname newnickname") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} SVSNICK nickname newnickname") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'gline': try: # TKL + G user host set_by expire_timestamp set_at_timestamp :reason # .gline [nickname] [host] [reason] if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - set_at_timestamp = self.MainUtils.get_unixtime() + set_at_timestamp = self.ctx.Utils.get_unixtime() expire_time = (60 * 60 * 24) + set_at_timestamp gline_reason = ' '.join(cmd[3:]) if nickname == '*' and hostname == '*': - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None - self.Protocol.send_gline(nickname=nickname, hostname=hostname, set_by=dnickname, expire_timestamp=expire_time, set_at_timestamp=set_at_timestamp, reason=gline_reason) + await self.ctx.Irc.Protocol.send_gline(nickname=nickname, hostname=hostname, set_by=dnickname, expire_timestamp=expire_time, set_at_timestamp=set_at_timestamp, reason=gline_reason) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'ungline': try: @@ -797,47 +802,47 @@ class Command(IModule): # TKL + G user host set_by expire_timestamp set_at_timestamp :reason # .ungline nickname host if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - # self.Protocol.send2socket(f":{self.Config.SERVEUR_ID} TKL - G {nickname} {hostname} {dnickname}") - self.Protocol.send_ungline(nickname=nickname, hostname=hostname) + # await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_ID} TKL - G {nickname} {hostname} {dnickname}") + await self.ctx.Irc.Protocol.send_ungline(nickname=nickname, hostname=hostname) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'kline': try: # TKL + k user host set_by expire_timestamp set_at_timestamp :reason # .gline [nickname] [host] [reason] if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - set_at_timestamp = self.MainUtils.get_unixtime() + set_at_timestamp = self.ctx.Utils.get_unixtime() expire_time = (60 * 60 * 24) + set_at_timestamp gline_reason = ' '.join(cmd[3:]) if nickname == '*' and hostname == '*': - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None - self.Protocol.send_kline(nickname=nickname, hostname=hostname, set_by=dnickname, expire_timestamp=expire_time, set_at_timestamp=set_at_timestamp, reason=gline_reason) + await self.ctx.Irc.Protocol.send_kline(nickname=nickname, hostname=hostname, set_by=dnickname, expire_timestamp=expire_time, set_at_timestamp=set_at_timestamp, reason=gline_reason) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'unkline': try: @@ -845,19 +850,19 @@ class Command(IModule): # TKL + G user host set_by expire_timestamp set_at_timestamp :reason # .ungline nickname host if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - self.Protocol.send_unkline(nickname=nickname, hostname=hostname) + await self.ctx.Irc.Protocol.send_unkline(nickname=nickname, hostname=hostname) except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'shun': try: @@ -865,26 +870,26 @@ class Command(IModule): # .shun [nickname] [host] [reason] if len(cmd) < 4: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - set_at_timestamp = self.MainUtils.get_unixtime() + set_at_timestamp = self.ctx.Utils.get_unixtime() expire_time = (60 * 60 * 24) + set_at_timestamp shun_reason = ' '.join(cmd[3:]) if nickname == '*' and hostname == '*': - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You want to close the server ? i would recommand ./unrealircd stop :)") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") return None - self.Protocol.send2socket(f":{self.Config.SERVEUR_ID} TKL + s {nickname} {hostname} {dnickname} {expire_time} {set_at_timestamp} :{shun_reason}") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_ID} TKL + s {nickname} {hostname} {dnickname} {expire_time} {set_at_timestamp} :{shun_reason}") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname host reason") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'unshun': try: @@ -892,52 +897,52 @@ class Command(IModule): # TKL + G user host set_by expire_timestamp set_at_timestamp :reason # .unshun nickname host if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") return None nickname = str(cmd[1]) hostname = str(cmd[2]) - self.Protocol.send2socket(f":{self.Config.SERVEUR_ID} TKL - s {nickname} {hostname} {dnickname}") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVEUR_ID} TKL - s {nickname} {hostname} {dnickname}") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname hostname") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'glinelist': try: self.user_to_notice = fromuser - self.Protocol.send2socket(f":{self.Config.SERVICE_ID} STATS G") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVICE_ID} STATS G") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'shunlist': try: self.user_to_notice = fromuser - self.Protocol.send2socket(f":{self.Config.SERVICE_ID} STATS s") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVICE_ID} STATS s") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case 'klinelist': try: self.user_to_notice = fromuser - self.Protocol.send2socket(f":{self.Config.SERVICE_ID} STATS k") + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVICE_ID} STATS k") except KeyError as ke: - self.Logs.error(ke) + self.ctx.Logs.error(ke) except Exception as err: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") - self.Logs.warning(f'Unknown Error: {str(err)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()}") + self.ctx.Logs.warning(f'Unknown Error: {str(err)}') case _: pass diff --git a/mods/command/utils.py b/mods/command/utils.py index d7ef806..3a5f521 100644 --- a/mods/command/utils.py +++ b/mods/command/utils.py @@ -4,243 +4,243 @@ if TYPE_CHECKING: from mods.command.mod_command import Command -def set_automode(uplink: 'Command', cmd: list[str], client: str) -> None: +async def set_automode(uplink: 'Command', cmd: list[str], client: str) -> None: command: str = str(cmd[0]).lower() option: str = str(cmd[1]).lower() - allowed_modes: list[str] = uplink.Loader.Settings.PROTOCTL_PREFIX # ['q','a','o','h','v'] - dnickname = uplink.Config.SERVICE_NICKNAME - service_id = uplink.Config.SERVICE_ID + allowed_modes: list[str] = uplink.ctx.Settings.PROTOCTL_PREFIX # ['q','a','o','h','v'] + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + service_id = uplink.ctx.Config.SERVICE_ID fromuser = client match option: case 'set': if len(cmd) < 5: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [+/-mode] [#channel]") - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AutoModes available: {' / '.join(allowed_modes)}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [+/-mode] [#channel]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AutoModes available: {' / '.join(allowed_modes)}") return None nickname = str(cmd[2]) mode = str(cmd[3]) - chan: str = str(cmd[4]).lower() if uplink.Channel.is_valid_channel(cmd[4]) else None + chan: str = str(cmd[4]).lower() if uplink.ctx.Channel.is_valid_channel(cmd[4]) else None sign = mode[0] if mode.startswith( ('+', '-')) else None clean_mode = mode[1:] if len(mode) > 0 else None if sign is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You must provide the flag mode + or -") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You must provide the flag mode + or -") return None if clean_mode not in allowed_modes: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}") return None if chan is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}") return None db_data: dict[str, str] = {"nickname": nickname, "channel": chan} - db_query = uplink.Base.db_execute_query(query="SELECT id FROM command_automode WHERE nickname = :nickname and channel = :channel", params=db_data) + db_query = await uplink.ctx.Base.db_execute_query(query="SELECT id FROM command_automode WHERE nickname = :nickname and channel = :channel", params=db_data) db_result = db_query.fetchone() if db_result is not None: if sign == '+': - db_data = {"updated_on": uplink.MainUtils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode} - db_result = uplink.Base.db_execute_query(query="UPDATE command_automode SET mode = :mode, updated_on = :updated_on WHERE nickname = :nickname and channel = :channel", + db_data = {"updated_on": uplink.ctx.Utils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode} + db_result = await uplink.ctx.Base.db_execute_query(query="UPDATE command_automode SET mode = :mode, updated_on = :updated_on WHERE nickname = :nickname and channel = :channel", params=db_data) if db_result.rowcount > 0: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} edited for {nickname} in {chan}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} edited for {nickname} in {chan}") elif sign == '-': db_data = {"nickname": nickname, "channel": chan, "mode": f"+{clean_mode}"} - db_result = uplink.Base.db_execute_query(query="DELETE FROM command_automode WHERE nickname = :nickname and channel = :channel and mode = :mode", + db_result = await uplink.ctx.Base.db_execute_query(query="DELETE FROM command_automode WHERE nickname = :nickname and channel = :channel and mode = :mode", params=db_data) if db_result.rowcount > 0: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} deleted for {nickname} in {chan}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} deleted for {nickname} in {chan}") else: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The mode [{mode}] has not been found for {nickname} in channel {chan}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The mode [{mode}] has not been found for {nickname} in channel {chan}") return None # Instert a new automode if sign == '+': - db_data = {"created_on": uplink.MainUtils.get_sdatetime(), "updated_on": uplink.MainUtils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode} - db_query = uplink.Base.db_execute_query( + db_data = {"created_on": uplink.ctx.Utils.get_sdatetime(), "updated_on": uplink.ctx.Utils.get_sdatetime(), "nickname": nickname, "channel": chan, "mode": mode} + db_query = await uplink.ctx.Base.db_execute_query( query="INSERT INTO command_automode (created_on, updated_on, nickname, channel, mode) VALUES (:created_on, :updated_on, :nickname, :channel, :mode)", params=db_data ) if db_query.rowcount > 0: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} applied to {nickname} in {chan}") - if uplink.Channel.is_user_present_in_channel(chan, uplink.User.get_uid(nickname)): - uplink.Protocol.send2socket(f":{service_id} MODE {chan} {mode} {nickname}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} applied to {nickname} in {chan}") + if uplink.ctx.Channel.is_user_present_in_channel(chan, uplink.ctx.User.get_uid(nickname)): + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan} {mode} {nickname}") else: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AUTOMODE {mode} cannot be added to {nickname} in {chan} because it doesn't exist") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AUTOMODE {mode} cannot be added to {nickname} in {chan} because it doesn't exist") case 'list': - db_query = uplink.Base.db_execute_query("SELECT nickname, channel, mode FROM command_automode") + db_query = await uplink.ctx.Base.db_execute_query("SELECT nickname, channel, mode FROM command_automode") db_results = db_query.fetchall() if not db_results: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="There is no automode to display.") for db_result in db_results: db_nickname, db_channel, db_mode = db_result - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nickname: {db_nickname} | Channel: {db_channel} | Mode: {db_mode}") case _: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]") - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST") - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(allowed_modes)}") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(allowed_modes)}") -def set_deopall(uplink: 'Command', channel_name: str) -> None: +async def set_deopall(uplink: 'Command', channel_name: str) -> None: - service_id = uplink.Config.SERVICE_ID - uplink.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -o") + service_id = uplink.ctx.Config.SERVICE_ID + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -o") return None -def set_devoiceall(uplink: 'Command', channel_name: str) -> None: +async def set_devoiceall(uplink: 'Command', channel_name: str) -> None: - service_id = uplink.Config.SERVICE_ID - uplink.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -v") + service_id = uplink.ctx.Config.SERVICE_ID + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} SVSMODE {channel_name} -v") return None -def set_mode_to_all(uplink: 'Command', channel_name: str, action: Literal['+', '-'], pmode: str) -> None: +async def set_mode_to_all(uplink: 'Command', channel_name: str, action: Literal['+', '-'], pmode: str) -> None: - chan_info = uplink.Channel.get_channel(channel_name) - service_id = uplink.Config.SERVICE_ID - dnickname = uplink.Config.SERVICE_NICKNAME + chan_info = uplink.ctx.Channel.get_channel(channel_name) + service_id = uplink.ctx.Config.SERVICE_ID + dnickname = uplink.ctx.Config.SERVICE_NICKNAME set_mode = pmode mode:str = '' users:str = '' uids_split = [chan_info.uids[i:i + 6] for i in range(0, len(chan_info.uids), 6)] - uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{set_mode} {dnickname}") + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{set_mode} {dnickname}") for uid in uids_split: for i in range(0, len(uid)): mode += set_mode - users += f'{uplink.User.get_nickname(uplink.MainUtils.clean_uid(uid[i]))} ' + users += f'{uplink.ctx.User.get_nickname(uplink.ctx.Utils.clean_uid(uid[i]))} ' if i == len(uid) - 1: - uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{mode} {users}") + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {action}{mode} {users}") mode = '' users = '' -def set_operation(uplink: 'Command', cmd: list[str], channel_name: Optional[str], client: str, mode: str) -> None: +async def set_operation(uplink: 'Command', cmd: list[str], channel_name: Optional[str], client: str, mode: str) -> None: - dnickname = uplink.Config.SERVICE_NICKNAME - service_id = uplink.Config.SERVICE_ID + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + service_id = uplink.ctx.Config.SERVICE_ID if channel_name is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {mode} [#SALON] [NICKNAME]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {mode} [#SALON] [NICKNAME]") return False if len(cmd) == 1: - # uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {client}") - uplink.Protocol.send_set_mode(mode, nickname=client, channel_name=channel_name) + # await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {client}") + await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=client, channel_name=channel_name) return None # deop nickname if len(cmd) == 2: nickname = cmd[1] - # uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}") - uplink.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name) + # await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}") + await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name) return None nickname = cmd[2] - # uplink.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}") - uplink.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name) + # await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel_name} {mode} {nickname}") + await uplink.ctx.Irc.Protocol.send_set_mode(mode, nickname=nickname, channel_name=channel_name) return None -def set_ban(uplink: 'Command', cmd: list[str], action: Literal['+', '-'], client: str) -> None: +async def set_ban(uplink: 'Command', cmd: list[str], action: Literal['+', '-'], client: str) -> None: command = str(cmd[0]) - dnickname = uplink.Config.SERVICE_NICKNAME - service_id = uplink.Config.SERVICE_ID - sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + service_id = uplink.ctx.Config.SERVICE_ID + sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON] [NICKNAME]") return None nickname = cmd[2] - uplink.Protocol.send2socket(f":{service_id} MODE {sentchannel} {action}b {nickname}!*@*") - uplink.Logs.debug(f'{client} has banned {nickname} from {sentchannel}') + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {sentchannel} {action}b {nickname}!*@*") + uplink.ctx.Logs.debug(f'{client} has banned {nickname} from {sentchannel}') return None -def set_kick(uplink: 'Command', cmd: list[str], client: str) -> None: +async def set_kick(uplink: 'Command', cmd: list[str], client: str) -> None: command = str(cmd[0]) - dnickname = uplink.Config.SERVICE_NICKNAME - service_id = uplink.Config.SERVICE_ID + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + service_id = uplink.ctx.Config.SERVICE_ID - sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None + sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") return False nickname = cmd[2] final_reason = ' '.join(cmd[3:]) - uplink.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}") - uplink.Logs.debug(f'{client} has kicked {nickname} from {sentchannel} : {final_reason}') + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}") + uplink.ctx.Logs.debug(f'{client} has kicked {nickname} from {sentchannel} : {final_reason}') return None -def set_kickban(uplink: 'Command', cmd: list[str], client: str) -> None: +async def set_kickban(uplink: 'Command', cmd: list[str], client: str) -> None: command = str(cmd[0]) - dnickname = uplink.Config.SERVICE_NICKNAME - service_id = uplink.Config.SERVICE_ID + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + service_id = uplink.ctx.Config.SERVICE_ID - sentchannel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None + sentchannel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None if sentchannel is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command} [#SALON] [NICKNAME]") return False nickname = cmd[2] final_reason = ' '.join(cmd[3:]) - uplink.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}") - uplink.Protocol.send2socket(f":{service_id} MODE {sentchannel} +b {nickname}!*@*") - uplink.Logs.debug(f'{client} has kicked and banned {nickname} from {sentchannel} : {final_reason}') + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} KICK {sentchannel} {nickname} {final_reason}") + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {sentchannel} +b {nickname}!*@*") + uplink.ctx.Logs.debug(f'{client} has kicked and banned {nickname} from {sentchannel} : {final_reason}') -def set_assign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None: +async def set_assign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None: if len(cmd) < 2: raise IndexError(f"{cmd[0].upper()} is expecting the channel parameter") command = str(cmd[0]) - dnickname = uplink.Config.SERVICE_NICKNAME - sent_channel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + sent_channel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None if sent_channel is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") return None # self.Protocol.send2socket(f':{service_id} JOIN {sent_channel}') - uplink.Protocol.send_join_chan(uidornickname=dnickname,channel=sent_channel) - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has joined {sent_channel}") - uplink.Channel.db_query_channel('add', uplink.module_name, sent_channel) + await uplink.ctx.Irc.Protocol.send_join_chan(uidornickname=dnickname,channel=sent_channel) + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has joined {sent_channel}") + await uplink.ctx.Channel.db_query_channel('add', uplink.module_name, sent_channel) return None -def set_unassign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None: +async def set_unassign_channel_to_service(uplink: 'Command', cmd: list[str], client: str) -> None: if len(cmd) < 2: raise IndexError(f"{cmd[0].upper()} is expecting the channel parameter") command = str(cmd[0]) - dnickname = uplink.Config.SERVICE_NICKNAME - dchanlog = uplink.Config.SERVICE_CHANLOG + dnickname = uplink.ctx.Config.SERVICE_NICKNAME + dchanlog = uplink.ctx.Config.SERVICE_CHANLOG - sent_channel = str(cmd[1]) if uplink.Channel.is_valid_channel(cmd[1]) else None + sent_channel = str(cmd[1]) if uplink.ctx.Channel.is_valid_channel(cmd[1]) else None if sent_channel is None: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Right command : /msg {dnickname} {command.upper()} [#SALON]") return None if sent_channel == dchanlog: - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f"[!] CAN'T LEFT {sent_channel} AS IT IS LOG CHANNEL [!]") + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f"[!] CAN'T LEFT {sent_channel} AS IT IS LOG CHANNEL [!]") return None - uplink.Protocol.send_part_chan(uidornickname=dnickname, channel=sent_channel) - uplink.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has left {sent_channel}") + await uplink.ctx.Irc.Protocol.send_part_chan(uidornickname=dnickname, channel=sent_channel) + await uplink.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client, msg=f" Has left {sent_channel}") - uplink.Channel.db_query_channel('del', uplink.module_name, sent_channel) + await uplink.ctx.Channel.db_query_channel('del', uplink.module_name, sent_channel) return None \ No newline at end of file diff --git a/mods/defender/mod_defender.py b/mods/defender/mod_defender.py index 2a5476c..1127a3e 100644 --- a/mods/defender/mod_defender.py +++ b/mods/defender/mod_defender.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, TYPE_CHECKING +from typing import Any, TYPE_CHECKING, Optional from core.classes.interfaces.imodule import IModule import mods.defender.schemas as schemas import mods.defender.utils as utils @@ -24,7 +24,12 @@ class Defender(IModule): } def __init__(self, context: 'Loader') -> None: - self.ctx = context + super().__init__(context) + self._mod_config: Optional[schemas.ModConfModel] = None + + @property + def mod_config(self) -> ModConfModel: + return self._mod_config def create_tables(self) -> None: """Methode qui va créer la base de donnée si elle n'existe pas. @@ -44,34 +49,37 @@ class Defender(IModule): # ) # ''' - # self.Base.db_execute_query(table_autoop) - # self.Base.db_execute_query(table_config) - # self.Base.db_execute_query(table_trusted) + # self.ctx.Base.db_execute_query(table_autoop) + # self.ctx.Base.db_execute_query(table_config) + # self.ctx.Base.db_execute_query(table_trusted) return None async def load(self): - + + # Variable qui va contenir les options de configuration du module Defender + self._mod_config: schemas.ModConfModel = self.ModConfModel() + + # sync the database with local variable (Mandatory) + await self.sync_db() + # Add module schemas self.Schemas = schemas - # Add utils functions - self.Utils = utils + # Add module utils functions + self.mod_utils = utils - # Variable qui va contenir les options de configuration du module Defender - self.ModConfig: schemas.ModConfModel = self.ModConfModel() - # Create module commands (Mandatory) - self.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access') - self.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server') - self.Irc.build_command(1, self.module_name, 'autolimit', 'Automatically set channel user limits') - self.Irc.build_command(3, self.module_name, 'reputation', 'Check or manage user reputation') - self.Irc.build_command(3, self.module_name, 'proxy_scan', 'Scan users for proxy connections') - self.Irc.build_command(3, self.module_name, 'flood', 'Handle flood detection and mitigation') - self.Irc.build_command(3, self.module_name, 'status', 'Check the status of the server or bot') - self.Irc.build_command(3, self.module_name, 'show_reputation', 'Display reputation information') - self.Irc.build_command(3, self.module_name, 'sentinel', 'Monitor and guard the channel or server') + self.ctx.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access') + self.ctx.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server') + self.ctx.Irc.build_command(1, self.module_name, 'autolimit', 'Automatically set channel user limits') + self.ctx.Irc.build_command(3, self.module_name, 'reputation', 'Check or manage user reputation') + self.ctx.Irc.build_command(3, self.module_name, 'proxy_scan', 'Scan users for proxy connections') + self.ctx.Irc.build_command(3, self.module_name, 'flood', 'Handle flood detection and mitigation') + self.ctx.Irc.build_command(3, self.module_name, 'status', 'Check the status of the server or bot') + self.ctx.Irc.build_command(3, self.module_name, 'show_reputation', 'Display reputation information') + self.ctx.Irc.build_command(3, self.module_name, 'sentinel', 'Monitor and guard the channel or server') - self.timeout = self.Config.API_TIMEOUT + self.timeout = self.ctx.Config.API_TIMEOUT # Listes qui vont contenir les ip a scanner avec les différentes API self.Schemas.DB_ABUSEIPDB_USERS = self.Schemas.DB_FREEIPAPI_USERS = self.Schemas.DB_CLOUDFILT_USERS = [] @@ -93,27 +101,27 @@ class Defender(IModule): self.cloudfilt_key = 'r1gEtjtfgRQjtNBDMxsg' # Démarrer les threads pour démarrer les api - self.Base.create_thread(func=thds.thread_freeipapi_scan, func_args=(self, )) - self.Base.create_thread(func=thds.thread_cloudfilt_scan, func_args=(self, )) - self.Base.create_thread(func=thds.thread_abuseipdb_scan, func_args=(self, )) - self.Base.create_thread(func=thds.thread_local_scan, func_args=(self, )) - self.Base.create_thread(func=thds.thread_psutil_scan, func_args=(self, )) - self.Base.create_thread(func=thds.thread_apply_reputation_sanctions, func_args=(self, )) + self.ctx.Base.create_asynctask(thds.coro_freeipapi_scan(self)) + self.ctx.Base.create_asynctask(thds.coro_cloudfilt_scan(self)) + self.ctx.Base.create_asynctask(thds.coro_abuseipdb_scan(self)) + self.ctx.Base.create_asynctask(thds.coro_local_scan(self)) + self.ctx.Base.create_asynctask(thds.coro_psutil_scan(self)) + self.ctx.Base.create_asynctask(thds.coro_apply_reputation_sanctions(self)) - if self.ModConfig.autolimit == 1: - self.Base.create_thread(func=thds.thread_autolimit, func_args=(self, )) + if self.mod_config.autolimit == 1: + self.ctx.Base.create_asynctask(thds.coro_autolimit(self)) - if self.ModConfig.reputation == 1: - await self.Protocol.send_sjoin(self.Config.SALON_JAIL) - await self.Protocol.send2socket(f":{self.Config.SERVICE_NICKNAME} SAMODE {self.Config.SALON_JAIL} +o {self.Config.SERVICE_NICKNAME}") + if self.mod_config.reputation == 1: + await self.ctx.Irc.Protocol.send_sjoin(self.ctx.Config.SALON_JAIL) + await self.ctx.Irc.Protocol.send2socket(f":{self.ctx.Config.SERVICE_NICKNAME} SAMODE {self.ctx.Config.SALON_JAIL} +o {self.ctx.Config.SERVICE_NICKNAME}") def __onload(self): - abuseipdb = self.Settings.get_cache('ABUSEIPDB') - freeipapi = self.Settings.get_cache('FREEIPAPI') - cloudfilt = self.Settings.get_cache('CLOUDFILT') - psutils = self.Settings.get_cache('PSUTIL') - localscan = self.Settings.get_cache('LOCALSCAN') + abuseipdb = self.ctx.Settings.get_cache('ABUSEIPDB') + freeipapi = self.ctx.Settings.get_cache('FREEIPAPI') + cloudfilt = self.ctx.Settings.get_cache('CLOUDFILT') + psutils = self.ctx.Settings.get_cache('PSUTIL') + localscan = self.ctx.Settings.get_cache('LOCALSCAN') if abuseipdb: self.Schemas.DB_ABUSEIPDB_USERS = abuseipdb @@ -148,12 +156,12 @@ class Defender(IModule): self.reputationTimer_isRunning:bool = False self.autolimit_isRunning: bool = False - self.Irc.Commands.drop_command_by_module(self.module_name) + self.ctx.Commands.drop_command_by_module(self.module_name) return None - def insert_db_trusted(self, uid: str, nickname:str) -> None: - u = self.User.get_user(uid) + async def insert_db_trusted(self, uid: str, nickname:str) -> None: + u = self.ctx.User.get_user(uid) if u is None: return None @@ -161,119 +169,119 @@ class Defender(IModule): nickname = u.nickname query = "SELECT id FROM def_trusted WHERE user = ?" - exec_query = self.Base.db_execute_query(query, {"user": nickname}) + exec_query = await self.ctx.Base.db_execute_query(query, {"user": nickname}) response = exec_query.fetchone() if response is not None: q_insert = "INSERT INTO def_trusted (datetime, user, host, vhost) VALUES (?, ?, ?, ?)" - mes_donnees = {'datetime': self.Loader.Utils.get_datetime(), 'user': nickname, 'host': '*', 'vhost': '*'} - exec_query = self.Base.db_execute_query(q_insert, mes_donnees) + mes_donnees = {'datetime': self.ctx.mod_utils.get_datetime(), 'user': nickname, 'host': '*', 'vhost': '*'} + exec_query = self.ctx.Base.db_execute_query(q_insert, mes_donnees) pass async def join_saved_channels(self) -> None: """_summary_ """ try: - result = self.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.Config.TABLE_CHANNEL}") + result = await self.ctx.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.ctx.Config.TABLE_CHANNEL}") channels = result.fetchall() - jail_chan = self.Config.SALON_JAIL - jail_chan_mode = self.Config.SALON_JAIL_MODES - service_id = self.Config.SERVICE_ID - dumodes = self.Config.SERVICE_UMODES - dnickname = self.Config.SERVICE_NICKNAME + jail_chan = self.ctx.Config.SALON_JAIL + jail_chan_mode = self.ctx.Config.SALON_JAIL_MODES + service_id = self.ctx.Config.SERVICE_ID + dumodes = self.ctx.Config.SERVICE_UMODES + dnickname = self.ctx.Config.SERVICE_NICKNAME for channel in channels: chan = channel[0] - await self.Protocol.send_sjoin(chan) + await self.ctx.Irc.Protocol.send_sjoin(chan) if chan == jail_chan: - await self.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") - await self.Protocol.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}") return None except Exception as err: - self.Logs.error(f"General Error: {err}") + self.ctx.Logs.error(f"General Error: {err}") - def cmd(self, data: list[str]) -> None: + async def cmd(self, data: list[str]) -> None: if not data or len(data) < 2: return None cmd = data.copy() if isinstance(data, list) else list(data).copy() try: - index, command = self.Irc.Protocol.get_ircd_protocol_poisition(cmd) + index, command = self.ctx.Irc.Protocol.get_ircd_protocol_poisition(cmd) if index == -1: return None match command: case 'REPUTATION': - self.Utils.handle_on_reputation(self, cmd) + self.mod_utils.handle_on_reputation(self, cmd) return None case 'MODE': - self.Utils.handle_on_mode(self, cmd) + await self.mod_utils.handle_on_mode(self, cmd) return None case 'PRIVMSG': - self.Utils.handle_on_privmsg(self, cmd) + await self.mod_utils.handle_on_privmsg(self, cmd) return None case 'UID': - self.Utils.handle_on_uid(self, cmd) + await self.mod_utils.handle_on_uid(self, cmd) return None case 'SJOIN': - self.Utils.handle_on_sjoin(self, cmd) + await self.mod_utils.handle_on_sjoin(self, cmd) return None case 'SLOG': - self.Utils.handle_on_slog(self, cmd) + self.mod_utils.handle_on_slog(self, cmd) return None case 'NICK': - self.Utils.handle_on_nick(self, cmd) + await self.mod_utils.handle_on_nick(self, cmd) return None case 'QUIT': - self.Utils.handle_on_quit(self, cmd) + await self.mod_utils.handle_on_quit(self, cmd) return None case _: return None except KeyError as ke: - self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}") + self.ctx.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}") except IndexError as ie: - self.Logs.error(f"{ie} / {cmd} / length {str(len(cmd))}") + self.ctx.Logs.error(f"{ie} / {cmd} / length {str(len(cmd))}") except Exception as err: - self.Logs.error(f"General Error: {err}", exc_info=True) + self.ctx.Logs.error(f"General Error: {err}", exc_info=True) async def hcmds(self, user: str, channel: Any, cmd: list, fullcmd: list = []) -> None: - u = self.User.get_user(user) + u = self.ctx.User.get_user(user) if u is None: return None command = str(cmd[0]).lower() fromuser = u.nickname - channel = fromchannel = channel if self.Channel.is_valid_channel(channel) else None + channel = fromchannel = channel if self.ctx.Channel.is_valid_channel(channel) else None - dnickname = self.Config.SERVICE_NICKNAME # Defender nickname - dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log - dumodes = self.Config.SERVICE_UMODES # Les modes de Defender - service_id = self.Config.SERVICE_ID # Defender serveur id - jail_chan = self.Config.SALON_JAIL # Salon pot de miel - jail_chan_mode = self.Config.SALON_JAIL_MODES # Mode du salon "pot de miel" + dnickname = self.ctx.Config.SERVICE_NICKNAME # Defender nickname + dchanlog = self.ctx.Config.SERVICE_CHANLOG # Defender chan log + dumodes = self.ctx.Config.SERVICE_UMODES # Les modes de Defender + service_id = self.ctx.Config.SERVICE_ID # Defender serveur id + jail_chan = self.ctx.Config.SALON_JAIL # Salon pot de miel + jail_chan_mode = self.ctx.Config.SALON_JAIL_MODES # Mode du salon "pot de miel" match command: case 'show_reputation': - if not self.Reputation.UID_REPUTATION_DB: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="No one is suspected") + if not self.ctx.Reputation.UID_REPUTATION_DB: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="No one is suspected") - for suspect in self.Reputation.UID_REPUTATION_DB: - await self.Protocol.send_notice(nick_from=dnickname, + for suspect in self.ctx.Reputation.UID_REPUTATION_DB: + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Uid: {suspect.uid} | Nickname: {suspect.nickname} | Reputation: {suspect.score_connexion} | Secret code: {suspect.secret_code} | Connected on: {suspect.connexion_datetime}") @@ -282,106 +290,106 @@ class Defender(IModule): release_code = cmd[1] jailed_nickname = u.nickname jailed_UID = u.uid - get_reputation = self.Reputation.get_reputation(jailed_UID) + get_reputation = self.ctx.Reputation.get_reputation(jailed_UID) if get_reputation is None: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" No code is requested ...") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" No code is requested ...") return False jailed_IP = get_reputation.remote_ip - jailed_salon = self.Config.SALON_JAIL - reputation_seuil = self.ModConfig.reputation_seuil - welcome_salon = self.Config.SALON_LIBERER + jailed_salon = self.ctx.Config.SALON_JAIL + reputation_seuil = self.mod_config.reputation_seuil + welcome_salon = self.ctx.Config.SALON_LIBERER - self.Logs.debug(f"IP de {jailed_nickname} : {jailed_IP}") - link = self.Config.SERVEUR_LINK - color_green = self.Config.COLORS.green - color_black = self.Config.COLORS.black + self.ctx.Logs.debug(f"IP de {jailed_nickname} : {jailed_IP}") + link = self.ctx.Config.SERVEUR_LINK + color_green = self.ctx.Config.COLORS.green + color_black = self.ctx.Config.COLORS.black if release_code == get_reputation.secret_code: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg="Bon mot de passe. Allez du vent !", channel=jailed_salon) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg="Bon mot de passe. Allez du vent !", channel=jailed_salon) - if self.ModConfig.reputation_ban_all_chan == 1: - for chan in self.Channel.UID_CHANNEL_DB: + if self.mod_config.reputation_ban_all_chan == 1: + for chan in self.ctx.Channel.UID_CHANNEL_DB: if chan.name != jailed_salon: - await self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {jailed_nickname}!*@*") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {jailed_nickname}!*@*") - self.Reputation.delete(jailed_UID) - self.Logs.debug(f'{jailed_UID} - {jailed_nickname} removed from REPUTATION_DB') - await self.Protocol.send_sapart(nick_to_sapart=jailed_nickname, channel_name=jailed_salon) - await self.Protocol.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=welcome_salon) - await self.Protocol.send2socket(f":{link} REPUTATION {jailed_IP} {self.ModConfig.reputation_score_after_release}") + self.ctx.Reputation.delete(jailed_UID) + self.ctx.Logs.debug(f'{jailed_UID} - {jailed_nickname} removed from REPUTATION_DB') + await self.ctx.Irc.Protocol.send_sapart(nick_to_sapart=jailed_nickname, channel_name=jailed_salon) + await self.ctx.Irc.Protocol.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=welcome_salon) + await self.ctx.Irc.Protocol.send2socket(f":{link} REPUTATION {jailed_IP} {self.mod_config.reputation_score_after_release}") u.score_connexion = reputation_seuil + 1 - await self.Protocol.send_priv_msg(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{color_green} MOT DE PASS CORRECT {color_black}] : You have now the right to enjoy the network !", nick_to=jailed_nickname) else: - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, msg="Mauvais password", channel=jailed_salon ) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[{color_green} MAUVAIS PASSWORD {color_black}] You have typed a wrong code. for recall your password is: {self.Config.SERVICE_PREFIX}code {get_reputation.secret_code}", + msg=f"[{color_green} MAUVAIS PASSWORD {color_black}] You have typed a wrong code. for recall your password is: {self.ctx.Config.SERVICE_PREFIX}code {get_reputation.secret_code}", nick_to=jailed_nickname ) except IndexError as ie: - self.Logs.error(f'Index Error: {ie}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} code [code]") + self.ctx.Logs.error(f'Index Error: {ie}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} code [code]") except KeyError as ke: - self.Logs.error(f'_hcmd code: KeyError {ke}') + self.ctx.Logs.error(f'_hcmd code: KeyError {ke}') case 'autolimit': try: # autolimit on # autolimit set [amount] [interval] if len(cmd) < 2: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ON") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ON") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") return None arg = str(cmd[1]).lower() match arg: case 'on': - if self.ModConfig.autolimit == 0: - self.update_configuration('autolimit', 1) + if self.mod_config.autolimit == 0: + await self.update_configuration('autolimit', 1) self.autolimit_isRunning = True - self.Base.create_thread(func=thds.thread_autolimit, func_args=(self, )) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.Config.COLORS.green}AUTOLIMIT{self.Config.COLORS.nogc}] Activated", channel=self.Config.SERVICE_CHANLOG) + self.ctx.Base.create_asynctask(thds.coro_autolimit(self), async_name='coro_autolimit') + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.ctx.Config.COLORS.green}AUTOLIMIT{self.ctx.Config.COLORS.nogc}] Activated", channel=self.ctx.Config.SERVICE_CHANLOG) else: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.Config.COLORS.red}AUTOLIMIT{self.Config.COLORS.nogc}] Already activated", channel=self.Config.SERVICE_CHANLOG) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.ctx.Config.COLORS.red}AUTOLIMIT{self.ctx.Config.COLORS.nogc}] Already activated", channel=self.ctx.Config.SERVICE_CHANLOG) case 'off': - if self.ModConfig.autolimit == 1: - self.update_configuration('autolimit', 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.Config.COLORS.green}AUTOLIMIT{self.Config.COLORS.nogc}] Deactivated", channel=self.Config.SERVICE_CHANLOG) + if self.mod_config.autolimit == 1: + await self.update_configuration('autolimit', 0) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.ctx.Config.COLORS.green}AUTOLIMIT{self.ctx.Config.COLORS.nogc}] Deactivated", channel=self.ctx.Config.SERVICE_CHANLOG) else: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.Config.COLORS.red}AUTOLIMIT{self.Config.COLORS.nogc}] Already Deactivated", channel=self.Config.SERVICE_CHANLOG) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{self.ctx.Config.COLORS.red}AUTOLIMIT{self.ctx.Config.COLORS.nogc}] Already Deactivated", channel=self.ctx.Config.SERVICE_CHANLOG) case 'set': amount = int(cmd[2]) interval = int(cmd[3]) - self.update_configuration('autolimit_amount', amount) - self.update_configuration('autolimit_interval', interval) - await self.Protocol.send_priv_msg( + await self.update_configuration('autolimit_amount', amount) + await self.update_configuration('autolimit_interval', interval) + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[{self.Config.COLORS.green}AUTOLIMIT{self.Config.COLORS.nogc}] Amount set to ({amount}) | Interval set to ({interval})", - channel=self.Config.SERVICE_CHANLOG + msg=f"[{self.ctx.Config.COLORS.green}AUTOLIMIT{self.ctx.Config.COLORS.nogc}] Amount set to ({amount}) | Interval set to ({interval})", + channel=self.ctx.Config.SERVICE_CHANLOG ) case _: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ON") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ON") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") except Exception as err: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} ON") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") - self.Logs.error(f"Value Error -> {err}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} ON") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.ctx.Config.SERVICE_NICKNAME} {command.upper()} SET [AMOUNT] [INTERVAL]") + self.ctx.Logs.error(f"Value Error -> {err}") case 'reputation': # .reputation [on/off] --> activate or deactivate reputation system @@ -401,54 +409,54 @@ class Defender(IModule): key = 'reputation' if activation == 'on': - if self.ModConfig.reputation == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Already activated", channel=dchanlog) + if self.mod_config.reputation == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION{self.ctx.Config.COLORS.black} ] : Already activated", channel=dchanlog) return False # self.update_db_configuration('reputation', 1) - self.update_configuration(key, 1) + await self.update_configuration(key, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION{self.ctx.Config.COLORS.black} ] : Activated by {fromuser}", channel=dchanlog) - await self.Protocol.send_join_chan(uidornickname=dnickname, channel=jail_chan) - await self.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") - await self.Protocol.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}") + await self.ctx.Irc.Protocol.send_join_chan(uidornickname=dnickname, channel=jail_chan) + await self.ctx.Irc.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}") - if self.ModConfig.reputation_sg == 1: - for chan in self.Channel.UID_CHANNEL_DB: + if self.mod_config.reputation_sg == 1: + for chan in self.ctx.Channel.UID_CHANNEL_DB: if chan.name != jail_chan: - await self.Protocol.send2socket(f":{service_id} MODE {chan.name} +b ~security-group:unknown-users") - await self.Protocol.send2socket(f":{service_id} MODE {chan.name} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan.name} +b ~security-group:unknown-users") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan.name} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") - self.Channel.db_query_channel('add', self.module_name, jail_chan) + await self.ctx.Channel.db_query_channel('add', self.module_name, jail_chan) if activation == 'off': - if self.ModConfig.reputation == 0: - await self.Protocol.send_priv_msg( + if self.mod_config.reputation == 0: + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Already deactivated", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION{self.ctx.Config.COLORS.black} ] : Already deactivated", channel=dchanlog ) return False - self.update_configuration(key, 0) + await self.update_configuration(key, 0) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.red}REPUTATION{self.Config.COLORS.black} ] : Deactivated by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.red}REPUTATION{self.ctx.Config.COLORS.black} ] : Deactivated by {fromuser}", channel=dchanlog ) - await self.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} -{dumodes} {dnickname}") - await self.Protocol.send2socket(f":{service_id} MODE {jail_chan} -sS") - await self.Protocol.send2socket(f":{service_id} PART {jail_chan}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} SAMODE {jail_chan} -{dumodes} {dnickname}") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {jail_chan} -sS") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} PART {jail_chan}") - for chan in self.Channel.UID_CHANNEL_DB: + for chan in self.ctx.Channel.UID_CHANNEL_DB: if chan.name != jail_chan: - await self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b ~security-group:unknown-users") - await self.Protocol.send2socket(f":{service_id} MODE {chan.name} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan.name} -b ~security-group:unknown-users") + await self.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {chan.name} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") - self.Channel.db_query_channel('del', self.module_name, jail_chan) + await self.ctx.Channel.db_query_channel('del', self.module_name, jail_chan) if len_cmd == 3: get_options = str(cmd[1]).lower() @@ -456,44 +464,44 @@ class Defender(IModule): match get_options: case 'release': # .reputation release [nick] - p = await self.Protocol - link = self.Config.SERVEUR_LINK - jailed_salon = self.Config.SALON_JAIL - welcome_salon = self.Config.SALON_LIBERER - client_obj = self.User.get_user(str(cmd[2])) + p = await self.ctx.Irc.Protocol + link = self.ctx.Config.SERVEUR_LINK + jailed_salon = self.ctx.Config.SALON_JAIL + welcome_salon = self.ctx.Config.SALON_LIBERER + client_obj = self.ctx.User.get_user(str(cmd[2])) if client_obj is None: - p.send_notice(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This nickname ({str(cmd[2])}) is not connected to the network!") return None - client_to_release = self.Reputation.get_reputation(client_obj.uid) + client_to_release = self.ctx.Reputation.get_reputation(client_obj.uid) if client_to_release is None: - p.send_notice(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This nickname ({str(cmd[2])}) doesn't exist in the reputation databalse!") return None - if self.Reputation.delete(client_to_release.uid): - p.send_priv_msg( + if self.ctx.Reputation.delete(client_to_release.uid): + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION RELEASE{self.Config.COLORS.black} ] : {client_to_release.nickname} has been released", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION RELEASE{self.ctx.Config.COLORS.black} ] : {client_to_release.nickname} has been released", channel=dchanlog) - p.send_notice(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This nickname has been released from reputation system") - p.send_notice(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=client_to_release.nickname, msg=f"You have been released from the reputation system by ({fromuser})") - p.send_sapart(nick_to_sapart=client_to_release.nickname, channel_name=jailed_salon) - p.send_sajoin(nick_to_sajoin=client_to_release.nickname, channel_name=welcome_salon) - p.send2socket(f":{link} REPUTATION {client_to_release.remote_ip} {self.ModConfig.reputation_score_after_release}") + await self.ctx.Irc.Protocol.send_sapart(nick_to_sapart=client_to_release.nickname, channel_name=jailed_salon) + await self.ctx.Irc.Protocol.send_sajoin(nick_to_sajoin=client_to_release.nickname, channel_name=welcome_salon) + await self.ctx.Irc.Protocol.send2socket(f":{link} REPUTATION {client_to_release.remote_ip} {self.mod_config.reputation_score_after_release}") return None else: - p.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.red}REPUTATION RELEASE ERROR{self.Config.COLORS.black} ] : " + msg=f"[ {self.ctx.Config.COLORS.red}REPUTATION RELEASE ERROR{self.ctx.Config.COLORS.black} ] : " f"{client_to_release.nickname} has not been released! as he is not in the reputation database", channel=dchanlog ) @@ -512,38 +520,38 @@ class Defender(IModule): get_value = str(cmd[3]).lower() if get_value == 'on': - if self.ModConfig.reputation_ban_all_chan == 1: - await self.Protocol.send_priv_msg( + if self.mod_config.reputation_ban_all_chan == 1: + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.red}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Already activated", + msg=f"[ {self.ctx.Config.COLORS.red}BAN ON ALL CHANS{self.ctx.Config.COLORS.black} ] : Already activated", channel=dchanlog ) return False # self.update_db_configuration(key, 1) - self.update_configuration(key, 1) + await self.update_configuration(key, 1) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Activated by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}BAN ON ALL CHANS{self.ctx.Config.COLORS.black} ] : Activated by {fromuser}", channel=dchanlog ) elif get_value == 'off': - if self.ModConfig.reputation_ban_all_chan == 0: - await self.Protocol.send_priv_msg( + if self.mod_config.reputation_ban_all_chan == 0: + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.red}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Already deactivated", + msg=f"[ {self.ctx.Config.COLORS.red}BAN ON ALL CHANS{self.ctx.Config.COLORS.black} ] : Already deactivated", channel=dchanlog ) return False # self.update_db_configuration(key, 0) - self.update_configuration(key, 0) + await self.update_configuration(key, 0) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Deactivated by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}BAN ON ALL CHANS{self.ctx.Config.COLORS.black} ] : Deactivated by {fromuser}", channel=dchanlog ) @@ -552,73 +560,73 @@ class Defender(IModule): key = 'reputation_seuil' # self.update_db_configuration(key, reputation_seuil) - self.update_configuration(key, reputation_seuil) + await self.update_configuration(key, reputation_seuil) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION SEUIL{self.Config.COLORS.black} ] : Limit set to {str(reputation_seuil)} by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION SEUIL{self.ctx.Config.COLORS.black} ] : Limit set to {str(reputation_seuil)} by {fromuser}", channel=dchanlog ) - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation set to {reputation_seuil}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation set to {reputation_seuil}") case 'timer': reputation_timer = int(cmd[3]) key = 'reputation_timer' - self.update_configuration(key, reputation_timer) + await self.update_configuration(key, reputation_timer) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION TIMER{self.Config.COLORS.black} ] : Timer set to {str(reputation_timer)} minute(s) by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION TIMER{self.ctx.Config.COLORS.black} ] : Timer set to {str(reputation_timer)} minute(s) by {fromuser}", channel=dchanlog ) - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation set to {reputation_timer}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation set to {reputation_timer}") case 'score_after_release': reputation_score_after_release = int(cmd[3]) key = 'reputation_score_after_release' - self.update_configuration(key, reputation_score_after_release) + await self.update_configuration(key, reputation_score_after_release) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION SCORE AFTER RELEASE{self.Config.COLORS.black} ] : Reputation score after release set to {str(reputation_score_after_release)} by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION SCORE AFTER RELEASE{self.ctx.Config.COLORS.black} ] : Reputation score after release set to {str(reputation_score_after_release)} by {fromuser}", channel=dchanlog ) - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation score after release set to {reputation_score_after_release}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation score after release set to {reputation_score_after_release}") case 'security_group': reputation_sg = int(cmd[3]) key = 'reputation_sg' - self.update_configuration(key, reputation_sg) + await self.update_configuration(key, reputation_sg) - await self.Protocol.send_priv_msg( + await self.ctx.Irc.Protocol.send_priv_msg( nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}REPUTATION SECURITY-GROUP{self.Config.COLORS.black} ] : Reputation Security-group set to {str(reputation_sg)} by {fromuser}", + msg=f"[ {self.ctx.Config.COLORS.green}REPUTATION SECURITY-GROUP{self.ctx.Config.COLORS.black} ] : Reputation Security-group set to {str(reputation_sg)} by {fromuser}", channel=dchanlog ) - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation score after release set to {reputation_sg}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Reputation score after release set to {reputation_sg}") case _: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation [ON/OFF]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation release [nickname]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set banallchan [ON/OFF]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set limit [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set score_after_release [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set timer [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set action [kill|None]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation [ON/OFF]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation release [nickname]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set banallchan [ON/OFF]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set limit [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set score_after_release [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set timer [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set action [kill|None]") except IndexError as ie: - self.Logs.warning(f'{ie}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation [ON/OFF]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation release [nickname]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set banallchan [ON/OFF]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set limit [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set score_after_release [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set timer [1234]") - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set action [kill|None]") + self.ctx.Logs.warning(f'{ie}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation [ON/OFF]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation release [nickname]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set banallchan [ON/OFF]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set limit [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set score_after_release [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set timer [1234]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Right command : /msg {dnickname} reputation set action [kill|None]") except ValueError as ve: - self.Logs.warning(f'{ve}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" La valeur devrait etre un entier >= 0") + self.ctx.Logs.warning(f'{ve}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" La valeur devrait etre un entier >= 0") case 'proxy_scan': @@ -626,19 +634,19 @@ class Defender(IModule): # .proxy_scan set psutil_scan on/off --> Active les informations de connexion a la machine locale # .proxy_scan set abuseipdb_scan on/off --> Active le scan via l'api abuseipdb len_cmd = len(cmd) - color_green = self.Config.COLORS.green - color_red = self.Config.COLORS.red - color_black = self.Config.COLORS.black + color_green = self.ctx.Config.COLORS.green + color_red = self.ctx.Config.COLORS.red + color_black = self.ctx.Config.COLORS.black if len_cmd == 4: set_key = str(cmd[1]).lower() if set_key != 'set': - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') option = str(cmd[2]).lower() # => local_scan, psutil_scan, abuseipdb_scan action = str(cmd[3]).lower() # => on / off @@ -646,106 +654,106 @@ class Defender(IModule): match option: case 'local_scan': if action == 'on': - if self.ModConfig.local_scan == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) + if self.mod_config.local_scan == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) return None - self.update_configuration(option, 1) + await self.update_configuration(option, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) elif action == 'off': - if self.ModConfig.local_scan == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.local_scan == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) return None - self.update_configuration(option, 0) + await self.update_configuration(option, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) case 'psutil_scan': if action == 'on': - if self.ModConfig.psutil_scan == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) + if self.mod_config.psutil_scan == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) return None - self.update_configuration(option, 1) + await self.update_configuration(option, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) elif action == 'off': - if self.ModConfig.psutil_scan == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.psutil_scan == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) return None - self.update_configuration(option, 0) + await self.update_configuration(option, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) case 'abuseipdb_scan': if action == 'on': - if self.ModConfig.abuseipdb_scan == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) + if self.mod_config.abuseipdb_scan == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) return None - self.update_configuration(option, 1) + await self.update_configuration(option, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) elif action == 'off': - if self.ModConfig.abuseipdb_scan == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.abuseipdb_scan == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) return None - self.update_configuration(option, 0) + await self.update_configuration(option, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) case 'freeipapi_scan': if action == 'on': - if self.ModConfig.freeipapi_scan == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) + if self.mod_config.freeipapi_scan == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) return None - self.update_configuration(option, 1) + await self.update_configuration(option, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) elif action == 'off': - if self.ModConfig.freeipapi_scan == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.freeipapi_scan == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) return None - self.update_configuration(option, 0) + await self.update_configuration(option, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) case 'cloudfilt_scan': if action == 'on': - if self.ModConfig.cloudfilt_scan == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) + if self.mod_config.cloudfilt_scan == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated", channel=dchanlog) return None - self.update_configuration(option, 1) + await self.update_configuration(option, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}", channel=dchanlog) elif action == 'off': - if self.ModConfig.cloudfilt_scan == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.cloudfilt_scan == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated", channel=dchanlog) return None - self.update_configuration(option, 0) + await self.update_configuration(option, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}", channel=dchanlog) case _: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') else: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]') case 'flood': # .flood on/off @@ -759,22 +767,22 @@ class Defender(IModule): activation = str(cmd[1]).lower() key = 'flood' if activation == 'on': - if self.ModConfig.flood == 1: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Already activated", channel=dchanlog) + if self.mod_config.flood == 1: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Already activated", channel=dchanlog) return False - self.update_configuration(key, 1) + await self.update_configuration(key, 1) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Activated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Activated by {fromuser}", channel=dchanlog) if activation == 'off': - if self.ModConfig.flood == 0: - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.red}FLOOD{self.Config.COLORS.black} ] : Already Deactivated", channel=dchanlog) + if self.mod_config.flood == 0: + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.red}FLOOD{self.ctx.Config.COLORS.black} ] : Already Deactivated", channel=dchanlog) return False - self.update_configuration(key, 0) + await self.update_configuration(key, 0) - await self.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Deactivated by {fromuser}", channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Deactivated by {fromuser}", channel=dchanlog) if len_cmd == 4: set_key = str(cmd[2]).lower() @@ -784,124 +792,126 @@ class Defender(IModule): case 'flood_message': key = 'flood_message' set_value = int(cmd[3]) - self.update_configuration(key, set_value) + await self.update_configuration(key, set_value) - await self.Protocol.send_priv_msg(nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood message set to {set_value} by {fromuser}", + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, + msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Flood message set to {set_value} by {fromuser}", channel=dchanlog) case 'flood_time': key = 'flood_time' set_value = int(cmd[3]) - self.update_configuration(key, set_value) + await self.update_configuration(key, set_value) - await self.Protocol.send_priv_msg(nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood time set to {set_value} by {fromuser}", + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, + msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Flood time set to {set_value} by {fromuser}", channel=dchanlog) case 'flood_timer': key = 'flood_timer' set_value = int(cmd[3]) - self.update_configuration(key, set_value) + await self.update_configuration(key, set_value) - await self.Protocol.send_priv_msg(nick_from=dnickname, - msg=f"[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood timer set to {set_value} by {fromuser}", + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, + msg=f"[ {self.ctx.Config.COLORS.green}FLOOD{self.ctx.Config.COLORS.black} ] : Flood timer set to {set_value} by {fromuser}", channel=dchanlog) case _: pass except ValueError as ve: - self.Logs.error(f"{self.__class__.__name__} Value Error : {ve}") + self.ctx.Logs.error(f"{self.__class__.__name__} Value Error : {ve}") case 'status': - color_green = self.Config.COLORS.green - color_red = self.Config.COLORS.red - color_black = self.Config.COLORS.black - nogc = self.Config.COLORS.nogc + color_green = self.ctx.Config.COLORS.green + color_red = self.ctx.Config.COLORS.red + color_black = self.ctx.Config.COLORS.black + nogc = self.ctx.Config.COLORS.nogc try: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.reputation == 1 else color_red}Reputation{nogc}] ==> {self.ModConfig.reputation}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_seuil ==> {self.ModConfig.reputation_seuil}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_after_release ==> {self.ModConfig.reputation_score_after_release}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_ban_all_chan ==> {self.ModConfig.reputation_ban_all_chan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_timer ==> {self.ModConfig.reputation_timer}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' [Proxy_scan]') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.local_scan == 1 else color_red}local_scan{nogc} ==> {self.ModConfig.local_scan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.psutil_scan == 1 else color_red}psutil_scan{nogc} ==> {self.ModConfig.psutil_scan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.abuseipdb_scan == 1 else color_red}abuseipdb_scan{nogc} ==> {self.ModConfig.abuseipdb_scan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.freeipapi_scan == 1 else color_red}freeipapi_scan{nogc} ==> {self.ModConfig.freeipapi_scan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.cloudfilt_scan == 1 else color_red}cloudfilt_scan{nogc} ==> {self.ModConfig.cloudfilt_scan}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.autolimit == 1 else color_red}Autolimit{nogc}] ==> {self.ModConfig.autolimit}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.autolimit == 1 else color_red}Autolimit Amount{nogc} ==> {self.ModConfig.autolimit_amount}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.autolimit == 1 else color_red}Autolimit Interval{nogc} ==> {self.ModConfig.autolimit_interval}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.flood == 1 else color_red}Flood{nogc}] ==> {self.ModConfig.flood}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' flood_action ==> Coming soon') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_message ==> {self.ModConfig.flood_message}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_time ==> {self.ModConfig.flood_time}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_timer ==> {self.ModConfig.flood_timer}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.flood == 1 else color_red}Sentinel{nogc}] ==> {self.ModConfig.sentinel}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.mod_config.reputation == 1 else color_red}Reputation{nogc}] ==> {self.mod_config.reputation}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_seuil ==> {self.mod_config.reputation_seuil}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_after_release ==> {self.mod_config.reputation_score_after_release}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_ban_all_chan ==> {self.mod_config.reputation_ban_all_chan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_timer ==> {self.mod_config.reputation_timer}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' [Proxy_scan]') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.local_scan == 1 else color_red}local_scan{nogc} ==> {self.mod_config.local_scan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.psutil_scan == 1 else color_red}psutil_scan{nogc} ==> {self.mod_config.psutil_scan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.abuseipdb_scan == 1 else color_red}abuseipdb_scan{nogc} ==> {self.mod_config.abuseipdb_scan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.freeipapi_scan == 1 else color_red}freeipapi_scan{nogc} ==> {self.mod_config.freeipapi_scan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.cloudfilt_scan == 1 else color_red}cloudfilt_scan{nogc} ==> {self.mod_config.cloudfilt_scan}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.mod_config.autolimit == 1 else color_red}Autolimit{nogc}] ==> {self.mod_config.autolimit}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.autolimit == 1 else color_red}Autolimit Amount{nogc} ==> {self.mod_config.autolimit_amount}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.mod_config.autolimit == 1 else color_red}Autolimit Interval{nogc} ==> {self.mod_config.autolimit_interval}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.mod_config.flood == 1 else color_red}Flood{nogc}] ==> {self.mod_config.flood}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' flood_action ==> Coming soon') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_message ==> {self.mod_config.flood_message}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_time ==> {self.mod_config.flood_time}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_timer ==> {self.mod_config.flood_timer}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.mod_config.flood == 1 else color_red}Sentinel{nogc}] ==> {self.mod_config.sentinel}') except KeyError as ke: - self.Logs.error(f"Key Error : {ke}") + self.ctx.Logs.error(f"Key Error : {ke}") case 'info': try: if len(cmd) < 2: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Syntax. /msg {dnickname} INFO [nickname]") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Syntax. /msg {dnickname} INFO [nickname]") return None nickoruid = cmd[1] - UserObject = self.User.get_user(nickoruid) + UserObject = self.ctx.User.get_user(nickoruid) if UserObject is not None: - channels: list = [chan.name for chan in self.Channel.UID_CHANNEL_DB for uid_in_chan in chan.uids if self.Loader.Utils.clean_uid(uid_in_chan) == UserObject.uid] + channels: list = [chan.name for chan in self.ctx.Channel.UID_CHANNEL_DB for uid_in_chan in chan.uids if self.ctx.mod_utils.clean_uid(uid_in_chan) == UserObject.uid] - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' UID : {UserObject.uid}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' NICKNAME : {UserObject.nickname}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' USERNAME : {UserObject.username}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' REALNAME : {UserObject.realname}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' HOSTNAME : {UserObject.hostname}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' VHOST : {UserObject.vhost}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' IP : {UserObject.remote_ip}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Country : {UserObject.geoip}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' WebIrc : {UserObject.isWebirc}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' WebWebsocket : {UserObject.isWebsocket}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' REPUTATION : {UserObject.score_connexion}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' MODES : {UserObject.umodes}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' CHANNELS : {", ".join(channels)}') - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' CONNECTION TIME : {UserObject.connexion_datetime}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' UID : {UserObject.uid}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' NICKNAME : {UserObject.nickname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' USERNAME : {UserObject.username}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' REALNAME : {UserObject.realname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' HOSTNAME : {UserObject.hostname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' VHOST : {UserObject.vhost}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' IP : {UserObject.remote_ip}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' Country : {UserObject.geoip}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' WebIrc : {UserObject.isWebirc}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' WebWebsocket : {UserObject.isWebsocket}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' REPUTATION : {UserObject.score_connexion}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' MODES : {UserObject.umodes}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' CHANNELS : {", ".join(channels)}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' CONNECTION TIME : {UserObject.connexion_datetime}') else: - await self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {nickoruid} doesn't exist") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {nickoruid} doesn't exist") except KeyError as ke: - self.Logs.warning(f"Key error info user : {ke}") + self.ctx.Logs.warning(f"Key error info user : {ke}") case 'sentinel': # .sentinel on activation = str(cmd[1]).lower() - channel_to_dont_quit = [self.Config.SALON_JAIL, self.Config.SERVICE_CHANLOG] + channel_to_dont_quit = [self.ctx.Config.SALON_JAIL, self.ctx.Config.SERVICE_CHANLOG] if activation == 'on': - result = self.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.Config.TABLE_CHANNEL}") + result = await self.ctx.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.ctx.Config.TABLE_CHANNEL}") channels = result.fetchall() channel_in_db = [channel[0] for channel in channels] channel_to_dont_quit.extend(channel_in_db) - self.update_configuration('sentinel', 1) - for chan in self.Channel.UID_CHANNEL_DB: + await self.update_configuration('sentinel', 1) + for chan in self.ctx.Channel.UID_CHANNEL_DB: if chan.name not in channel_to_dont_quit: - await self.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name) - await self.Protocol.send_priv_msg(dnickname, f"Sentinel mode activated on {channel}", channel=chan.name) + await self.ctx.Irc.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name) + await self.ctx.Irc.Protocol.send_priv_msg(dnickname, f"Sentinel mode activated on {channel}", channel=chan.name) return None if activation == 'off': - result = self.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.Config.TABLE_CHANNEL}") + result = await self.ctx.Base.db_execute_query(f"SELECT distinct channel_name FROM {self.ctx.Config.TABLE_CHANNEL}") channels = result.fetchall() channel_in_db = [channel[0] for channel in channels] channel_to_dont_quit.extend(channel_in_db) - self.update_configuration('sentinel', 0) - for chan in self.Channel.UID_CHANNEL_DB: + await self.update_configuration('sentinel', 0) + for chan in self.ctx.Channel.UID_CHANNEL_DB: if chan.name not in channel_to_dont_quit: - await self.Protocol.send_part_chan(uidornickname=dnickname, channel=chan.name) - await self.Protocol.send_priv_msg(dnickname, f"Sentinel mode deactivated on {channel}", channel=chan.name) - self.join_saved_channels() + await self.ctx.Irc.Protocol.send_part_chan(uidornickname=dnickname, channel=chan.name) + await self.ctx.Irc.Protocol.send_priv_msg(dnickname, f"Sentinel mode deactivated on {channel}", channel=chan.name) + + await self.join_saved_channels() + return None diff --git a/mods/defender/threads.py b/mods/defender/threads.py index 9f00077..e785238 100644 --- a/mods/defender/threads.py +++ b/mods/defender/threads.py @@ -1,115 +1,116 @@ +import asyncio from typing import TYPE_CHECKING from time import sleep if TYPE_CHECKING: from mods.defender.mod_defender import Defender -def thread_apply_reputation_sanctions(uplink: 'Defender'): +async def coro_apply_reputation_sanctions(uplink: 'Defender'): while uplink.reputationTimer_isRunning: - uplink.Utils.action_apply_reputation_santions(uplink) - sleep(5) + await uplink.mod_utils.action_apply_reputation_santions(uplink) + await asyncio.sleep(5) -def thread_cloudfilt_scan(uplink: 'Defender'): +async def coro_cloudfilt_scan(uplink: 'Defender'): while uplink.cloudfilt_isRunning: list_to_remove:list = [] for user in uplink.Schemas.DB_CLOUDFILT_USERS: - uplink.Utils.action_scan_client_with_cloudfilt(uplink, user) + uplink.mod_utils.action_scan_client_with_cloudfilt(uplink, user) list_to_remove.append(user) - sleep(1) + await asyncio.sleep(1) for user_model in list_to_remove: uplink.Schemas.DB_CLOUDFILT_USERS.remove(user_model) - sleep(1) + await asyncio.sleep(1) -def thread_freeipapi_scan(uplink: 'Defender'): +async def coro_freeipapi_scan(uplink: 'Defender'): while uplink.freeipapi_isRunning: list_to_remove: list = [] for user in uplink.Schemas.DB_FREEIPAPI_USERS: - uplink.Utils.action_scan_client_with_freeipapi(uplink, user) + uplink.mod_utils.action_scan_client_with_freeipapi(uplink, user) list_to_remove.append(user) - sleep(1) + await asyncio.sleep(1) for user_model in list_to_remove: uplink.Schemas.DB_FREEIPAPI_USERS.remove(user_model) - sleep(1) + await asyncio.sleep(1) -def thread_abuseipdb_scan(uplink: 'Defender'): +async def coro_abuseipdb_scan(uplink: 'Defender'): while uplink.abuseipdb_isRunning: list_to_remove: list = [] for user in uplink.Schemas.DB_ABUSEIPDB_USERS: - uplink.Utils.action_scan_client_with_abuseipdb(uplink, user) + uplink.mod_utils.action_scan_client_with_abuseipdb(uplink, user) list_to_remove.append(user) - sleep(1) + await asyncio.sleep(1) for user_model in list_to_remove: uplink.Schemas.DB_ABUSEIPDB_USERS.remove(user_model) - sleep(1) + await asyncio.sleep(1) -def thread_local_scan(uplink: 'Defender'): +async def coro_local_scan(uplink: 'Defender'): while uplink.localscan_isRunning: list_to_remove:list = [] for user in uplink.Schemas.DB_LOCALSCAN_USERS: - uplink.Utils.action_scan_client_with_local_socket(uplink, user) + uplink.mod_utils.action_scan_client_with_local_socket(uplink, user) list_to_remove.append(user) - sleep(1) + await asyncio.sleep(1) for user_model in list_to_remove: uplink.Schemas.DB_LOCALSCAN_USERS.remove(user_model) - sleep(1) + await asyncio.sleep(1) -def thread_psutil_scan(uplink: 'Defender'): +async def coro_psutil_scan(uplink: 'Defender'): while uplink.psutil_isRunning: list_to_remove:list = [] for user in uplink.Schemas.DB_PSUTIL_USERS: - uplink.Utils.action_scan_client_with_psutil(uplink, user) + uplink.mod_utils.action_scan_client_with_psutil(uplink, user) list_to_remove.append(user) - sleep(1) + await asyncio.sleep(1) for user_model in list_to_remove: uplink.Schemas.DB_PSUTIL_USERS.remove(user_model) - sleep(1) + await asyncio.sleep(1) -def thread_autolimit(uplink: 'Defender'): +async def coro_autolimit(uplink: 'Defender'): - if uplink.ModConfig.autolimit == 0: - uplink.Logs.debug("autolimit deactivated ... canceling the thread") + if uplink.mod_config.autolimit == 0: + uplink.ctx.Logs.debug("autolimit deactivated ... canceling the thread") return None - while uplink.Irc.autolimit_started: - sleep(0.2) + while uplink.ctx.Irc.autolimit_started: + await asyncio.sleep(0.2) - uplink.Irc.autolimit_started = True - init_amount = uplink.ModConfig.autolimit_amount - p = uplink.Protocol + uplink.ctx.Irc.autolimit_started = True + init_amount = uplink.mod_config.autolimit_amount + p = uplink.ctx.Irc.Protocol INIT = 1 # Copy Channels to a list of dict - chanObj_copy: list[dict[str, int]] = [{"name": c.name, "uids_count": len(c.uids)} for c in uplink.Channel.UID_CHANNEL_DB] - chan_list: list[str] = [c.name for c in uplink.Channel.UID_CHANNEL_DB] + chanObj_copy: list[dict[str, int]] = [{"name": c.name, "uids_count": len(c.uids)} for c in uplink.ctx.Channel.UID_CHANNEL_DB] + chan_list: list[str] = [c.name for c in uplink.ctx.Channel.UID_CHANNEL_DB] while uplink.autolimit_isRunning: - if uplink.ModConfig.autolimit == 0: - uplink.Logs.debug("autolimit deactivated ... stopping the current thread") + if uplink.mod_config.autolimit == 0: + uplink.ctx.Logs.debug("autolimit deactivated ... stopping the current thread") break - for chan in uplink.Channel.UID_CHANNEL_DB: + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: for chan_copy in chanObj_copy: if chan_copy["name"] == chan.name and len(chan.uids) != chan_copy["uids_count"]: - p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}") + await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}") chan_copy["uids_count"] = len(chan.uids) if chan.name not in chan_list: @@ -117,51 +118,55 @@ def thread_autolimit(uplink: 'Defender'): chanObj_copy.append({"name": chan.name, "uids_count": 0}) # Verifier si un salon a été vidé - current_chan_in_list = [d.name for d in uplink.Channel.UID_CHANNEL_DB] + current_chan_in_list = [d.name for d in uplink.ctx.Channel.UID_CHANNEL_DB] for c in chan_list: if c not in current_chan_in_list: chan_list.remove(c) # Si c'est la premiere execution if INIT == 1: - for chan in uplink.Channel.UID_CHANNEL_DB: - p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}") + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: + await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}") # Si le nouveau amount est différent de l'initial - if init_amount != uplink.ModConfig.autolimit_amount: - init_amount = uplink.ModConfig.autolimit_amount - for chan in uplink.Channel.UID_CHANNEL_DB: - p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.ModConfig.autolimit_amount}") + if init_amount != uplink.mod_config.autolimit_amount: + init_amount = uplink.mod_config.autolimit_amount + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: + await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + uplink.mod_config.autolimit_amount}") INIT = 0 if uplink.autolimit_isRunning: - sleep(uplink.ModConfig.autolimit_interval) + await asyncio.sleep(uplink.mod_config.autolimit_interval) - for chan in uplink.Channel.UID_CHANNEL_DB: - p.send2socket(f":{uplink.Config.SERVICE_ID} MODE {chan.name} -l") + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: + # await p.send2socket(f":{uplink.ctx.Config.SERVICE_ID} MODE {chan.name} -l") + await p.send_set_mode('-l', channel_name=chan.name) - uplink.Irc.autolimit_started = False + uplink.ctx.Irc.autolimit_started = False return None -def timer_release_mode_mute(uplink: 'Defender', action: str, channel: str): - """DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING +async def coro_release_mode_mute(uplink: 'Defender', action: str, channel: str): + """DO NOT EXECUTE THIS FUNCTION DIRECTLY + IT WILL BLOCK THE PROCESS Args: - action (str): _description_ + action (str): mode-m channel (str): The related channel """ - service_id = uplink.Config.SERVICE_ID + service_id = uplink.ctx.Config.SERVICE_ID + timeout = uplink.mod_config.flood_timer + await asyncio.sleep(timeout) - if not uplink.Channel.is_valid_channel(channel): - uplink.Logs.debug(f"Channel is not valid {channel}") + if not uplink.ctx.Channel.is_valid_channel(channel): + uplink.ctx.Logs.debug(f"Channel is not valid {channel}") return match action: case 'mode-m': # Action -m sur le salon - uplink.Protocol.send2socket(f":{service_id} MODE {channel} -m") + await uplink.ctx.Irc.Protocol.send2socket(f":{service_id} MODE {channel} -m") case _: pass diff --git a/mods/defender/utils.py b/mods/defender/utils.py index a930600..a880a42 100644 --- a/mods/defender/utils.py +++ b/mods/defender/utils.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Optional from mods.defender.schemas import FloodUser if TYPE_CHECKING: + from core.loader import Loader from core.definition import MUser from mods.defender.mod_defender import Defender @@ -28,10 +29,10 @@ def handle_on_reputation(uplink: 'Defender', srvmsg: list[str]): return # Possibilité de déclancher les bans a ce niveau. - if not uplink.Base.is_valid_ip(ip): + if not uplink.ctx.Base.is_valid_ip(ip): return -def handle_on_mode(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_mode(uplink: 'Defender', srvmsg: list[str]): """_summary_ >>> srvmsg = ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1'] >>> srvmsg = ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users'] @@ -40,10 +41,10 @@ def handle_on_mode(uplink: 'Defender', srvmsg: list[str]): srvmsg (list[str]): The Server MSG confmodel (ModConfModel): The Module Configuration """ - irc = uplink.Irc - gconfig = uplink.Config - p = uplink.Protocol - confmodel = uplink.ModConfig + irc = uplink.ctx.Irc + gconfig = uplink.ctx.Config + p = irc.Protocol + confmodel = uplink.mod_config channel = str(srvmsg[3]) mode = str(srvmsg[4]) @@ -52,25 +53,25 @@ def handle_on_mode(uplink: 'Defender', srvmsg: list[str]): if confmodel.autolimit == 1: if mode == '+l' or mode == '-l': - chan = irc.Channel.get_channel(channel) - p.send2socket(f":{gconfig.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + confmodel.autolimit_amount}") + chan = uplink.ctx.Channel.get_channel(channel) + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + confmodel.autolimit_amount}") if gconfig.SALON_JAIL == channel: if mode == '+b' and group_to_unban in group_to_check: - p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -b ~security-group:unknown-users") - p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -b ~security-group:unknown-users") + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {gconfig.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") -def handle_on_privmsg(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_privmsg(uplink: 'Defender', srvmsg: list[str]): # ['@mtag....',':python', 'PRIVMSG', '#defender', ':zefzefzregreg', 'regg', 'aerg'] - sender, reciever, channel, message = uplink.Protocol.parse_privmsg(srvmsg) - if uplink.ModConfig.sentinel == 1 and channel.name != uplink.Config.SERVICE_CHANLOG: - uplink.Protocol.send_priv_msg(uplink.Config.SERVICE_NICKNAME, f"{sender.nickname} say on {channel.name}: {' '.join(message)}", uplink.Config.SERVICE_CHANLOG) + sender, reciever, channel, message = uplink.ctx.Irc.Protocol.parse_privmsg(srvmsg) + if uplink.mod_config.sentinel == 1 and channel.name != uplink.ctx.Config.SERVICE_CHANLOG: + await uplink.ctx.Irc.Protocol.send_priv_msg(uplink.ctx.Config.SERVICE_NICKNAME, f"{sender.nickname} say on {channel.name}: {' '.join(message)}", uplink.ctx.Config.SERVICE_CHANLOG) - action_on_flood(uplink, srvmsg) + await action_on_flood(uplink, srvmsg) return None -def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]): """If Joining a new channel, it applies group bans. >>> srvmsg = ['@msgid..', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL'] @@ -80,37 +81,37 @@ def handle_on_sjoin(uplink: 'Defender', srvmsg: list[str]): srvmsg (list[str]): The Server MSG confmodel (ModConfModel): The Module Configuration """ - irc = uplink.Irc + irc = uplink.ctx.Irc p = irc.Protocol - gconfig = uplink.Config - confmodel = uplink.ModConfig + gconfig = uplink.ctx.Config + confmodel = uplink.mod_config - parsed_chan = srvmsg[4] if irc.Channel.is_valid_channel(srvmsg[4]) else None - parsed_UID = uplink.Loader.Utils.clean_uid(srvmsg[5]) + parsed_chan = srvmsg[4] if uplink.ctx.Channel.is_valid_channel(srvmsg[4]) else None + parsed_UID = uplink.ctx.Utils.clean_uid(srvmsg[5]) if parsed_chan is None or parsed_UID is None: return if confmodel.reputation == 1: - get_reputation = irc.Reputation.get_reputation(parsed_UID) + get_reputation = uplink.ctx.Reputation.get_reputation(parsed_UID) if parsed_chan != gconfig.SALON_JAIL: - p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b ~security-group:unknown-users") - p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b ~security-group:unknown-users") + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users") if get_reputation is not None: isWebirc = get_reputation.isWebirc if not isWebirc: if parsed_chan != gconfig.SALON_JAIL: - p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan) + await p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan) if confmodel.reputation_ban_all_chan == 1 and not isWebirc: if parsed_chan != gconfig.SALON_JAIL: - p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b {get_reputation.nickname}!*@*") - p.send2socket(f":{gconfig.SERVICE_ID} KICK {parsed_chan} {get_reputation.nickname}") + await p.send2socket(f":{gconfig.SERVICE_ID} MODE {parsed_chan} +b {get_reputation.nickname}!*@*") + await p.send2socket(f":{gconfig.SERVICE_ID} KICK {parsed_chan} {get_reputation.nickname}") - irc.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}') + uplink.ctx.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}') def handle_on_slog(uplink: 'Defender', srvmsg: list[str]): """Handling SLOG messages @@ -122,27 +123,27 @@ def handle_on_slog(uplink: 'Defender', srvmsg: list[str]): """ ['@unrealircd...', ':001', 'SLOG', 'info', 'blacklist', 'BLACKLIST_HIT', ':[Blacklist]', 'IP', '162.x.x.x', 'matches', 'blacklist', 'dronebl', '(dnsbl.dronebl.org/reply=6)'] - if not uplink.Base.is_valid_ip(srvmsg[8]): + if not uplink.ctx.Base.is_valid_ip(srvmsg[8]): return None - # if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: + # if self.mod_config.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # self.localscan_remote_ip.append(cmd[7]) - # if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: + # if self.mod_config.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # self.psutil_remote_ip.append(cmd[7]) - # if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: + # if self.mod_config.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # self.abuseipdb_remote_ip.append(cmd[7]) - # if self.ModConfig.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: + # if self.mod_config.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # self.freeipapi_remote_ip.append(cmd[7]) - # if self.ModConfig.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: + # if self.mod_config.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # self.cloudfilt_remote_ip.append(cmd[7]) return None -def handle_on_nick(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_nick(uplink: 'Defender', srvmsg: list[str]): """Handle nickname changes. >>> srvmsg = ['@unrealircd.org...', ':001MZQ0RB', 'NICK', 'newnickname', '1754663712'] >>> [':97KAAAAAC', 'NICK', 'testinspir', '1757360740'] @@ -151,22 +152,22 @@ def handle_on_nick(uplink: 'Defender', srvmsg: list[str]): srvmsg (list[str]): The Server MSG confmodel (ModConfModel): The Module Configuration """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol u, new_nickname, timestamp = p.parse_nick(srvmsg) if u is None: - uplink.Logs.error(f"[USER OBJ ERROR {timestamp}] - {srvmsg}") + uplink.ctx.Logs.error(f"[USER OBJ ERROR {timestamp}] - {srvmsg}") return None uid = u.uid - confmodel = uplink.ModConfig + confmodel = uplink.mod_config - get_reputation = uplink.Reputation.get_reputation(uid) - jail_salon = uplink.Config.SALON_JAIL - service_id = uplink.Config.SERVICE_ID + get_reputation = uplink.ctx.Reputation.get_reputation(uid) + jail_salon = uplink.ctx.Config.SALON_JAIL + service_id = uplink.ctx.Config.SERVICE_ID if get_reputation is None: - uplink.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass') + uplink.ctx.Logs.debug(f'This UID: {uid} is not listed in the reputation dataclass') return None # Update the new nickname @@ -176,42 +177,42 @@ def handle_on_nick(uplink: 'Defender', srvmsg: list[str]): # If ban in all channel is ON then unban old nickname an ban the new nickname if confmodel.reputation_ban_all_chan == 1: - for chan in uplink.Channel.UID_CHANNEL_DB: + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: if chan.name != jail_salon: - p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*") - p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*") + await p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*") + await p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*") -def handle_on_quit(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_quit(uplink: 'Defender', srvmsg: list[str]): """Handle on quit message >>> srvmsg = ['@unrealircd.org...', ':001MZQ0RB', 'QUIT', ':Quit:', 'quit message'] Args: uplink (Irc): The Defender Module instance srvmsg (list[str]): The Server MSG """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol userobj, reason = p.parse_quit(srvmsg) - confmodel = uplink.ModConfig + confmodel = uplink.mod_config if userobj is None: - uplink.Logs.debug(f"This UID do not exist anymore: {srvmsg}") + uplink.ctx.Logs.debug(f"This UID do not exist anymore: {srvmsg}") return None - ban_all_chan = uplink.Base.int_if_possible(confmodel.reputation_ban_all_chan) - jail_salon = uplink.Config.SALON_JAIL - service_id = uplink.Config.SERVICE_ID - get_user_reputation = uplink.Reputation.get_reputation(userobj.uid) + ban_all_chan = uplink.ctx.Base.int_if_possible(confmodel.reputation_ban_all_chan) + jail_salon = uplink.ctx.Config.SALON_JAIL + service_id = uplink.ctx.Config.SERVICE_ID + get_user_reputation = uplink.ctx.Reputation.get_reputation(userobj.uid) if get_user_reputation is not None: final_nickname = get_user_reputation.nickname - for chan in uplink.Channel.UID_CHANNEL_DB: + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: if chan.name != jail_salon and ban_all_chan == 1: - p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*") - uplink.Logs.debug(f"Mode -b {final_nickname} on channel {chan.name}") + await p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*") + uplink.ctx.Logs.debug(f"Mode -b {final_nickname} on channel {chan.name}") - uplink.Reputation.delete(userobj.uid) - uplink.Logs.debug(f"Client {get_user_reputation.nickname} has been removed from Reputation local DB") + uplink.ctx.Reputation.delete(userobj.uid) + uplink.ctx.Logs.debug(f"Client {get_user_reputation.nickname} has been removed from Reputation local DB") -def handle_on_uid(uplink: 'Defender', srvmsg: list[str]): +async def handle_on_uid(uplink: 'Defender', srvmsg: list[str]): """_summary_ >>> ['@s2s-md...', ':001', 'UID', 'nickname', '0', '1754675249', '...', '125-168-141-239.hostname.net', '001BAPN8M', '0', '+iwx', '*', '32001BBE.25ACEFE7.429FE90D.IP', 'ZA2ic7w==', ':realname'] @@ -220,10 +221,10 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]): uplink (Defender): The Defender instance srvmsg (list[str]): The Server MSG """ - _User = uplink.Protocol.parse_uid(srvmsg) - gconfig = uplink.Config - irc = uplink.Irc - confmodel = uplink.ModConfig + irc = uplink.ctx.Irc + _User = irc.Protocol.parse_uid(srvmsg) + gconfig = uplink.ctx.Config + confmodel = uplink.mod_config # If Init then do nothing if gconfig.DEFENDER_INIT == 1: @@ -231,7 +232,7 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]): # Get User information if _User is None: - irc.Logs.warning(f'Error when parsing UID', exc_info=True) + uplink.ctx.Logs.warning(f'Error when parsing UID', exc_info=True) return # If user is not service or IrcOp then scan them @@ -250,38 +251,38 @@ def handle_on_uid(uplink: 'Defender', srvmsg: list[str]): if not match(r'^.*[S|o?].*$', _User.umodes): if reputation_flag == 1 and _User.score_connexion <= reputation_seuil: # currentDateTime = self.Base.get_datetime() - irc.Reputation.insert( - irc.Loader.Definition.MReputation( + uplink.ctx.Reputation.insert( + uplink.ctx.Definition.MReputation( **_User.to_dict(), - secret_code=irc.Utils.generate_random_string(8) + secret_code=uplink.ctx.Utils.generate_random_string(8) ) ) - if irc.Reputation.is_exist(_User.uid): + if uplink.ctx.Reputation.is_exist(_User.uid): if reputation_flag == 1 and _User.score_connexion <= reputation_seuil: - action_add_reputation_sanctions(uplink, _User.uid) - irc.Logs.info(f'[REPUTATION] Reputation system ON (Nickname: {_User.nickname}, uid: {_User.uid})') + await action_add_reputation_sanctions(uplink, _User.uid) + uplink.ctx.Logs.info(f'[REPUTATION] Reputation system ON (Nickname: {_User.nickname}, uid: {_User.uid})') #################### # ACTION FUNCTIONS # #################### # [:] UID []+ : # [:] UID nickname hopcount timestamp username hostname uid servicestamp umodes virthost cloakedhost ip :gecos -def action_on_flood(uplink: 'Defender', srvmsg: list[str]): +async def action_on_flood(uplink: 'Defender', srvmsg: list[str]): - confmodel = uplink.ModConfig + confmodel = uplink.mod_config if confmodel.flood == 0: return None - irc = uplink.Irc - gconfig = uplink.Config - p = uplink.Protocol + irc = uplink.ctx.Irc + gconfig = uplink.ctx.Config + p = irc.Protocol flood_users = uplink.Schemas.DB_FLOOD_USERS user_trigger = str(srvmsg[1]).replace(':','') channel = srvmsg[3] - User = irc.User.get_user(user_trigger) + User = uplink.ctx.User.get_user(user_trigger) - if User is None or not irc.Channel.is_valid_channel(channel_to_check=channel): + if User is None or not uplink.ctx.Channel.is_valid_channel(channel_to_check=channel): return flood_time = confmodel.flood_time @@ -294,7 +295,7 @@ def action_on_flood(uplink: 'Defender', srvmsg: list[str]): get_detected_uid = User.uid get_detected_nickname = User.nickname - unixtime = irc.Utils.get_unixtime() + unixtime = uplink.ctx.Utils.get_unixtime() get_diff_secondes = 0 def get_flood_user(uid: str) -> Optional[FloodUser]: @@ -315,29 +316,29 @@ def action_on_flood(uplink: 'Defender', srvmsg: list[str]): fu.nbr_msg = 0 get_diff_secondes = unixtime - fu.first_msg_time elif fu.nbr_msg > flood_message: - irc.Logs.info('system de flood detecté') - p.send_priv_msg( + uplink.ctx.Logs.info('system de flood detecté') + await p.send_priv_msg( nick_from=dnickname, msg=f"{color_red} {color_bold} Flood detected. Apply the +m mode (Ô_o)", channel=channel ) - p.send2socket(f":{service_id} MODE {channel} +m") - irc.Logs.info(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}') + await p.send2socket(f":{service_id} MODE {channel} +m") + uplink.ctx.Logs.info(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}') fu.nbr_msg = 0 fu.first_msg_time = unixtime - irc.Base.create_timer(flood_timer, dthreads.timer_release_mode_mute, (uplink, 'mode-m', channel)) + uplink.ctx.Base.create_asynctask(dthreads.coro_release_mode_mute(uplink, 'mode-m', channel)) -def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ): +async def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ): - irc = uplink.Irc - gconfig = uplink.Config - p = uplink.Protocol - confmodel = uplink.ModConfig + irc = uplink.ctx.Irc + gconfig = uplink.ctx.Config + p = irc.Protocol + confmodel = uplink.mod_config - get_reputation = irc.Reputation.get_reputation(jailed_uid) + get_reputation = uplink.ctx.Reputation.get_reputation(jailed_uid) if get_reputation is None: - irc.Logs.warning(f'UID {jailed_uid} has not been found') + uplink.ctx.Logs.warning(f'UID {jailed_uid} has not been found') return salon_logs = gconfig.SERVICE_CHANLOG @@ -357,33 +358,33 @@ def action_add_reputation_sanctions(uplink: 'Defender', jailed_uid: str ): if not get_reputation.isWebirc: # Si le user ne vient pas de webIrc - p.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=salon_jail) - p.send_priv_msg(nick_from=gconfig.SERVICE_NICKNAME, + await p.send_sajoin(nick_to_sajoin=jailed_nickname, channel_name=salon_jail) + await p.send_priv_msg(nick_from=gconfig.SERVICE_NICKNAME, msg=f" [{color_red} REPUTATION {nogc}] : Connexion de {jailed_nickname} ({jailed_score}) ==> {salon_jail}", channel=salon_logs ) - p.send_notice( + await p.send_notice( nick_from=gconfig.SERVICE_NICKNAME, nick_to=jailed_nickname, msg=f"[{color_red} {jailed_nickname} {color_black}] : Merci de tapez la commande suivante {color_bold}{service_prefix}code {code}{color_bold}" ) if reputation_ban_all_chan == 1: - for chan in irc.Channel.UID_CHANNEL_DB: + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: if chan.name != salon_jail: - p.send2socket(f":{service_id} MODE {chan.name} +b {jailed_nickname}!*@*") - p.send2socket(f":{service_id} KICK {chan.name} {jailed_nickname}") + await p.send2socket(f":{service_id} MODE {chan.name} +b {jailed_nickname}!*@*") + await p.send2socket(f":{service_id} KICK {chan.name} {jailed_nickname}") - irc.Logs.info(f"[REPUTATION] {jailed_nickname} jailed (UID: {jailed_uid}, score: {jailed_score})") + uplink.ctx.Logs.info(f"[REPUTATION] {jailed_nickname} jailed (UID: {jailed_uid}, score: {jailed_score})") else: - irc.Logs.info(f"[REPUTATION] {jailed_nickname} skipped (trusted or WebIRC)") - irc.Reputation.delete(jailed_uid) + uplink.ctx.Logs.info(f"[REPUTATION] {jailed_nickname} skipped (trusted or WebIRC)") + uplink.ctx.Reputation.delete(jailed_uid) -def action_apply_reputation_santions(uplink: 'Defender') -> None: +async def action_apply_reputation_santions(uplink: 'Defender') -> None: - irc = uplink.Irc - gconfig = uplink.Config - p = uplink.Protocol - confmodel = uplink.ModConfig + irc = uplink.ctx.Irc + gconfig = uplink.ctx.Config + p = irc.Protocol + confmodel = uplink.mod_config reputation_flag = confmodel.reputation reputation_timer = confmodel.reputation_timer @@ -396,36 +397,36 @@ def action_apply_reputation_santions(uplink: 'Defender') -> None: salon_jail = gconfig.SALON_JAIL uid_to_clean = [] - if reputation_flag == 0 or reputation_timer == 0 or not irc.Reputation.UID_REPUTATION_DB: + if reputation_flag == 0 or reputation_timer == 0 or not uplink.ctx.Reputation.UID_REPUTATION_DB: return None - for user in irc.Reputation.UID_REPUTATION_DB: + for user in uplink.ctx.Reputation.UID_REPUTATION_DB: if not user.isWebirc: # Si il ne vient pas de WebIRC - if irc.User.get_user_uptime_in_minutes(user.uid) >= reputation_timer and int(user.score_connexion) <= int(reputation_seuil): - p.send_priv_msg( + if uplink.ctx.User.get_user_uptime_in_minutes(user.uid) >= reputation_timer and int(user.score_connexion) <= int(reputation_seuil): + await p.send_priv_msg( nick_from=service_id, msg=f"[{color_red} REPUTATION {nogc}] : Action sur {user.nickname} aprés {str(reputation_timer)} minutes d'inactivité", channel=dchanlog ) - p.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code") - p.send2socket(f":{gconfig.SERVEUR_LINK} REPUTATION {user.remote_ip} 0") + await p.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code") + await p.send2socket(f":{gconfig.SERVEUR_LINK} REPUTATION {user.remote_ip} 0") - irc.Logs.info(f"Nickname: {user.nickname} KILLED after {str(reputation_timer)} minutes of inactivity") + uplink.ctx.Logs.info(f"Nickname: {user.nickname} KILLED after {str(reputation_timer)} minutes of inactivity") uid_to_clean.append(user.uid) for uid in uid_to_clean: # Suppression des éléments dans {UID_DB} et {REPUTATION_DB} - for chan in irc.Channel.UID_CHANNEL_DB: + for chan in uplink.ctx.Channel.UID_CHANNEL_DB: if chan.name != salon_jail and ban_all_chan == 1: - get_user_reputation = irc.Reputation.get_reputation(uid) - p.send2socket(f":{service_id} MODE {chan.name} -b {get_user_reputation.nickname}!*@*") + get_user_reputation = uplink.ctx.Reputation.get_reputation(uid) + await p.send2socket(f":{service_id} MODE {chan.name} -b {get_user_reputation.nickname}!*@*") # Lorsqu'un utilisateur quitte, il doit être supprimé de {UID_DB}. - irc.Channel.delete_user_from_all_channel(uid) - irc.Reputation.delete(uid) - irc.User.delete(uid) + uplink.ctx.Channel.delete_user_from_all_channel(uid) + uplink.ctx.Reputation.delete(uid) + uplink.ctx.User.delete(uid) -def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: +async def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: """Analyse l'ip avec cloudfilt Cette methode devra etre lancer toujours via un thread ou un timer. Args: @@ -440,19 +441,19 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') - username = user_model.username hostname = user_model.hostname nickname = user_model.nickname - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol - if remote_ip in uplink.Config.WHITELISTED_IP: + if remote_ip in uplink.ctx.Config.WHITELISTED_IP: return None - if uplink.ModConfig.cloudfilt_scan == 0: + if uplink.mod_config.cloudfilt_scan == 0: return None if uplink.cloudfilt_key == '': return None - service_id = uplink.Config.SERVICE_ID - service_chanlog = uplink.Config.SERVICE_CHANLOG - color_red = uplink.Config.COLORS.red - nogc = uplink.Config.COLORS.nogc + service_id = uplink.ctx.Config.SERVICE_ID + service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG + color_red = uplink.ctx.Config.COLORS.red + nogc = uplink.ctx.Config.COLORS.nogc url = "https://developers18334.cloudfilt.com/" @@ -466,7 +467,7 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') - decoded_response: dict = loads(response.text) status_code = response.status_code if status_code != 200: - uplink.Logs.warning(f'Error connecting to cloudfilt API | Code: {str(status_code)}') + uplink.ctx.Logs.warning(f'Error connecting to cloudfilt API | Code: {str(status_code)}') return result = { @@ -479,22 +480,22 @@ def action_scan_client_with_cloudfilt(uplink: 'Defender', user_model: 'MUser') - # pseudo!ident@host fullname = f'{nickname}!{username}@{hostname}' - p.send_priv_msg( + await p.send_priv_msg( nick_from=service_id, msg=f"[ {color_red}CLOUDFILT_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Host: {str(result['host'])} | country: {str(result['countryiso'])} | listed: {str(result['listed'])} | listed by : {str(result['listed_by'])}", channel=service_chanlog) - uplink.Logs.debug(f"[CLOUDFILT SCAN] ({fullname}) connected from ({result['countryiso']}), Listed: {result['listed']}, by: {result['listed_by']}") + uplink.ctx.Logs.debug(f"[CLOUDFILT SCAN] ({fullname}) connected from ({result['countryiso']}), Listed: {result['listed']}, by: {result['listed_by']}") if result['listed']: - p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} Your connexion is listed as dangerous {str(result['listed'])} {str(result['listed_by'])} - detected by cloudfilt") - uplink.Logs.debug(f"[CLOUDFILT SCAN GLINE] Dangerous connection ({fullname}) from ({result['countryiso']}) Listed: {result['listed']}, by: {result['listed_by']}") + await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} Your connexion is listed as dangerous {str(result['listed'])} {str(result['listed_by'])} - detected by cloudfilt") + uplink.ctx.Logs.debug(f"[CLOUDFILT SCAN GLINE] Dangerous connection ({fullname}) from ({result['countryiso']}) Listed: {result['listed']}, by: {result['listed_by']}") response.close() return result -def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: +async def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: """Analyse l'ip avec Freeipapi Cette methode devra etre lancer toujours via un thread ou un timer. Args: @@ -504,21 +505,21 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') - dict[str, any] | None: les informations du provider keys : 'countryCode', 'isProxy' """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol remote_ip = user_model.remote_ip username = user_model.username hostname = user_model.hostname nickname = user_model.nickname - if remote_ip in uplink.Config.WHITELISTED_IP: + if remote_ip in uplink.ctx.Config.WHITELISTED_IP: return None - if uplink.ModConfig.freeipapi_scan == 0: + if uplink.mod_config.freeipapi_scan == 0: return None - service_id = uplink.Config.SERVICE_ID - service_chanlog = uplink.Config.SERVICE_CHANLOG - color_red = uplink.Config.COLORS.red - nogc = uplink.Config.COLORS.nogc + service_id = uplink.ctx.Config.SERVICE_ID + service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG + color_red = uplink.ctx.Config.COLORS.red + nogc = uplink.ctx.Config.COLORS.nogc url = f'https://freeipapi.com/api/json/{remote_ip}' @@ -533,10 +534,10 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') - status_code = response.status_code if status_code == 429: - uplink.Logs.warning('Too Many Requests - The rate limit for the API has been exceeded.') + uplink.ctx.Logs.warning('Too Many Requests - The rate limit for the API has been exceeded.') return None elif status_code != 200: - uplink.Logs.warning(f'status code = {str(status_code)}') + uplink.ctx.Logs.warning(f'status code = {str(status_code)}') return None result = { @@ -547,21 +548,21 @@ def action_scan_client_with_freeipapi(uplink: 'Defender', user_model: 'MUser') - # pseudo!ident@host fullname = f'{nickname}!{username}@{hostname}' - p.send_priv_msg( + await p.send_priv_msg( nick_from=service_id, msg=f"[ {color_red}FREEIPAPI_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Proxy: {str(result['isProxy'])} | Country : {str(result['countryCode'])}", channel=service_chanlog) - uplink.Logs.debug(f"[FREEIPAPI SCAN] ({fullname}) connected from ({result['countryCode']}), Proxy: {result['isProxy']}") + uplink.ctx.Logs.debug(f"[FREEIPAPI SCAN] ({fullname}) connected from ({result['countryCode']}), Proxy: {result['isProxy']}") if result['isProxy']: - p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} This server do not allow proxy connexions {str(result['isProxy'])} - detected by freeipapi") - uplink.Logs.debug(f"[FREEIPAPI SCAN GLINE] Server do not allow proxy connexions {result['isProxy']}") + await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} This server do not allow proxy connexions {str(result['isProxy'])} - detected by freeipapi") + uplink.ctx.Logs.debug(f"[FREEIPAPI SCAN GLINE] Server do not allow proxy connexions {result['isProxy']}") response.close() return result -def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: +async def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') -> Optional[dict[str, str]]: """Analyse l'ip avec AbuseIpDB Cette methode devra etre lancer toujours via un thread ou un timer. Args: @@ -571,15 +572,15 @@ def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') - Returns: dict[str, str] | None: les informations du provider """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol remote_ip = user_model.remote_ip username = user_model.username hostname = user_model.hostname nickname = user_model.nickname - if remote_ip in uplink.Config.WHITELISTED_IP: + if remote_ip in uplink.ctx.Config.WHITELISTED_IP: return None - if uplink.ModConfig.abuseipdb_scan == 0: + if uplink.mod_config.abuseipdb_scan == 0: return None if uplink.abuseipdb_key == '': @@ -611,81 +612,81 @@ def action_scan_client_with_abuseipdb(uplink: 'Defender', user_model: 'MUser') - 'totalReports': decoded_response.get('data', {}).get('totalReports', 0) } - service_id = uplink.Config.SERVICE_ID - service_chanlog = uplink.Config.SERVICE_CHANLOG - color_red = uplink.Config.COLORS.red - nogc = uplink.Config.COLORS.nogc + service_id = uplink.ctx.Config.SERVICE_ID + service_chanlog = uplink.ctx.Config.SERVICE_CHANLOG + color_red = uplink.ctx.Config.COLORS.red + nogc = uplink.ctx.Config.COLORS.nogc # pseudo!ident@host fullname = f'{nickname}!{username}@{hostname}' - p.send_priv_msg( + await p.send_priv_msg( nick_from=service_id, msg=f"[ {color_red}ABUSEIPDB_SCAN{nogc} ] : Connexion de {fullname} ({remote_ip}) ==> Score: {str(result['score'])} | Country : {result['country']} | Tor : {str(result['isTor'])} | Total Reports : {str(result['totalReports'])}", channel=service_chanlog ) - uplink.Logs.debug(f"[ABUSEIPDB SCAN] ({fullname}) connected from ({result['country']}), Score: {result['score']}, Tor: {result['isTor']}") + uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN] ({fullname}) connected from ({result['country']}), Score: {result['score']}, Tor: {result['isTor']}") if result['isTor']: - p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} This server do not allow Tor connexions {str(result['isTor'])} - Detected by Abuseipdb") - uplink.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not allow Tor connections Tor: {result['isTor']}, Score: {result['score']}") + await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} This server do not allow Tor connexions {str(result['isTor'])} - Detected by Abuseipdb") + uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not allow Tor connections Tor: {result['isTor']}, Score: {result['score']}") elif result['score'] >= 95: - p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.Config.GLINE_DURATION} You were banned from this server because your abuse score is = {str(result['score'])} - Detected by Abuseipdb") - uplink.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not high risk connections Country: {result['country']}, Score: {result['score']}") + await p.send2socket(f":{service_id} GLINE +*@{remote_ip} {uplink.ctx.Config.GLINE_DURATION} You were banned from this server because your abuse score is = {str(result['score'])} - Detected by Abuseipdb") + uplink.ctx.Logs.debug(f"[ABUSEIPDB SCAN GLINE] Server do not high risk connections Country: {result['country']}, Score: {result['score']}") response.close() return result -def action_scan_client_with_local_socket(uplink: 'Defender', user_model: 'MUser'): +async def action_scan_client_with_local_socket(uplink: 'Defender', user_model: 'MUser'): """local_scan Args: uplink (Defender): Defender instance object user_model (MUser): l'objet User qui contient l'ip """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol remote_ip = user_model.remote_ip username = user_model.username hostname = user_model.hostname nickname = user_model.nickname fullname = f'{nickname}!{username}@{hostname}' - if remote_ip in uplink.Config.WHITELISTED_IP: + if remote_ip in uplink.ctx.Config.WHITELISTED_IP: return None - for port in uplink.Config.PORTS_TO_SCAN: + for port in uplink.ctx.Config.PORTS_TO_SCAN: try: newSocket = '' newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM or socket.SOCK_NONBLOCK) newSocket.settimeout(0.5) - connection = (remote_ip, uplink.Base.int_if_possible(port)) + connection = (remote_ip, uplink.ctx.Base.int_if_possible(port)) newSocket.connect(connection) - p.send_priv_msg( - nick_from=uplink.Config.SERVICE_NICKNAME, - msg=f"[ {uplink.Config.COLORS.red}PROXY_SCAN{uplink.Config.COLORS.nogc} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]", - channel=uplink.Config.SERVICE_CHANLOG + await p.send_priv_msg( + nick_from=uplink.ctx.Config.SERVICE_NICKNAME, + msg=f"[ {uplink.ctx.Config.COLORS.red}PROXY_SCAN{uplink.ctx.Config.COLORS.nogc} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]", + channel=uplink.ctx.Config.SERVICE_CHANLOG ) # print(f"=======> Le port {str(port)} est ouvert !!") - uplink.Base.running_sockets.append(newSocket) + uplink.ctx.Base.running_sockets.append(newSocket) # print(newSocket) newSocket.shutdown(socket.SHUT_RDWR) newSocket.close() except (socket.timeout, ConnectionRefusedError): - uplink.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé") + uplink.ctx.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé") except AttributeError as ae: - uplink.Logs.warning(f"AttributeError ({remote_ip}): {ae}") + uplink.ctx.Logs.warning(f"AttributeError ({remote_ip}): {ae}") except socket.gaierror as err: - uplink.Logs.warning(f"Address Info Error ({remote_ip}): {err}") + uplink.ctx.Logs.warning(f"Address Info Error ({remote_ip}): {err}") finally: # newSocket.shutdown(socket.SHUT_RDWR) newSocket.close() - uplink.Logs.info('=======> Fermeture de la socket') + uplink.ctx.Logs.info('=======> Fermeture de la socket') -def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> list[int]: +async def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> list[int]: """psutil_scan for Linux (should be run on the same location as the unrealircd server) Args: @@ -694,13 +695,13 @@ def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> l Returns: list[int]: list of ports """ - p = uplink.Protocol + p = uplink.ctx.Irc.Protocol remote_ip = user_model.remote_ip username = user_model.username hostname = user_model.hostname nickname = user_model.nickname - if remote_ip in uplink.Config.WHITELISTED_IP: + if remote_ip in uplink.ctx.Config.WHITELISTED_IP: return None try: @@ -708,16 +709,16 @@ def action_scan_client_with_psutil(uplink: 'Defender', user_model: 'MUser') -> l fullname = f'{nickname}!{username}@{hostname}' matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip] - uplink.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}") + uplink.ctx.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}") if matching_ports: - p.send_priv_msg( - nick_from=uplink.Config.SERVICE_NICKNAME, - msg=f"[ {uplink.Config.COLORS.red}PSUTIL_SCAN{uplink.Config.COLORS.black} ] {fullname} ({remote_ip}) : is using ports {matching_ports}", - channel=uplink.Config.SERVICE_CHANLOG + await p.send_priv_msg( + nick_from=uplink.ctx.Config.SERVICE_NICKNAME, + msg=f"[ {uplink.ctx.Config.COLORS.red}PSUTIL_SCAN{uplink.ctx.Config.COLORS.black} ] {fullname} ({remote_ip}) : is using ports {matching_ports}", + channel=uplink.ctx.Config.SERVICE_CHANLOG ) return matching_ports except psutil.AccessDenied as ad: - uplink.Logs.critical(f'psutil_scan: Permission error: {ad}') \ No newline at end of file + uplink.ctx.Logs.critical(f'psutil_scan: Permission error: {ad}') \ No newline at end of file diff --git a/mods/test/mod_test.py b/mods/test/mod_test.py index 4b8aac7..f4dd35f 100644 --- a/mods/test/mod_test.py +++ b/mods/test/mod_test.py @@ -48,7 +48,7 @@ class Test(IModule): # self.ctx.Base.db_execute_query(table_logs) return None - def load(self) -> None: + async def load(self) -> None: """### Load Module Configuration (Mandatory) """ @@ -62,8 +62,11 @@ class Test(IModule): # Build the default configuration model (Mandatory) self._mod_config = self.ModConfModel(param_exemple1='str', param_exemple2=1) - # Init the module (Mandatory) - self.init() + # sync the database with local variable (Mandatory) + await self.sync_db() + + if self.mod_config.param_exemple2 == 1: + await self.ctx.Irc.Protocol.send_priv_msg(self.ctx.Config.SERVICE_NICKNAME, "Param activated", self.ctx.Config.SERVICE_CHANLOG) @property def mod_config(self) -> ModConfModel: @@ -71,7 +74,7 @@ class Test(IModule): def unload(self) -> None: """### This method is called when you unload, or you reload the module (Mandatory)""" - self.ctx.Irc.Commands.drop_command_by_module(self.module_name) + self.ctx.Commands.drop_command_by_module(self.module_name) return None def cmd(self, data: list[str]) -> None: diff --git a/requirements.txt b/requirements.txt index 005b826..c0408c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,6 @@ psutil==7.1.2 PyYAML==6.0.3 requests==2.32.5 SQLAlchemy==2.0.44 -unrealircd_rpc_py==3.0.2 \ No newline at end of file +unrealircd_rpc_py==3.0.2 +starlette==0.50.0 +uvicorn==0.38.0 \ No newline at end of file diff --git a/version.json b/version.json index f8598c8..18a4577 100644 --- a/version.json +++ b/version.json @@ -1,10 +1,12 @@ { - "version": "6.3.3", + "version": "6.4.0", "requests": "2.32.5", "psutil": "7.1.2", "unrealircd_rpc_py": "3.0.1", "sqlalchemy": "2.0.44", "faker": "37.12.0", - "pyyaml": "6.0.3" + "pyyaml": "6.0.3", + "starlette":"0.50.0", + "uvicorn":"0.38.0" }