mchess-server/main.go

126 lines
3.1 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"mchess_server/api"
"mchess_server/chess"
lobbies "mchess_server/lobby_registry"
"mchess_server/usher"
"log"
"net/http"
"os"
"sync"
"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/hostPrivate", hostPrivateGame)
router.GET("/api/joinPrivate", joinPrivateGame)
router.GET("/api/ws", registerWebSocketConnection)
if hostname == "mbook" {
log.Println("Starting service WITHOUT TLS")
log.Fatal(router.Run("localhost:8080"))
} else {
gin.SetMode(gin.ReleaseMode)
log.Println("Starting in release mode")
log.Println("Starting service with TLS")
log.Fatal(router.RunTLS("chess.sw-gross.de:9999", cert_file, key_file))
}
}
var mut sync.Mutex
func registerForRandomGame(c *gin.Context) {
player := chess.NewPlayer(uuid.New())
usher := usher.GetUsher()
mut.Lock()
lobby := usher.WelcomeNewPlayer(player)
usher.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
mut.Unlock()
info := api.PlayerInfo{
PlayerID: player.Uuid,
LobbyID: lobby.Uuid,
}
log.Println("responding with info ", info)
c.Header("Access-Control-Allow-Origin", "*")
c.IndentedJSON(http.StatusOK, info)
}
func hostPrivateGame(c *gin.Context) {
player := chess.NewPlayer(uuid.New())
usher.GetUsher()
mut.Lock()
lobby := usher.NewUsher().FindNewPrivateLobby(player)
mut.Unlock()
c.IndentedJSON(http.StatusOK, lobby.Passphrase)
}
func joinPrivateGame(c *gin.Context) {
}
func registerWebSocketConnection(c *gin.Context) {
webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"chess.sw-gross.de", "localhost:*"}})
if err != nil {
log.Println(err)
return
}
go waitForAndHandlePlayerID(c, webSocketConn)
}
func waitForAndHandlePlayerID(ctx context.Context, conn *websocket.Conn) {
msgType, msg, err := conn.Read(ctx)
if err != nil {
errorMessage := fmt.Sprintf("Reading from websocket connection did not work: %s", err)
log.Println(errorMessage)
conn.Close(websocket.StatusCode(400), errorMessage)
return
}
log.Println("read from websocket: ", msgType, string(msg), err)
var info api.PlayerInfo
err = json.Unmarshal(msg, &info)
if err != nil {
errorMessage := fmt.Sprintf("Unmarshaling message did not work: %s", err)
log.Println(errorMessage)
conn.Close(websocket.StatusCode(400), errorMessage)
return
}
lobby := lobbies.GetLobbyRegistry().GetLobbyByUUID(info.LobbyID)
player, found := lobby.GetPlayerByUUID(info.PlayerID)
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)
}