mirror of
https://github.com/HexCardGames/HexDeck.git
synced 2025-09-05 11:18:38 +02:00
🎉 🚧 Start working on backend
This commit is contained in:
153
backend/api/api.go
Normal file
153
backend/api/api.go
Normal file
@ -0,0 +1,153 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/HexCardGames/HexDeck/db"
|
||||
"github.com/HexCardGames/HexDeck/game"
|
||||
"github.com/HexCardGames/HexDeck/types"
|
||||
"github.com/HexCardGames/HexDeck/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ErrorReply struct {
|
||||
StatusCode string
|
||||
Message string
|
||||
}
|
||||
type StatsReply struct {
|
||||
TotalGamesPlayed int
|
||||
RunningGames int
|
||||
OnlinePlayerCount int
|
||||
}
|
||||
type ImprintReply struct {
|
||||
Content string
|
||||
}
|
||||
type CreateRoomReply struct {
|
||||
JoinCode string
|
||||
}
|
||||
type JoinRoomRequest struct {
|
||||
JoinCode string
|
||||
Username string
|
||||
}
|
||||
type LeaveRoomRequest struct {
|
||||
SessionToken string
|
||||
}
|
||||
|
||||
func InitApi() {
|
||||
server := gin.Default()
|
||||
server.SetTrustedProxies(nil)
|
||||
|
||||
server.GET("/api/stats", func(c *gin.Context) {
|
||||
stats := game.CalculateStats()
|
||||
c.JSON(http.StatusOK, StatsReply{
|
||||
TotalGamesPlayed: db.Conn.QueryGlobalStats().GamesPlayed,
|
||||
RunningGames: stats.RunningGames,
|
||||
OnlinePlayerCount: stats.OnlinePlayerCount,
|
||||
})
|
||||
})
|
||||
server.GET("/api/imprint", func(c *gin.Context) {
|
||||
// TODO: Implement imprint endpoint
|
||||
c.JSON(http.StatusOK, ImprintReply{
|
||||
Content: "Not implemented yet",
|
||||
})
|
||||
})
|
||||
|
||||
server.POST("/api/room/create", func(c *gin.Context) {
|
||||
request := JoinRoomRequest{}
|
||||
c.BindJSON(&request)
|
||||
room := game.CreateRoom()
|
||||
player := game.JoinRoom(room, request.Username)
|
||||
player.SetPermissionBit(types.PermissionHost)
|
||||
slog.Debug("New room created", "username", player.Username, "sessionToken", player.SessionToken, "roomId", room.RoomId.Hex())
|
||||
c.JSON(http.StatusOK, player)
|
||||
})
|
||||
|
||||
server.POST("/api/room/join", func(c *gin.Context) {
|
||||
request := JoinRoomRequest{}
|
||||
c.BindJSON(&request)
|
||||
room := game.FindRoomByJoinCode(request.JoinCode)
|
||||
if room == nil {
|
||||
slog.Debug("Client tried joining room using an invalid joinCode", "joinCode", request.JoinCode)
|
||||
c.JSON(http.StatusBadRequest, ErrorReply{
|
||||
StatusCode: "invalid_join_code",
|
||||
Message: "No valid joinCode was provided",
|
||||
})
|
||||
return
|
||||
}
|
||||
if room.GameState != types.StateLobby {
|
||||
slog.Debug("Client tried joining room not in lobby state", "joinCode", request.JoinCode)
|
||||
c.JSON(http.StatusBadRequest, ErrorReply{
|
||||
StatusCode: "game_already_running",
|
||||
Message: "You cannot join this room as the game has already started",
|
||||
})
|
||||
return
|
||||
}
|
||||
player := game.JoinRoom(room, request.Username)
|
||||
slog.Debug("New session created", "username", player.Username, "sessionToken", player.SessionToken, "roomId", room.RoomId.Hex(), "joinCode", request.JoinCode)
|
||||
c.JSON(http.StatusOK, player)
|
||||
})
|
||||
|
||||
server.GET("/api/check/session", func(c *gin.Context) {
|
||||
sessionToken := c.Query("sessionToken")
|
||||
if sessionToken == "" {
|
||||
c.JSON(http.StatusBadRequest, ErrorReply{
|
||||
StatusCode: "missing_parameter",
|
||||
Message: "Parameter sessionToken is missing",
|
||||
})
|
||||
}
|
||||
_, player := game.FindSession(sessionToken)
|
||||
if player == nil {
|
||||
c.Status(401)
|
||||
} else {
|
||||
c.Status(200)
|
||||
}
|
||||
})
|
||||
|
||||
server.GET("/api/check/joinCode", func(c *gin.Context) {
|
||||
joinCode := c.Query("JoinCode")
|
||||
if joinCode == "" {
|
||||
c.JSON(http.StatusBadRequest, ErrorReply{
|
||||
StatusCode: "missing_parameter",
|
||||
Message: "Parameter JoinCode is missing",
|
||||
})
|
||||
}
|
||||
room := game.FindRoomByJoinCode(joinCode)
|
||||
if room == nil {
|
||||
c.Status(401)
|
||||
} else {
|
||||
c.Status(200)
|
||||
}
|
||||
})
|
||||
|
||||
server.POST("/api/room/leave", func(c *gin.Context) {
|
||||
request := LeaveRoomRequest{}
|
||||
c.BindJSON(&request)
|
||||
room, player := game.FindSession(request.SessionToken)
|
||||
if player == nil {
|
||||
c.JSON(http.StatusBadRequest, ErrorReply{
|
||||
StatusCode: "invalid_session",
|
||||
Message: "No user was found with the provided sessionToken",
|
||||
})
|
||||
return
|
||||
}
|
||||
room.RemovePlayer(*player)
|
||||
game.OnRoomUpdate(room)
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
// Handle WebSocket connections using Socket.io
|
||||
wsHandler := initWS()
|
||||
server.Any("/socket.io/", gin.WrapH(wsHandler))
|
||||
|
||||
listenHost := utils.Getenv("LISTEN_HOST", "0.0.0.0")
|
||||
listenPort, err := strconv.Atoi(utils.Getenv("LISTEN_PORT", "3000"))
|
||||
if err != nil {
|
||||
log.Fatal("Value of variable PORT is not a valid integer!")
|
||||
}
|
||||
slog.Info(fmt.Sprintf("HexDeck server listening on http://%s:%d", listenHost, listenPort))
|
||||
server.Run(fmt.Sprintf("%s:%d", listenHost, listenPort))
|
||||
}
|
Reference in New Issue
Block a user