package netwrk import ( "fmt" "log" "net" "time" "github.com/google/uuid" ) type Client struct { name string conn net.Conn } type ClientPool struct { clients map[string]Client } type GameClients struct { client1 Client client2 Client } type GameConnections struct { games map[string]GameClients } var clientPool *ClientPool var gameConnections *GameConnections func Listen() { clientPool = &ClientPool{ clients: map[string]Client{}, } gameConnections = &GameConnections{ games: map[string]GameClients{}, } listener, err := net.Listen("tcp", ":12345") if err != nil { log.Fatal(err) } defer listener.Close() go func() { for { conn, err := listener.Accept() if err != nil { log.Println(err) continue } name := make([]byte, 1024) n, err := conn.Read(name) if err != nil { log.Println(fmt.Sprintf("Failed to read from connection: %s", conn.LocalAddr())) } else { clientPool.clients[uuid.New().String()] = Client{ name: string(name[:n]), conn: conn, } } } }() } func GetPool() (map[string]Client, bool) { if clientPool.clients != nil { return clientPool.clients, true } return clientPool.clients, false } func CreateGame(clientID1, clientID2 string) (string, error) { client1, ok := clientPool.clients[clientID1] if !ok { return "", fmt.Errorf("Client 1 was not found in client pool :(") } if err := client1.conn.SetWriteDeadline(time.Time{}); err != nil { return "", fmt.Errorf("Client 1 was not responsive") } client2, ok := clientPool.clients[clientID2] if !ok { return "", fmt.Errorf("Client 2 was not found in client pool :(") } if err := client2.conn.SetWriteDeadline(time.Time{}); err != nil { return "", fmt.Errorf("Client 2 was not responsive") } gameID := uuid.New().String() gameConnections.games[gameID] = GameClients{ client1: client1, client2: client2, } delete(clientPool.clients, clientID1) delete(clientPool.clients, clientID2) return gameID, nil } func SendGameUpdateToClients(gameID string, bytes []byte) error { clients, ok := gameConnections.games[gameID] if !ok { return fmt.Errorf("Could not find game clients record") } _, err := clients.client1.conn.Write(bytes) if err != nil { return fmt.Errorf("Could not write to client1 connection") } _, err = clients.client1.conn.Write(bytes) if err != nil { return fmt.Errorf("Could not write to client2 connection") } return nil } func PingAndCleanLobbyClients() { ping := []byte("ping") deadClients := []string{} for id, client := range clientPool.clients { client.conn.SetWriteDeadline(time.Now().Add(time.Second)) _, err := client.conn.Write(ping) if err != nil { log.Println("Could not write to client, deleting connection:", id) deadClients = append(deadClients, id) } } for _, id := range deadClients { delete(clientPool.clients, id) } }