Update server.py

This commit is contained in:
Nova Cat 2025-02-05 12:24:40 -08:00
parent 6577098a60
commit 96e0649ea5

View file

@ -33,7 +33,7 @@ def isalphanumeric(text:str, channel=False):
def getident(hostt:str, clientport:int, ssll:bool): def getident(hostt:str, clientport:int, ssll:bool):
try: try:
identsender = socket.socket(socket.AF_INET, socket.SOCK_STREAM) identsender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
identsender.settimeout(5) identsender.settimeout(2)
responsee = "" responsee = ""
try: try:
identsender.connect((hostt, 113)) identsender.connect((hostt, 113))
@ -193,6 +193,7 @@ if ssl_option:
sockets_ssl[i].listen(1) sockets_ssl[i].listen(1)
opened=True opened=True
lower_chans = {} # Channel names in lowercase lower_chans = {} # Channel names in lowercase
"""
def pinger(nick, connection): def pinger(nick, connection):
global property_list global property_list
while nick in property_list: while nick in property_list:
@ -219,6 +220,7 @@ def pinger(nick, connection):
connection.shutdown(socket.SHUT_WR) connection.shutdown(socket.SHUT_WR)
connection.close() connection.close()
break break
"""
def session(connection, client, ip, isssl=False): def session(connection, client, ip, isssl=False):
global property_list global property_list
global channels_list global channels_list
@ -239,8 +241,22 @@ def session(connection, client, ip, isssl=False):
pendingCommands = "" # list of commands that were executed before verification pendingCommands = "" # list of commands that were executed before verification
unfinished = False unfinished = False
textt = "" textt = ""
last_ping = time.time()
ping_pending = False
pendingSend = "" # Text that should be sent to the client pendingSend = "" # Text that should be sent to the client
IRCv3Features = [] # List of Acknowledged IRCv3 features. IRCv3Features = [] # List of Acknowledged IRCv3 features.
def ping(): # Ping
if pending != "*":
if (time.time() - last_ping) > 30 and not ping_pending:
print(f"Sending ping msg to {pending}")
ping_pending = True
time.sleep(0.5)
connection.sendall(bytes(f"PING {server}\r\n","UTF-8"))
else ping_pending and (time.time() - last_ping) > ping_timeout:
cause = f"Ping timeout: {ping_timeout} seconds"
print(f"{pending} timed out.")
return True
return False
def tags(): # Get IRCv3 tags def tags(): # Get IRCv3 tags
tags = "" tags = ""
if "server-time" in IRCv3Features: if "server-time" in IRCv3Features:
@ -292,7 +308,9 @@ def session(connection, client, ip, isssl=False):
break break
except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError): except (SSL.WantReadError, SSL.WantWriteError, SSL.WantX509LookupError):
print("Skipable error occurred.") print("Skipable error occurred.")
pass except socket.timeout:
print("Socket timed out, ticking...")
data = bytes("", "UTF-8")
except SSL.ZeroReturnError: except SSL.ZeroReturnError:
print(traceback.format_exc()) print(traceback.format_exc())
cause = "Remote host closed the connection" cause = "Remote host closed the connection"
@ -304,6 +322,8 @@ def session(connection, client, ip, isssl=False):
print("Received data: {}".format(data)) print("Received data: {}".format(data))
try: try:
textt += data.decode() textt += data.decode()
if ping():
break
if textt[-1] == "\n": if textt[-1] == "\n":
for text in textt.replace("\r", "").split("\n"): for text in textt.replace("\r", "").split("\n"):
for i in socketListeners: for i in socketListeners:
@ -366,12 +386,11 @@ def session(connection, client, ip, isssl=False):
cleanup_manual() cleanup_manual()
print(f"User {pending} successfully logged in.") print(f"User {pending} successfully logged in.")
nickname_list[pending] = connection nickname_list[pending] = connection
property_list[pending] = {"host": hostname, "username": clident if clident != None else f"~{username }", "realname": realname, "modes": "iw", "last_ping": time.time(), "ping_pending": False, "away": False, "identified": False, "ssl": isssl, "v3cap": IRCv3Features} property_list[pending] = {"host": hostname, "username": clident if clident != None else f"~{username }", "realname": realname, "modes": "iw", "away": False, "identified": False, "ssl": isssl, "v3cap": IRCv3Features}
lower_nicks[pending.lower()] = pending lower_nicks[pending.lower()] = pending
for i in socketListeners: for i in socketListeners:
if "onValidate" in dir(i): if "onValidate" in dir(i):
i.onValidate(socket=connection, ip=client[0], v3cap=IRCv3Features) i.onValidate(socket=connection, ip=client[0], v3cap=IRCv3Features)
threading.Thread(target=pinger, args=[pending, connection]).start()
if clident == None: if clident == None:
rident = f"~{username}" rident = f"~{username}"
connection.sendall(bytes(f"{tags()}:{server} 001 {pending} :Welcome to the {displayname} Internet Relay Chat Network {pending}\r\n", "UTF-8")) connection.sendall(bytes(f"{tags()}:{server} 001 {pending} :Welcome to the {displayname} Internet Relay Chat Network {pending}\r\n", "UTF-8"))
@ -490,8 +509,8 @@ def session(connection, client, ip, isssl=False):
e = text.split(" ")[1] e = text.split(" ")[1]
if e == server or e == f":{server}": if e == server or e == f":{server}":
print(pending + " replied to PING.") print(pending + " replied to PING.")
property_list[pending]["last_ping"] = time.time() last_ping = time.time()
property_list[pending]["ping_pending"] = False ping_pending = False
elif command == "NICK": elif command == "NICK":
if len(args) == 0: if len(args) == 0:
connection.sendall(bytes(f"{tags()}:{server} 461 {pending} {command} :Not enough parameters\r\n","UTF-8")) connection.sendall(bytes(f"{tags()}:{server} 461 {pending} {command} :Not enough parameters\r\n","UTF-8"))
@ -528,11 +547,7 @@ def session(connection, client, ip, isssl=False):
nickname_list[pending2] = nickname_list.pop(pending) nickname_list[pending2] = nickname_list.pop(pending)
del lower_nicks[pending.lower()] del lower_nicks[pending.lower()]
lower_nicks[pending2.lower()] = pending2 lower_nicks[pending2.lower()] = pending2
print("starting pinger...")
pending = pending2 pending = pending2
property_list[pending2]["ping_pending"] = False
property_list[pending2]["last_ping"] = time.time()
threading.Thread(target=pinger, args=[pending, connection]).start()
print(f"User {pending} set nick") print(f"User {pending} set nick")
print("Broadcasting nickname change...") print("Broadcasting nickname change...")
elif command == "PART": elif command == "PART":
@ -848,6 +863,7 @@ def ssl_session(sock):
ctx.use_privatekey_file(ssl_pkey) ctx.use_privatekey_file(ssl_pkey)
ctx.use_certificate_chain_file(ssl_cert) ctx.use_certificate_chain_file(ssl_cert)
conn = SSL.Connection(ctx, connection) conn = SSL.Connection(ctx, connection)
conn.settimeout(5)
conn.set_accept_state() conn.set_accept_state()
conn.do_handshake() conn.do_handshake()
threading.Thread(target=session, daemon=True, args=[conn, client, ip_to, True]).start() threading.Thread(target=session, daemon=True, args=[conn, client, ip_to, True]).start()