package main import ( "fmt" "log" "log/slog" "net" "os" "sshpong/internal/config" "sshpong/internal/lobby" "sshpong/internal/pong" "strings" "sync" ) var exit chan bool var games sync.Map func main() { if len(os.Args) == 1 { config.LoadConfig("") } else { config.LoadConfig(os.Args[1]) } slog.SetLogLoggerLevel(slog.Level(config.Config.LogLevel)) fmt.Println("Starting sshpong lobby...") go LobbyListen() fmt.Println("Lobby started") fmt.Println("Starting game listener...") go GamesListen() fmt.Println("Game listener started") _ = <-exit } // Starts listening on port 12345 for TCP connections // Also creates client pool and game connection singletons func LobbyListen() { listener, err := net.Listen("tcp", "127.0.0.1:12345") if err != nil { slog.Error("Error setting up listener for lobby. Exiting...", err) } defer listener.Close() l := lobby.CreateLobby() for { conn, err := listener.Accept() if err != nil { log.Println(err) continue } go func() { client, msgOut, err := l.InitialConnectionHandler(conn) if err != nil { conn.Write(msgOut) } else { fmt.Println("new client", client) _, err = conn.Write(msgOut) if err != nil { slog.Debug("error writing to new player... disconnecting") msg, err := lobby.Marshal(lobby.DisconnectData{ From: client.Username, }, lobby.Disconnect) if err != nil { slog.Error("error marshalling disconnect message on player connect") } l.BroadcastToLobby(msg) } go l.HandleLobbyConnection(client) } }() } } func GamesListen() { type GameClients struct { Client1 lobby.Client Client2 lobby.Client } gameListener, err := net.Listen("tcp", "127.0.0.1:42069") if err != nil { log.Fatal(err) } defer gameListener.Close() for { conn, err := gameListener.Accept() if err != nil { log.Println(err) continue } slog.Debug("Received game connection") go func(conn net.Conn) { messageBytes := make([]byte, 126) n, err := conn.Read(messageBytes) if err != nil { log.Printf("Error reading game ID on connection %s", err) } gInfo := strings.SplitAfter(string(messageBytes[:n]), ":") if err != nil { log.Printf("Game id was not a string? %s", err) } slog.Debug("Game request data", slog.Any("game info", gInfo)) game, ok := games.Load(gInfo[0]) if !ok { games.Store(gInfo[0], GameClients{Client1: lobby.Client{ Username: gInfo[1], Conn: conn, }, Client2: lobby.Client{}}) } else { gameclients, _ := game.(GameClients) client2 := lobby.Client{ Username: gInfo[1], Conn: conn, } games.Store(gInfo[0], GameClients{ Client1: gameclients.Client1, Client2: client2}) go pong.StartGame(gameclients.Client1.Conn, client2.Conn, gameclients.Client1.Username, client2.Username) } }(conn) } }