mchess-server/main.go
Marco aac428baab First changes to move away from central registry of all players
1. Introduce 'usher' that opens lobbies and fills it and waits for them
   to be filled
2. Add global registry of all games
2023-05-31 23:55:40 +02:00

110 lines
2.8 KiB
Go

package main
import (
"context"
"local/m/mchess_server/chess"
"local/m/mchess_server/usher"
"log"
"net/http"
"os"
"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"nhooyr.io/websocket"
)
var cert_path = "/etc/letsencrypt/live/chess.sw-gross.de/"
var cert_file = cert_path + "fullchain.pem"
var key_file = cert_path + "privkey.pem"
func main() {
hostname, err := os.Hostname()
if err != nil {
log.Fatal(err)
}
router := gin.Default()
router.GET("/api/random", registerForRandomGame)
router.GET("/api/ws", registerWebSocketConnection)
if hostname == "mbook" {
log.Println("Starting service WITHOUT TLS")
log.Fatal(router.Run("localhost:8080"))
} else {
log.Fatal(autotls.Run(router, "chess.sw-gross.de"))
}
}
func registerForRandomGame(c *gin.Context) {
/*
What should be done:
1. Register player
2. Check if there is a game open that lacks one player
3. Fill open game, then respond with player id and game id.
OR
1. Register player
2. If there is no open game, open a game and wait for a second player to join
3. Only after a second player joins, respond with player id and game id.
*/
player := chess.NewPlayer(uuid.New())
usher := usher.GetUsher()
lobby := usher.WelcomeNewPlayer(player)
usher.AddPlayerToLobby(player, lobby)
// Counter point to this approach:
// Waiting for two players might not be necessary.
// Just open the lobby and respond with lobby/game id and player id
// The waiting can be done in the game handler until both players opened a ws connection
usher.WaitForTwoPlayersInLobby(lobby)
log.Println("responding with player id ", player.Uuid)
c.IndentedJSON(http.StatusOK, chess.PlayerInfo{
PlayerID: player.Uuid,
})
}
func registerWebSocketConnection(c *gin.Context) {
webSocketConn, err := websocket.Accept(c.Writer, c.Request, nil)
if err != nil {
log.Println(err)
return
}
go waitForAndHandlePlayerID(c, *webSocketConn)
}
func waitForAndHandlePlayerID(ctx context.Context, conn websocket.Conn) {
msgType, id, err := conn.Read(ctx)
log.Println("read from websocket: ", msgType, id, err)
log.Println("id as string", string(id))
uuid, err := uuid.ParseBytes(id)
if err != nil {
log.Println(err)
conn.Close(websocket.StatusCode(400), err.Error())
return
}
// since we cannot use the lobby anymore (it does not exist anymore after this change) the client needs to
// send game id and player id so we can make the connection to the player
//lobby := chess.GetLobby()
player, found := lobby.GetPlayer(uuid)
if !found {
conn.Close(websocket.StatusCode(400), "player not found")
return
}
if player.Conn != nil {
player.Conn.Close(websocket.StatusCode(400), "closing existing connection")
}
player.SetConnection(ctx, conn)
log.Println("player after setting connection: ", player)
}