195 lines
4.5 KiB
Go
195 lines
4.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"game-admin/internal/models"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
func (h *GameHandler) ListModules(c *gin.Context) {
|
|
var modules []models.Module
|
|
err := h.db.NewSelect().
|
|
Model(&modules).
|
|
OrderExpr("id ASC").
|
|
Scan(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, modules)
|
|
}
|
|
|
|
func (h *GameHandler) ListGameModules(c *gin.Context) {
|
|
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
|
|
return
|
|
}
|
|
|
|
exists, err := h.gameExists(c, gameID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if !exists {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Game not found"})
|
|
return
|
|
}
|
|
|
|
modulesByGame, err := h.loadModulesByGameIDs(c, []int64{gameID})
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, modulesByGame[gameID])
|
|
}
|
|
|
|
func (h *GameHandler) ConnectModule(c *gin.Context) {
|
|
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
|
|
return
|
|
}
|
|
|
|
var req models.ConnectGameModuleRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
exists, err := h.gameExists(c, gameID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if !exists {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Game not found"})
|
|
return
|
|
}
|
|
|
|
module := new(models.Module)
|
|
err = h.db.NewSelect().
|
|
Model(module).
|
|
Where(`"key" = ?`, strings.TrimSpace(req.ModuleKey)).
|
|
Scan(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Module not found"})
|
|
return
|
|
}
|
|
|
|
gameModule := &models.GameModule{
|
|
GameID: gameID,
|
|
ModuleID: module.ID,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
_, err = h.db.NewInsert().Model(gameModule).Exec(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": "Module already connected to game"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusCreated, module)
|
|
}
|
|
|
|
func (h *GameHandler) DisconnectModule(c *gin.Context) {
|
|
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
|
|
return
|
|
}
|
|
|
|
moduleKey := c.Param("module_key")
|
|
module := new(models.Module)
|
|
err = h.db.NewSelect().
|
|
Model(module).
|
|
Where(`"key" = ?`, moduleKey).
|
|
Scan(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Module not found"})
|
|
return
|
|
}
|
|
|
|
res, err := h.db.NewDelete().
|
|
Model((*models.GameModule)(nil)).
|
|
Where("game_id = ? AND module_id = ?", gameID, module.ID).
|
|
Exec(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if affected, _ := res.RowsAffected(); affected == 0 {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "Module is not connected to game"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Module disconnected"})
|
|
}
|
|
|
|
func (h *GameHandler) attachModulesToGames(c *gin.Context, games []models.Game) error {
|
|
if len(games) == 0 {
|
|
return nil
|
|
}
|
|
|
|
gameIDs := make([]int64, 0, len(games))
|
|
for _, game := range games {
|
|
gameIDs = append(gameIDs, game.ID)
|
|
}
|
|
|
|
modulesByGame, err := h.loadModulesByGameIDs(c, gameIDs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for i := range games {
|
|
games[i].Modules = modulesByGame[games[i].ID]
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *GameHandler) loadModulesByGameIDs(c *gin.Context, gameIDs []int64) (map[int64][]models.Module, error) {
|
|
var gameModules []models.GameModule
|
|
err := h.db.NewSelect().
|
|
Model(&gameModules).
|
|
Relation("Module").
|
|
Where("gm.game_id IN (?)", bun.In(gameIDs)).
|
|
OrderExpr("gm.id ASC").
|
|
Scan(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
modulesByGame := make(map[int64][]models.Module, len(gameIDs))
|
|
for _, gameID := range gameIDs {
|
|
modulesByGame[gameID] = []models.Module{}
|
|
}
|
|
|
|
for _, gameModule := range gameModules {
|
|
if gameModule.Module == nil {
|
|
continue
|
|
}
|
|
modulesByGame[gameModule.GameID] = append(modulesByGame[gameModule.GameID], *gameModule.Module)
|
|
}
|
|
|
|
return modulesByGame, nil
|
|
}
|
|
|
|
func (h *GameHandler) gameHasModule(ctx context.Context, gameID int64, moduleKey string) (bool, error) {
|
|
return h.db.NewSelect().
|
|
Model((*models.GameModule)(nil)).
|
|
Join("JOIN modules AS m ON m.id = gm.module_id").
|
|
Where("gm.game_id = ?", gameID).
|
|
Where(`m."key" = ?`, moduleKey).
|
|
Exists(ctx)
|
|
}
|