diff --git a/core/base.py b/core/base.py index c25e309..94edf95 100644 --- a/core/base.py +++ b/core/base.py @@ -66,7 +66,7 @@ class Base: def __get_latest_defender_version(self) -> None: try: - self.logs.debug(f'Looking for a new version available on Github') + self.logs.debug(f'-- Looking for a new version available on Github') token = '' json_url = f'https://raw.githubusercontent.com/adator85/DEFENDER/main/version.json' headers = { @@ -100,13 +100,13 @@ class Base: bool: True if there is a new version available """ try: - self.logs.debug(f'Checking for a new service version') + self.logs.debug(f'-- Checking for a new service version') # Assigner la version actuelle de Defender self.__set_current_defender_version() # Récuperer la dernier version disponible dans github if online: - self.logs.debug(f'Retrieve the latest version from Github') + self.logs.debug(f'-- Retrieve the latest version from Github') self.__get_latest_defender_version() isNewVersion = False @@ -465,7 +465,7 @@ class Base: self.running_timers.append(t) - self.logs.debug(f"Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}") + self.logs.debug(f"-- Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}") except AssertionError as ae: self.logs.error(f'Assertion Error -> {ae}') @@ -490,7 +490,7 @@ class Base: th.start() self.running_threads.append(th) - self.logs.debug(f"Thread ID : {str(th.ident)} | Thread name : {th.getName()} | Running Threads : {len(threading.enumerate())}") + self.logs.debug(f"-- Thread ID : {str(th.ident)} | Thread name : {th.getName()} | Running Threads : {len(threading.enumerate())}") except AssertionError as ae: self.logs.error(f'{ae}') @@ -523,9 +523,9 @@ class Base: if not timer.is_alive(): timer.cancel() self.running_timers.remove(timer) - self.logs.info(f"Timer {str(timer)} removed") + self.logs.info(f"-- Timer {str(timer)} removed") else: - self.logs.debug(f"===> Timer {str(timer)} Still running ...") + self.logs.debug(f"--* Timer {str(timer)} Still running ...") except AssertionError as ae: self.logs.error(f'Assertion Error -> {ae}') @@ -539,7 +539,7 @@ class Base: # print(thread.getName(), thread.is_alive(), sep=' / ') if not thread.is_alive(): self.running_threads.remove(thread) - self.logs.info(f"Thread {str(thread.getName())} {str(thread.native_id)} removed") + self.logs.info(f"-- Thread {str(thread.getName())} {str(thread.native_id)} removed") # print(threading.enumerate()) except AssertionError as ae: @@ -554,7 +554,7 @@ class Base: soc.close() self.running_sockets.remove(soc) - self.logs.debug(f"Socket ==> closed {str(soc.fileno())}") + self.logs.debug(f"-- Socket ==> closed {str(soc.fileno())}") def shutdown(self) -> None: """Methode qui va préparer l'arrêt complêt du service @@ -599,7 +599,7 @@ class Base: engine = create_engine(f'sqlite:///{full_path_db}.db', echo=False) cursor = engine.connect() - self.logs.info("database connexion has been initiated") + self.logs.info("-- database connexion has been initiated") return engine, cursor def __create_db(self) -> None: diff --git a/core/classes/channel.py b/core/classes/channel.py index 94d8438..993f21d 100644 --- a/core/classes/channel.py +++ b/core/classes/channel.py @@ -108,6 +108,27 @@ class Channel: except ValueError as ve: self.Logs.error(f'{ve}') + def add_user_to_a_channel(self, channel_name: str, uid: str) -> bool: + try: + result = False + chanObj = self.get_Channel(channel_name) + self.Logs.debug(f"** {__name__}") + + if chanObj is None: + result = self.insert(MChannel(channel_name, uids=[uid])) + # self.Logs.debug(f"** {__name__} - result: {result}") + # self.Logs.debug(f'New Channel Created: ({chanObj})') + return result + + chanObj.uids.append(uid) + del_duplicates = list(set(chanObj.uids)) + chanObj.uids = del_duplicates + # self.Logs.debug(f'New Channel Created: ({chanObj})') + + return True + except Exception as err: + self.Logs.error(f'{err}') + def clean_channel(self) -> None: """Remove Channels if empty """ diff --git a/core/classes/protocol.py b/core/classes/protocol.py index 536a396..e20ff20 100644 --- a/core/classes/protocol.py +++ b/core/classes/protocol.py @@ -10,9 +10,10 @@ class Protocol: def __init__(self, protocol: Literal['unreal6','inspircd'], ircInstance: 'Irc'): self.Protocol = None - if protocol == 'unreal6': - self.Protocol: Unrealircd6 = Unrealircd6(ircInstance) - elif protocol == 'inspircd': # InspIRCd - self.Protocol: Inspircd = Inspircd(ircInstance) - else: - self.Protocol = None \ No newline at end of file + match protocol: + case 'unreal6': + self.Protocol: Unrealircd6 = Unrealircd6(ircInstance) + case 'inspircd': + self.Protocol: Inspircd = Inspircd(ircInstance) + case _: + self.Protocol: Unrealircd6 = Unrealircd6(ircInstance) diff --git a/core/classes/protocols/inspircd.py b/core/classes/protocols/inspircd.py index 6b90471..f725b02 100644 --- a/core/classes/protocols/inspircd.py +++ b/core/classes/protocols/inspircd.py @@ -15,6 +15,8 @@ class Inspircd: self.__Config = ircInstance.Config self.__Base = ircInstance.Base + self.__Base.logs.info(f"** Loading protocol [{__name__}]") + def send2socket(self, message: str, print_log: bool = True) -> None: """Envoit les commandes à envoyer au serveur. @@ -122,21 +124,28 @@ class Inspircd: version = self.__Config.CURRENT_VERSION unixtime = self.__Base.get_unixtime() - self.send2socket(f":{server_id} PASS :{password}") - self.send2socket(f":{server_id} PROTOCTL SID NOQUIT NICKv2 SJOIN SJ3 NICKIP TKLEXT2 NEXTBANS CLK EXTSWHOIS MLOCK MTAGS") - # self.__Irc.send2socket(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS") - self.send2socket(f":{server_id} PROTOCTL EAUTH={link},,,{service_name}-v{version}") - self.send2socket(f":{server_id} PROTOCTL SID={server_id}") - self.send2socket(f":{server_id} SERVER {link} 1 :{info}") - self.send2socket(f":{server_id} {nickname} :Reserved for services") - #self.__Irc.send2socket(f":{sid} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * * :{realname}") - self.send2socket(f":{server_id} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * fwAAAQ== :{realname}") - # self.__Irc.send2socket(f":{server_id} SJOIN {unixtime} {chan} + :{service_id}") - self.sjoin(chan) - self.send2socket(f":{server_id} TKL + Q * {nickname} {host} 0 {unixtime} :Reserved for services") - self.send2socket(f":{service_id} MODE {chan} {cmodes}") - self.send2socket(f":{service_id} MODE {chan} {umodes} {service_id}") + self.send2socket(f"CAPAB START 1206") + self.send2socket(f"CAPAB CHANMODES :list:ban=b param-set:limit=l param:key=k prefix:10000:voice=+v prefix:30000:op=@o simple:inviteonly=i simple:moderated=m simple:noextmsg=n simple:private=p simple:secret=s simple:topiclock=t") + self.send2socket(f"CAPAB USERMODES :param-set:snomask=s simple:invisible=i simple:oper=o simple:wallops=w") + 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 {link} wobble {server_id} 079 :{service_name}") + + + # self.__Irc.send2socket(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS") + # self.send2socket(f":{server_id} PROTOCTL EAUTH={link},,,{service_name}-v{version}") + # self.send2socket(f":{server_id} PROTOCTL SID={server_id}") + # self.send2socket(f":{server_id} SERVER {link} 1 :{info}") + # self.send2socket(f":{server_id} {nickname} :Reserved for services") + # #self.__Irc.send2socket(f":{sid} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * * :{realname}") + # self.send2socket(f":{server_id} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * fwAAAQ== :{realname}") + # # self.__Irc.send2socket(f":{server_id} SJOIN {unixtime} {chan} + :{service_id}") + # self.sjoin(chan) + # self.send2socket(f":{server_id} TKL + Q * {nickname} {host} 0 {unixtime} :Reserved for services") + + # self.send2socket(f":{service_id} MODE {chan} {cmodes}") + # self.send2socket(f":{service_id} MODE {chan} {umodes} {service_id}") self.__Base.logs.debug(f'>> {__name__} Link information sent to the server') diff --git a/core/classes/protocols/unreal6.py b/core/classes/protocols/unreal6.py index f636aec..878bae0 100644 --- a/core/classes/protocols/unreal6.py +++ b/core/classes/protocols/unreal6.py @@ -2,6 +2,7 @@ from re import match, findall from datetime import datetime from typing import TYPE_CHECKING from ssl import SSLEOFError, SSLError +from dataclasses import dataclass if TYPE_CHECKING: from core.irc import Irc @@ -14,6 +15,9 @@ class Unrealircd6: self.__Irc = ircInstance self.__Config = ircInstance.Config self.__Base = ircInstance.Base + self.__Settings = ircInstance.Base.Settings + + self.__Base.logs.info(f"** Loading protocol [{__name__}]") def send2socket(self, message: str, print_log: bool = True) -> None: """Envoit les commandes à envoyer au serveur. @@ -55,8 +59,8 @@ class Unrealircd6: """ 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 None else None + 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 if User_from is None: self.__Base.logs.error(f"The sender nickname [{nick_from}] do not exist") @@ -71,8 +75,10 @@ class Unrealircd6: 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}") + except Exception as err: self.__Base.logs.error(f"General Error: {err}") + self.__Base.logs.error(f"General Error: {nick_from} - {channel} - {nick_to}") def sendNotice(self, nick_from: str, nick_to: str, msg: str) -> None: """Sending NOTICE by batches @@ -122,21 +128,18 @@ class Unrealircd6: version = self.__Config.CURRENT_VERSION unixtime = self.__Base.get_unixtime() - self.send2socket(f":{server_id} PASS :{password}") + self.send2socket(f":{server_id} PASS :{password}", print_log=False) self.send2socket(f":{server_id} PROTOCTL SID NOQUIT NICKv2 SJOIN SJ3 NICKIP TKLEXT2 NEXTBANS CLK EXTSWHOIS MLOCK MTAGS") # self.__Irc.send2socket(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS") self.send2socket(f":{server_id} PROTOCTL EAUTH={link},,,{service_name}-v{version}") self.send2socket(f":{server_id} PROTOCTL SID={server_id}") self.send2socket(f":{server_id} SERVER {link} 1 :{info}") self.send2socket(f":{server_id} {nickname} :Reserved for services") - #self.__Irc.send2socket(f":{sid} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * * :{realname}") self.send2socket(f":{server_id} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * fwAAAQ== :{realname}") - # self.__Irc.send2socket(f":{server_id} SJOIN {unixtime} {chan} + :{service_id}") self.sjoin(chan) self.send2socket(f":{server_id} TKL + Q * {nickname} {host} 0 {unixtime} :Reserved for services") - self.send2socket(f":{service_id} MODE {chan} {cmodes}") - self.send2socket(f":{service_id} MODE {chan} {umodes} {service_id}") + # self.send2socket(f":{service_id} MODE {chan} {umodes} {service_id}") self.__Base.logs.debug(f'>> {__name__} Link information sent to the server') @@ -148,8 +151,15 @@ class Unrealircd6: return None def set_nick(self, newnickname: str) -> None: - + """Change nickname of the server + \n This method will also update the User object + Args: + newnickname (str): New nickname of the server + """ self.send2socket(f":{self.__Config.SERVICE_NICKNAME} NICK {newnickname}") + + userObj = self.__Irc.User.get_User(self.__Config.SERVICE_NICKNAME) + self.__Irc.User.update(userObj.uid, newnickname) return None def squit(self, server_id: str, server_link: str, reason: str) -> None: @@ -180,12 +190,17 @@ class Unrealircd6: return None def sjoin(self, channel: str) -> None: + """Server will join a channel with pre defined umodes + Args: + channel (str): Channel to join + """ if not self.__Irc.Channel.Is_Channel(channel): self.__Base.logs.error(f"The channel [{channel}] is not valid") return None - self.send2socket(f":{self.__Config.SERVEUR_ID} SJOIN {self.__Base.get_unixtime()} {channel} + :{self.__Config.SERVICE_ID}") + self.send2socket(f":{self.__Config.SERVEUR_ID} SJOIN {self.__Base.get_unixtime()} {channel} {self.__Config.SERVICE_UMODES} :{self.__Config.SERVICE_ID}") + self.send2socket(f":{self.__Config.SERVICE_ID} MODE {channel} {self.__Config.SERVICE_UMODES} {self.__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])) @@ -216,6 +231,62 @@ class Unrealircd6: except Exception as err: self.__Base.logs.error(f"{__name__} - General Error: {err}") + def sendSajoin(self, nick_to_sajoin: str, channel_name: str) -> None: + """_summary_ + + Args: + nick_to_sajoin (str): _description_ + channel_name (str): _description_ + """ + try: + + userObj = self.__Irc.User.get_User(uidornickname=nick_to_sajoin) + chanObj = self.__Irc.Channel.get_Channel(channel_name) + service_uid = self.__Config.SERVICE_ID + + if userObj is None: + # User not exist: leave + return None + + if chanObj is None: + # Channel not exist + if not self.__Irc.Channel.Is_Channel(channel_name): + # Incorrect channel: leave + return None + + # Create the new channel with the uid + newChanObj = self.__Irc.Loader.Definition.MChannel(name=channel_name, uids=[userObj.uid]) + self.__Irc.Channel.insert(newChanObj) + self.send2socket(f":{service_uid} SAJOIN {userObj.nickname} {newChanObj.name}") + + else: + self.__Irc.Channel.add_user_to_a_channel(channel_name=channel_name, uid=userObj.uid) + self.send2socket(f":{service_uid} SAJOIN {userObj.nickname} {chanObj.name}") + + return None + + except Exception as err: + self.__Base.logs.error(f"{__name__} - General Error: {err}") + + def sendSvsmode(self, nickname: str, user_mode: str) -> None: + try: + + userObj = self.__Irc.User.get_User(uidornickname=nickname) + service_uid = self.__Config.SERVICE_ID + + if userObj is None: + # User not exist: leave + return None + + self.send2socket(f':{service_uid} SVSMODE {nickname} {user_mode}') + + # Update new mode + self.__Irc.User.update_mode(userObj.uid, user_mode) + + return None + except Exception as err: + self.__Base.logs.error(f"{__name__} - General Error: {err}") + def sendQuit(self, uid: str, reason: str, print_log: True) -> None: """Send quit message - Delete uid from User object @@ -305,6 +376,9 @@ class Unrealircd6: self.send2socket(f":{userObj.uid} JOIN {channel} {passwordChannel}", print_log=print_log) + if uidornickname == self.__Config.SERVICE_NICKNAME or uidornickname == self.__Config.SERVICE_ID: + self.send2socket(f":{self.__Config.SERVICE_ID} MODE {channel} {self.__Config.SERVICE_UMODES} {self.__Config.SERVICE_ID}") + # Add defender to the channel uids list self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[userObj.uid])) return None @@ -415,10 +489,13 @@ class Unrealircd6: Args: serverMsg (list[str]): Original server message """ + # ['PROTOCTL', 'CHANMODES=beI,fkL,lFH,cdimnprstzCDGKMNOPQRSTVZ', 'USERMODES=diopqrstwxzBDGHIRSTWZ', 'BOOTED=1728815798', 'PREFIX=(qaohv)~&@%+', 'SID=001', 'MLOCK', 'TS=1730662755', 'EXTSWHOIS'] if len(serverMsg) > 5: if '=' in serverMsg[5]: serveur_hosting_id = str(serverMsg[5]).split('=') self.__Config.HSID = serveur_hosting_id[1] + if 'USERMODES=' in serverMsg[2]: + self.__Settings.USER_MODES = list(serverMsg[2].split('=')[1]) return None @@ -457,27 +534,28 @@ class Unrealircd6: # ':001T6VU3F', '001JGWB2K', '@11ZAAAAAB', # '001F16WGR', '001X9YMGQ', '*+001DYPFGP', '@00BAAAAAJ', '001AAGOG9', '001FMFVG8', '001DAEEG7', # '&~G:unknown-users', '"~G:websocket-users', '"~G:known-users', '"~G:webirc-users'] - serverMsg.pop(0) - channel = str(serverMsg[3]).lower() - len_cmd = len(serverMsg) + serverMsg_copy = serverMsg.copy() + serverMsg_copy.pop(0) + channel = str(serverMsg_copy[3]).lower() + len_cmd = len(serverMsg_copy) list_users:list = [] occurence = 0 start_boucle = 0 # Trouver le premier user for i in range(len_cmd): - s: list = findall(fr':', serverMsg[i]) + s: list = findall(fr':', serverMsg_copy[i]) if s: occurence += 1 if occurence == 2: start_boucle = i # Boucle qui va ajouter l'ensemble des users (UID) - for i in range(start_boucle, len(serverMsg)): - parsed_UID = str(serverMsg[i]) + for i in range(start_boucle, len(serverMsg_copy)): + parsed_UID = str(serverMsg_copy[i]) clean_uid = self.__Irc.User.clean_uid(parsed_UID) if not clean_uid is None and len(clean_uid) == 9: - list_users.append(parsed_UID) + list_users.append(clean_uid) if list_users: self.__Irc.Channel.insert( @@ -682,7 +760,11 @@ class Unrealircd6: """ try: # ['@label=0073', ':0014E7P06', 'VERSION', 'PyDefender'] - getUser = self.__Irc.User.get_User(self.__Irc.User.clean_uid(serverMsg[1])) + serverMsg_copy = serverMsg.copy() + if '@' in list(serverMsg_copy[0])[0]: + serverMsg_copy.pop(0) + + getUser = self.__Irc.User.get_User(self.__Irc.User.clean_uid(serverMsg_copy[0])) if getUser is None: return None @@ -694,6 +776,9 @@ class Unrealircd6: response_005 = ' | '.join(modules) self.send2socket(f':{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server') + response_005 = ''.join(self.__Settings.USER_MODES) + self.send2socket(f":{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server") + return None except Exception as err: diff --git a/core/classes/settings.py b/core/classes/settings.py index ac3f4cf..b42d95b 100644 --- a/core/classes/settings.py +++ b/core/classes/settings.py @@ -9,4 +9,6 @@ class Settings: PERIODIC_FUNC: dict[object] = {} LOCK: RLock = RLock() - CONSOLE: bool = False + CONSOLE: bool = True + + USER_MODES: list[str] = [] diff --git a/core/classes/user.py b/core/classes/user.py index b21ce9b..035a9cb 100644 --- a/core/classes/user.py +++ b/core/classes/user.py @@ -76,22 +76,26 @@ class User: new_modes = modes[1:] existing_umodes = userObj.umodes - final_umodes = userObj.umodes + umodes = userObj.umodes if action == '+': for nm in new_modes: if nm not in existing_umodes: - final_umodes += nm + umodes += nm elif action == '-': for nm in new_modes: if nm in existing_umodes: - final_umodes = final_umodes.replace(nm, '') + umodes = umodes.replace(nm, '') else: return False - userObj.umodes = final_umodes + liste_umodes = list(umodes) + final_umodes_liste = [x for x in self.Base.Settings.USER_MODES if x in liste_umodes] + final_umodes = ''.join(final_umodes_liste) + + userObj.umodes = f"+{final_umodes}" return response diff --git a/core/irc.py b/core/irc.py index 9b4d606..f11f78a 100644 --- a/core/irc.py +++ b/core/irc.py @@ -138,11 +138,11 @@ class Irc: ssl_connexion.connect(connexion_information) self.IrcSocket:SSLSocket = ssl_connexion self.Config.SSL_VERSION = self.IrcSocket.version() - self.Logs.info(f"Connexion en mode SSL : Version = {self.Config.SSL_VERSION}") + self.Logs.info(f"-- Connexion en mode SSL : Version = {self.Config.SSL_VERSION}") else: soc.connect(connexion_information) self.IrcSocket:socket.socket = soc - self.Logs.info("Connexion en mode normal") + self.Logs.info("-- Connexion en mode normal") return None @@ -165,7 +165,7 @@ class Irc: ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - self.Logs.debug(f'SSLContext initiated with verified mode {ctx.verify_mode}') + self.Logs.debug(f'-- SSLContext initiated with verified mode {ctx.verify_mode}') return ctx @@ -192,7 +192,7 @@ class Irc: while self.IrcSocket.fileno() != -1: time.sleep(0.5) - self.Logs.warning('--> Waiting for socket to close ...') + self.Logs.warning('--* Waiting for socket to close ...') # Reload configuration self.Logs.debug('Reloading configuration') @@ -237,7 +237,7 @@ class Irc: self.IrcSocket.shutdown(socket.SHUT_RDWR) self.IrcSocket.close() - self.Logs.info("--> Fermeture de Defender ...") + self.Logs.info("-- Fermeture de Defender ...") sys.exit(0) except AssertionError as ae: @@ -265,33 +265,6 @@ class Irc: chan = chan_name[0] self.Protocol.sjoin(channel=chan) - # def send2socket(self, send_message:str, print_log: bool = True) -> None: - # """Envoit les commandes à envoyer au serveur. - - # Args: - # string (Str): contient la commande à envoyer au serveur. - # """ - # try: - # with self.Base.lock: - # self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0])) - # if print_log: - # self.Logs.debug(f'< {send_message}') - - # except UnicodeDecodeError: - # self.Logs.error(f'Decode Error try iso-8859-1 - message: {send_message}') - # self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace')) - # except UnicodeEncodeError: - # self.Logs.error(f'Encode Error try iso-8859-1 - message: {send_message}') - # self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace')) - # except AssertionError as ae: - # self.Logs.warning(f'Assertion Error {ae} - message: {send_message}') - # except ssl.SSLEOFError as soe: - # self.Logs.error(f"SSLEOFError: {soe} - {send_message}") - # except ssl.SSLError as se: - # self.Logs.error(f"SSLError: {se} - {send_message}") - # except OSError as oe: - # self.Logs.error(f"OSError: {oe} - {send_message}") - def send_response(self, responses:list[bytes]) -> None: try: # print(responses) @@ -802,6 +775,9 @@ class Irc: # self.Base.create_thread(self.abuseipdb_scan, (cmd[7], )) pass + case 'VERSION': + self.Protocol.on_version_msg(original_response) + case 'UMODE2': # [':adator_', 'UMODE2', '-i'] self.Protocol.on_umode2(serverMsg=original_response) @@ -1456,6 +1432,7 @@ class Irc: self.User.UID_DB.clear() # Clear User Object self.Channel.UID_CHANNEL_DB.clear() # Clear Channel Object + self.Base.delete_logger(self.Config.LOGGING_NAME) self.Protocol.squit(server_id=self.Config.SERVEUR_ID, server_link=self.Config.SERVEUR_LINK, reason=final_reason) self.Logs.info(f'Redémarrage du server {dnickname}') @@ -1527,8 +1504,8 @@ class Irc: msg=f'> Module [{mod}] reloaded', channel=self.Config.SERVICE_CHANLOG ) - - self.reload_module(fromuser, 'mod_command') + for mod in self.Base.get_all_modules(): + self.reload_module(fromuser, mod) case 'show_modules': diff --git a/defender.py b/defender.py index 2c40dbd..f78be65 100644 --- a/defender.py +++ b/defender.py @@ -19,7 +19,7 @@ from core import installation try: - installation.Install() + # installation.Install() from core.loader import Loader from core.irc import Irc diff --git a/mods/mod_command.py b/mods/mod_command.py index 758d6b6..663a35f 100644 --- a/mods/mod_command.py +++ b/mods/mod_command.py @@ -55,7 +55,7 @@ class Command(): self.__init_module() # Log the module - self.Logs.debug(f'Module {self.module_name} loaded ...') + self.Logs.debug(f'-- Module {self.module_name} loaded ...') def __init_module(self) -> None: @@ -810,26 +810,26 @@ class Command(): case 'invite': try: if len(cmd) < 3: - self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #CHANNEL NICKNAME") + self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") return None - chan = str(cmd[1]) - nickname = str(cmd[2]) + nickname = str(cmd[1]) + chan = str(cmd[2]) if not self.Channel.Is_Channel(chan): self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"The channel must start with #") - self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel nickname") + self.Protocol.sendNotice(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.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"Nickname not found !") - self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel NICKNAME") + self.Protocol.sendNotice(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}') except KeyError as ke: - self.Logs.error(ke) + self.Logs.error(f"KeyError: {ke}") except Exception as err: self.Logs.warning(f'Unknown Error: {str(err)}') @@ -842,7 +842,7 @@ class Command(): self.Protocol.send2socket(f':{dnickname} INVITE {fromuser} {self.Config.SERVICE_CHANLOG}') except KeyError as ke: - self.Logs.error(ke) + self.Logs.error(f"KeyError: {ke}") except Exception as err: self.Logs.warning(f'Unknown Error: {str(err)}') @@ -852,7 +852,7 @@ class Command(): self.Protocol.send2socket(f':{dnickname} MAP') except KeyError as ke: - self.Logs.error(ke) + self.Logs.error(f"KeyError: {ke}") except Exception as err: self.Logs.warning(f'Unknown Error: {str(err)}') @@ -866,7 +866,7 @@ class Command(): nickname = str(cmd[1]) umode = str(cmd[2]) - self.Protocol.send2socket(f':{dnickname} SVSMODE {nickname} {umode}') + self.Protocol.sendSvsmode(nickname=nickname, user_mode=umode) except KeyError as ke: self.Logs.error(ke) except Exception as err: @@ -950,7 +950,8 @@ class Command(): self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") return None - self.Protocol.send2socket(f':{self.Config.SERVEUR_ID} SAJOIN {nickname} {channel}') + self.Protocol.sendSajoin(nick_to_sajoin=nickname, channel_name=channel) + except KeyError as ke: self.Logs.error(ke) except Exception as err: @@ -966,7 +967,7 @@ class Command(): self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} {command.upper()} nickname #channel") return None - self.Protocol.send2socket(f':{self.Config.SERVEUR_ID} SAPART {nickname} {channel}') + self.Protocol.sendSapart(nick_to_sapart=nickname, channel_name=channel) except KeyError as ke: self.Logs.error(ke) except Exception as err: diff --git a/mods/mod_defender.py b/mods/mod_defender.py index 23ebd22..88d0535 100644 --- a/mods/mod_defender.py +++ b/mods/mod_defender.py @@ -92,7 +92,7 @@ class Defender(): self.__init_module() # Log the module - self.Logs.debug(f'Module {self.module_name} loaded ...') + self.Logs.debug(f'-- Module {self.module_name} loaded ...') def __init_module(self) -> None: @@ -351,7 +351,7 @@ class Defender(): if not get_reputation.isWebirc: # Si le user ne vient pas de webIrc - self.Protocol.send2socket(f":{service_id} SAJOIN {jailed_nickname} {salon_jail}") + self.Protocol.sendSajoin(nick_to_sajoin=jailed_nickname, channel_name=salon_jail) self.Protocol.sendPrivMsg(nick_from=self.Config.SERVICE_NICKNAME, msg=f" [{color_red} REPUTATION {nogc}] : Connexion de {jailed_nickname} ({jailed_score}) ==> {salon_jail}", channel=salon_logs @@ -402,10 +402,10 @@ class Defender(): if self.get_user_uptime_in_minutes(user.uid) >= reputation_timer and int(user.score_connexion) <= int(reputation_seuil): self.Protocol.sendPrivMsg( nick_from=service_id, - msg=f":{service_id} PRIVMSG {dchanlog} :[{color_red} REPUTATION {nogc}] : Action sur {user.nickname} aprés {str(reputation_timer)} minutes d'inactivité", + msg=f"[{color_red} REPUTATION {nogc}] : Action sur {user.nickname} aprés {str(reputation_timer)} minutes d'inactivité", channel=dchanlog ) - self.Protocol.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code ") + self.Protocol.send2socket(f":{service_id} KILL {user.nickname} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code") self.Protocol.send2socket(f":{self.Config.SERVEUR_LINK} REPUTATION {user.remote_ip} 0") self.Logs.info(f"Nickname: {user.nickname} KILLED after {str(reputation_timer)} minutes of inactivity") @@ -1080,7 +1080,7 @@ class Defender(): currentDateTime = self.Base.get_datetime() self.Reputation.insert( self.Loader.Definition.MReputation( - **_User, + **_User.__dict__, secret_code=self.Base.get_random(8) # uid=_User.uid, nickname=_User.nickname, username=_User.username, realname=_User.realname, # hostname=_User.hostname, umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion, @@ -1112,14 +1112,14 @@ class Defender(): if not isWebirc: if parsed_chan != self.Config.SALON_JAIL: - self.Protocol.send2socket(f":{service_id} SAPART {get_reputation.nickname} {parsed_chan}") + self.Protocol.sendSapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan) if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc: if parsed_chan != self.Config.SALON_JAIL: self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*") self.Protocol.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}") - self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}') + self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}') except KeyError as ke: self.Logs.error(f"key error SJOIN : {ke}") @@ -1249,7 +1249,7 @@ class Defender(): self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser, msg=" No code is requested ...") return False - jailed_IP = get_reputation.ip + jailed_IP = get_reputation.remote_ip jailed_salon = self.Config.SALON_JAIL reputation_seuil = self.ModConfig.reputation_seuil welcome_salon = self.Config.SALON_LIBERER @@ -1269,8 +1269,8 @@ class Defender(): self.Reputation.delete(jailed_UID) self.Logs.debug(f'{jailed_UID} - {jailed_nickname} removed from REPUTATION_DB') - self.Protocol.send2socket(f":{service_id} SAPART {jailed_nickname} {jailed_salon}") - self.Protocol.send2socket(f":{service_id} SAJOIN {jailed_nickname} {welcome_salon}") + self.Protocol.sendSapart(nick_to_sapart=jailed_nickname, channel_name=jailed_salon) + self.Protocol.sendSajoin(nick_to_sajoin=jailed_nickname, channel_name=welcome_salon) self.Protocol.send2socket(f":{link} REPUTATION {jailed_IP} {self.ModConfig.reputation_score_after_release}") self.User.get_User(jailed_UID).score_connexion = reputation_seuil + 1 self.Protocol.sendPrivMsg(nick_from=dnickname, @@ -1285,7 +1285,7 @@ class Defender(): ) self.Protocol.sendPrivMsg( nick_from=dnickname, - msg=f"[{color_green} MAUVAIS PASSWORD {color_black}]", + 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}", nick_to=jailed_nickname ) diff --git a/mods/mod_votekick.py b/mods/mod_votekick.py index 9a871d4..40be58b 100644 --- a/mods/mod_votekick.py +++ b/mods/mod_votekick.py @@ -64,7 +64,7 @@ class Votekick(): self.__init_module() # Log the module - self.Logs.debug(f'Module {self.module_name} loaded ...') + self.Logs.debug(f'-- Module {self.module_name} loaded ...') def __init_module(self) -> None: @@ -286,9 +286,8 @@ class Votekick(): match command: case 'vote': - option = str(cmd[1]).lower() - if len(command) == 1: + if len(cmd) == 1: self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote activate #channel') self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote deactivate #channel') self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote +') @@ -297,6 +296,9 @@ class Votekick(): self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote status') self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote submit nickname') self.Protocol.sendNotice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote verdict') + return None + + option = str(cmd[1]).lower() match option: