import socket import threading HEADER = 10 PORT = 5050 SERVER = socket.gethostbyname(socket.gethostname()) ADDR = (SERVER, PORT) FORMAT = 'utf-8' server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(ADDR) # only valid usernames users = ['ROBYN', 'NIRMAL', 'AMAAR', 'PATRICK'] # the menu the client can see and order off of menu = {'starter': ['garlic bread', 'dough balls', 'chicken wings'], 'main': ['pizza', 'burger', 'pasta'], 'side': ['fries', 'salad', 'rice']} # users orders stored here orders = {} chef_present = True global user global state # one of: LOGIN, CUSTOMER, NEW, STARTER, MAIN, SIDE, OLD, DONE def handle_message(msg): if chef_present: global state if state == 'LOGIN': if AUTH(msg.upper()): update_user(msg) state = "CUSTOMER" return "NEW or OLD customer?" else: return "Enter username: " if state == 'CUSTOMER': if msg.upper() == "NEW": state = 'NEW' return "MENU or ORDR?" elif msg.upper() == "OLD": state = 'OLD' return 'PKUP?' else: return "NEW or OLD?" if state == "NEW": if msg.upper() == "MENU": return menu_to_string() + "\nMENU or ORDR?" elif msg.upper() == "ORDR": state = "STARTER" return "Select starter: " else: return "MENU or ORDR?" if state == "STARTER": if is_starter(msg.lower()): orders[user] = [] orders[user].append(msg.lower()) state = "MAIN" return "Select main: " else: return "Select starter: " if state == "MAIN": if is_main(msg.lower()): orders[user].append(msg.lower()) state = "SIDE" return "Select side: " else: return "Select main: " if state == "SIDE": if is_side(msg.lower()): orders[user].append(msg.lower()) state = "DONE" return "DONE" else: return "Select side: " if state == "DONE": return "DONE" if state == "OLD": if msg.upper() == "PKUP": if user in orders: order = orders_to_string(user) orders.pop(user) return order + "\nOrder picked up, you may close the connection." else: return "You don't have any orders to pick up. Please close the connection." else: return "PKUP?" else: return 'ERR' else: return 'Sorry, the chef is currently unavailable' def AUTH(usr): if usr in users: return True else: return False def update_user(name): global user user = name.upper() def is_starter(item): if item in menu["starter"]: return True else: return False def is_side(item): if item in menu["side"]: return True else: return False def is_main(item): if item in menu["main"]: return True else: return False def menu_to_string(): menu_string = "Starters: " for item in menu['starter']: menu_string += item + ", " menu_string += "\nMains: " for item in menu['main']: menu_string += item + ", " menu_string += "\nSides: " for item in menu['side']: menu_string += item + ", " menu_string += "\n" return menu_string def orders_to_string(usr): order_string = usr + ":\n" for item in orders[usr]: order_string += item + "\n" return order_string def handle_client(conn, addr): print(f"[NEW CONNECTION] {addr} connected.") global state state = 'LOGIN' connected = True while connected: msg_length = conn.recv(HEADER).decode(FORMAT) if msg_length: msg_length = int(msg_length) msg = conn.recv(msg_length).decode(FORMAT) if msg == "BYE": connected = False print(f"[{addr}] {msg}") conn.send("END".encode(FORMAT)) else: print(f"[{addr}] {msg}") conn.send(handle_message(msg).encode(FORMAT)) conn.close() def start(): server.listen() print(f"[LISTENING] Server is listening on {SERVER}") while True: conn, addr = server.accept() thread = threading.Thread(target=handle_client, args=(conn, addr)) thread.start() print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}") print("[STARTING] server is starting...") start()