Загрузка данных


import socket
import threading

clients = {}
lock = threading.Lock()
colors = ["\033[92m", "\033[94m", "\033[93m", "\033[95m", "\033[96m", "\033[91m"]
color_idx = 0

def broadcast(msg, sender=None):
    with lock:
        for c in clients:
            if c != sender:
                try:
                    c.send(msg.encode())
                except:
                    del clients[c]
                    c.close()

def handle(conn, addr):
    global color_idx
    try:
        nick = conn.recv(1024).decode().strip()
        if not nick:
            nick = f"User_{addr[1]}"
    except:
        conn.close()
        return

    with lock:
        color = colors[color_idx % len(colors)]
        color_idx += 1
        clients[conn] = {"nick": nick, "color": color, "addr": addr}

    join_msg = f"{color}[Server] {nick} joined the chat\033[0m"
    print(f"[+] {nick} ({addr}) connected")
    broadcast(join_msg, conn)

    try:
        while True:
            data = conn.recv(1024).decode()
            if not data:
                break

            if data.startswith("/list"):
                with lock:
                    online = ", ".join([c["nick"] for c in clients.values()])
                conn.send(f"\033[93mOnline ({len(clients)}): {online}\033[0m".encode())
                continue

            if data.startswith("@"):
                parts = data.split(" ", 1)
                target_nick = parts[0][1:]
                msg_text = parts[1] if len(parts) > 1 else ""
                with lock:
                    target_conn = next((c for c, info in clients.items() if info["nick"] == target_nick), None)
                if target_conn:
                    sender_info = clients[conn]
                    target_conn.send(f"{sender_info['color']}[PM from {sender_info['nick']}] {msg_text}\033[0m".encode())
                else:
                    conn.send(f"\033[91mUser {target_nick} not found\033[0m".encode())
                continue

            sender_info = clients[conn]
            msg = f"{sender_info['color']}[{sender_info['nick']}] {data}\033[0m"
            print(f"[{nick}] {data}")
            broadcast(msg, conn)

    except:
        pass

    with lock:
        if conn in clients:
            info = clients.pop(conn)
            print(f"[-] {info['nick']} ({addr}) disconnected")
            broadcast(f"\033[90m[Server] {info['nick']} left the chat\033[0m", conn)
    conn.close()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", 5555))
s.listen()
print("Server started on port 5555")

while True:
    conn, addr = s.accept()
    threading.Thread(target=handle, args=(conn, addr), daemon=True).start()