diff --git a/config.yml b/config.yml index aa02907..1f9d51b 100644 --- a/config.yml +++ b/config.yml @@ -1,6 +1,6 @@ # IRCat Configuration -# Used as the server/network's display name. +# Used as the server/network's display name. MUST NOT CONTAIN SPACES! name: foo # The hostname the server should go by, such as ircserver1.example.com diff --git a/server.py b/server.py index 775dea6..99c4206 100644 --- a/server.py +++ b/server.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -__version__ = 0 +__version__ = "0.0.1-preview" print(f"INTERNET RELAY CAT v{__version__}") print("Welcome! /ᐠ ˵> ⩊ <˵マ") import socket, time, threading, traceback, sys, os, yaml @@ -27,9 +27,12 @@ channels_list = {} flags_list = {} print("Now listening on port 6667") def session(connection, client): - pending = None - already_set = False - ready = False + pending = None # The nickname of the client + already_set = False # If the client gave the server a NICK packet + ready = False # If the client gave the server a USER packet + finished = False # If the server gave the client its information, indicating it's ready. + username = "oreo" + hostname = client[0] try: print("Connected to client IP: {}".format(client)) connection.sendall(bytes(f":{server} NOTICE * :*** Looking for your hostname...\r\n","UTF-8")) @@ -51,89 +54,95 @@ def session(connection, client): pending = None else: if not already_set: - connection.sendall(bytes(f":{server} 001 {pending} :Welcome to the {displayname} Internet Relay Chat Network {pending}\r\n", "UTF-8")) - connection.sendall(bytes(f":{server} 002 {pending} :Your host is {server}[{ip}/6667], running version IRCat-v{__version__}\r\n", "UTF-8")) - connection.sendall(bytes(f":{pending} MODE {pending} +iw\r\n","UTF-8")) nickname_list[pending] = connection already_set = True - if text.split(" ")[0] == "USER": + elif text.split(" ")[0] == "USER": if not ready: username = text.split(" ")[1] - if text.split(" ")[0] == "JOIN": - channel = text.split(" ")[1] - success = True - if success: - try: - if channel in channels_list: - channels_list[channel].append(pending) - else: - channels_list[channel] = [pending] - except: - connection.sendall(bytes(f":{server} NOTICE * :*** Could not join {channel}\r\n","UTF-8")) - print(channels_list) - for i in channels_list[channel]: - try: - nickname_list[i].sendall(bytes(f":{pending}!~oreo@{client[0]} JOIN {channel}\r\n","UTF-8")) - except: - pass - if text.split(" ")[0] == "PART": - channel = text.split(" ")[1] - for i in channels_list[channel]: - try: - nickname_list[i].sendall(bytes(f":{pending}!~oreo@{client[0]} {text}\r\n","UTF-8")) - except: - pass - try: - channels_list[channel].remove(pending) - except: - print(traceback.format_exc()) - if text.split(" ")[0] == "WHO": - channel = text.split(" ")[1] - if channel in channels_list: - if pending in channels_list[channel]: - users = " ".join(channels_list[channel]) - connection.sendall(bytes(f":{server} 353 {pending} = {channel} :{users}\r\n","UTF-8")) - connection.sendall(bytes(f":{server} 366 {pending} {channel} :End of /NAMES list.\r\n","UTF-8")) - if text.split(" ")[0] == "PRIVMSG": - target = text.split(" ")[1] - if target in channels_list: - if pending in channels_list[target]: - for i in channels_list[channel]: - try: - if i != pending: - nickname_list[i].sendall(bytes(f":{pending}!~oreo@{client[0]} {text}\r\n","UTF-8")) - except: - pass - elif target in nickname_list: - nickname_list[target].sendall(bytes(f":{pending}!~oreo@{client[0]} {text}\r\n","UTF-8")) - else: - nickname_list[target].sendall(bytes(f":{server} 401 {pending} {target} :No such nick/channel\r\n","UTF-8")) - nickname_list[i].sendall(bytes(f":{server} 366 {pending} {channel} :End of /NAMES list.\r\n","UTF-8")) - if text.split(" ")[0] == "QUIT": - # Parse the quit message. - done = [] - msg = text.split(" ")[1:] - if len(msg) > 0: - mse = " ".join(msg) - msg = f"Quit: {mse}" - else: - msg = "Client Quit" - text = f"QUIT :{msg}" - # Broadcast all users in the joined channels that the person left. - for i, users in channels_list.items(): - if pending in users: - for j in users: - if j != pending and not j in done: - nickname_list[j].sendall(bytes(f":{pending}!~oreo@{client[0]} {text}\r\n","UTF-8")) - done.append(j) - # Remove the quitting user from the channel. + elif (ready and already_set) and not finished: + connection.sendall(bytes(f":{server} 001 {pending} :Welcome to the {displayname} Internet Relay Chat Network {pending}\r\n", "UTF-8")) + connection.sendall(bytes(f":{server} 002 {pending} :Your host is {server}[{ip}/6667], running version IRCat-v{__version__}\r\n", "UTF-8")) + connection.sendall(bytes(f":{server} 004 {pending} {server} IRCat-{__version__} iow ovmsitnlbkq\r\n", "UTF-8")) + connection.sendall(bytes(f":{server} 005 {pending} CHANMODES=bq NETWORK={displayname} :are supported by this server\r\n", "UTF-8")) + + connection.sendall(bytes(f":{pending} MODE {pending} +iw\r\n","UTF-8")) + finished = True + elif (ready and already_set) and finished: + if text.split(" ")[0] == "JOIN": + channel = text.split(" ")[1] + success = True + if success: try: - channels_list[i].remove(pending) + if channel in channels_list: + channels_list[channel].append(pending) + else: + channels_list[channel] = [pending] except: - print(traceback.format_exc()) - # Finally, confirm that the client quitted by mirroring the QUIT message. - connection.sendall(bytes(f":{pending}!~oreo@{client[0]} {text}\r\nERROR :Closing Link: {client[0]} ({msg})\r\n","UTF-8")) - break + connection.sendall(bytes(f":{server} NOTICE * :*** Could not join {channel}\r\n","UTF-8")) + print(channels_list) + for i in channels_list[channel]: + try: + nickname_list[i].sendall(bytes(f":{pending}!~{username}@{client[0]} JOIN {channel}\r\n","UTF-8")) + except: + pass + if text.split(" ")[0] == "PART": + channel = text.split(" ")[1] + for i in channels_list[channel]: + try: + nickname_list[i].sendall(bytes(f":{pending}!~{username}@{client[0]} {text}\r\n","UTF-8")) + except: + pass + try: + channels_list[channel].remove(pending) + except: + print(traceback.format_exc()) + if text.split(" ")[0] == "WHO": + channel = text.split(" ")[1] + if channel in channels_list: + if pending in channels_list[channel]: + users = " ".join(channels_list[channel]) + connection.sendall(bytes(f":{server} 353 {pending} = {channel} :{users}\r\n","UTF-8")) + connection.sendall(bytes(f":{server} 366 {pending} {channel} :End of /NAMES list.\r\n","UTF-8")) + if text.split(" ")[0] == "PRIVMSG": + target = text.split(" ")[1] + if target in channels_list: + if pending in channels_list[target]: + for i in channels_list[channel]: + try: + if i != pending: + nickname_list[i].sendall(bytes(f":{pending}!~{username}@{hostname} {text}\r\n","UTF-8")) + except: + pass + elif target in nickname_list: + nickname_list[target].sendall(bytes(f":{pending}!~{username}@{hostname} {text}\r\n","UTF-8")) + else: + nickname_list[target].sendall(bytes(f":{server} 401 {pending} {target} :No such nick/channel\r\n","UTF-8")) + nickname_list[i].sendall(bytes(f":{server} 366 {pending} {channel} :End of /NAMES list.\r\n","UTF-8")) + if text.split(" ")[0] == "QUIT": + # Parse the quit message. + done = [] + msg = text.split(" ")[1:] + if len(msg) > 0: + mse = " ".join(msg) + msg = f"Quit: {mse}" + else: + msg = "Client Quit" + text = f"QUIT :{msg}" + # Broadcast all users in the joined channels that the person left. + for i, users in channels_list.items(): + if pending in users: + for j in users: + if j != pending and not j in done: + nickname_list[j].sendall(bytes(f":{pending}!~{username}@{client[0]} {text}\r\n","UTF-8")) + done.append(j) + # Remove the quitting user from the channel. + try: + channels_list[i].remove(pending) + except: + print(traceback.format_exc()) + # Finally, confirm that the client quitted by mirroring the QUIT message. + connection.sendall(bytes(f":{pending}!~{username}@{client[0]} {text}\r\nERROR :Closing Link: {client[0]} ({msg})\r\n","UTF-8")) + break except: print(traceback.format_exc())