Marco
aac428baab
1. Introduce 'usher' that opens lobbies and fills it and waits for them to be filled 2. Add global registry of all games
110 lines
2.8 KiB
Go
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)
|
|
}
|