tijl.dev-core/internal/apps/flags/handlers.go

271 lines
7.1 KiB
Go
Raw Normal View History

2024-08-26 14:22:24 +02:00
package flags
import (
"context"
"database/sql"
2024-08-26 17:43:36 +02:00
"net/http"
2024-08-26 14:22:24 +02:00
"strconv"
2024-08-26 20:28:20 +02:00
"time"
2024-08-26 14:22:24 +02:00
"git.tijl.dev/tijl/tijl.dev-core/internal/queries"
"git.tijl.dev/tijl/tijl.dev-core/internal/user"
"git.tijl.dev/tijl/tijl.dev-core/internal/utils"
"git.tijl.dev/tijl/tijl.dev-core/modules/db"
2024-08-26 17:43:36 +02:00
"git.tijl.dev/tijl/tijl.dev-core/modules/i18n"
2024-08-26 14:22:24 +02:00
"git.tijl.dev/tijl/tijl.dev-core/modules/web"
"github.com/enescakir/emoji"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
2024-08-26 17:43:36 +02:00
const flagSessionCookie string = "app_flags_game_session"
2024-08-26 16:57:28 +02:00
2024-08-26 14:22:24 +02:00
func answerHandler(c *fiber.Ctx) error {
2024-08-26 16:46:28 +02:00
2024-08-26 16:57:28 +02:00
gameId, err := uuid.Parse(c.Cookies(flagSessionCookie))
2024-08-26 16:46:28 +02:00
if err != nil {
return err
}
answer := c.FormValue("answer")
2024-08-26 20:28:20 +02:00
gameSession, err := db.Queries.AppFlagsGetGame(context.TODO(), gameId)
2024-08-26 16:46:28 +02:00
if err != nil {
return err
}
err, countries := filterCountriesByTags(gameSession.Tags)
if err != nil {
return err
}
2024-08-26 20:28:20 +02:00
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.String())
2024-08-26 16:46:28 +02:00
correctAnswer := shuffledCountries[gameSession.QuestionCurrent-1]
if answer == correctAnswer {
2024-08-26 20:28:20 +02:00
db.Queries.AppFlagsUpdateGame(context.TODO(), queries.AppFlagsUpdateGameParams{
2024-08-26 16:46:28 +02:00
GameID: gameId,
QuestionCurrent: gameSession.QuestionCurrent + 1,
})
2024-08-26 20:28:20 +02:00
db.Queries.AppFlagsUpsertGameAnswer(context.TODO(), queries.AppFlagsUpsertGameAnswerParams{
2024-08-26 16:46:28 +02:00
GameID: gameId,
Question: gameSession.QuestionCurrent,
Errors: 0,
})
} else {
2024-08-26 20:28:20 +02:00
db.Queries.AppFlagsUpsertGameAnswer(context.TODO(), queries.AppFlagsUpsertGameAnswerParams{
2024-08-26 16:46:28 +02:00
GameID: gameId,
Question: gameSession.QuestionCurrent,
Errors: 1,
})
}
2024-08-26 20:28:20 +02:00
err = db.Queries.AppFlagsUpdateQuestionCorrect(context.TODO(), gameId)
2024-08-26 16:46:28 +02:00
if err != nil {
return err
}
2024-08-26 14:22:24 +02:00
return questionHandler(c, NewGameUUID{})
}
type NewGameUUID struct {
uuid.UUID
used bool
}
func questionHandler(c *fiber.Ctx, newGame NewGameUUID) error {
var gameId uuid.UUID
var err error
if newGame.used {
gameId = newGame.UUID
} else {
2024-08-26 16:57:28 +02:00
gameId, err = uuid.Parse(c.Cookies(flagSessionCookie))
2024-08-26 14:22:24 +02:00
if err != nil {
return err
}
}
2024-08-26 20:28:20 +02:00
gameSession, err := db.Queries.AppFlagsGetGame(context.TODO(), gameId)
2024-08-26 14:22:24 +02:00
if err != nil {
return err
}
2024-08-26 16:57:28 +02:00
uid, err := user.GetSession(c)
if uid != gameSession.Uid.String {
utils.ClearCookie(c, flagSessionCookie)
2024-08-26 17:43:36 +02:00
return gameStartHandler(c)
2024-08-26 16:57:28 +02:00
}
2024-08-26 14:22:24 +02:00
if (gameSession.QuestionAmount != 0) && (gameSession.QuestionAmount+1 == gameSession.QuestionCurrent) {
2024-08-26 16:46:28 +02:00
return gameEndHandler(c)
2024-08-26 14:22:24 +02:00
}
err, countries := filterCountriesByTags(gameSession.Tags)
if err != nil {
return err
}
2024-08-26 16:46:28 +02:00
if int(gameSession.QuestionCurrent) == len(countries) {
return gameEndHandler(c)
}
2024-08-26 20:28:20 +02:00
shuffledCountries := shuffleSlice(countries, gameSession.GameSeed.String())
shuffledAnswers := shuffleSlice(countries, gameSession.GameSeed.String()+string(gameSession.QuestionCurrent))
shuffledAnswers = shuffledAnswers[0:4] // 4 random aswers
shuffledAnswers = append(shuffledAnswers, shuffledCountries[gameSession.QuestionCurrent-1]) // add correct answer
shuffledAnswers = shuffleSlice(shuffledAnswers, gameSession.GameSeed.String()+string(gameSession.QuestionCurrent)) // shuffle again
2024-08-26 14:22:24 +02:00
2024-08-26 17:43:36 +02:00
if gameSession.QuestionAmount != 0 && int(gameSession.QuestionAmount) < len(countries) {
2024-08-26 14:22:24 +02:00
shuffledCountries = shuffledCountries[0:gameSession.QuestionAmount]
}
2024-08-26 20:28:20 +02:00
var timeleft = []string{}
if gameSession.Seconds != 0 {
timeleft = append(timeleft, strconv.Itoa(int(gameSession.Seconds)-int(time.Since(gameSession.CreatedAt).Seconds())))
}
2024-08-26 14:22:24 +02:00
flag, err := emoji.CountryFlag(shuffledCountries[gameSession.QuestionCurrent-1])
if err != nil {
return err
}
data := *web.Common(c)
data["Title"] = "tmp"
2024-08-26 20:28:20 +02:00
data["TimeLeft"] = timeleft
data["QuestionsLeft"] = len(shuffledCountries) - int(gameSession.QuestionCurrent) + 1
2024-08-26 14:22:24 +02:00
data["Answers"] = shuffledAnswers
data["Flag"] = flag
2024-08-26 16:46:28 +02:00
data["Errors"] = gameSession.QuestionsErrors
2024-08-26 14:22:24 +02:00
return c.Render("apps/flags/question", data, "layouts/base")
}
2024-08-26 20:28:20 +02:00
func sharedGameHandler(c *fiber.Ctx) error {
shareKey := c.FormValue("sharekey")
data, err := db.Queries.AppFlagsGetSharedData(context.TODO(), shareKey)
if err != nil {
return err
}
return setupGame(c, data.Tags, int(data.Questions), int(data.Seconds), true, data.GameSeed)
2024-08-26 16:46:28 +02:00
}
2024-08-26 14:22:24 +02:00
func startNewGameHandler(c *fiber.Ctx) error {
values := c.Request().PostArgs().PeekMulti("tags")
var selectedTags []string
for _, v := range values {
selectedTags = append(selectedTags, string(v))
}
2024-08-26 17:43:36 +02:00
if len(selectedTags) < 1 {
return c.Status(http.StatusBadRequest).SendString(i18n.GetTranslations(i18n.GetLanguage(c))["select_more_countries"])
}
err, countries := filterCountriesByTags(selectedTags)
if err != nil {
return err
}
if len(countries) < 6 {
return c.Status(http.StatusBadRequest).SendString(i18n.GetTranslations(i18n.GetLanguage(c))["select_more_countries"])
}
2024-08-26 14:22:24 +02:00
maxQuestions, err := strconv.Atoi(c.FormValue("max_questions"))
if err != nil {
return err
}
2024-08-26 20:28:20 +02:00
seconds, err := strconv.Atoi(c.FormValue("seconds"))
if err != nil {
return err
}
if c.FormValue("share") != "" {
return createSharedGameData(c, selectedTags, maxQuestions, seconds)
}
return setupGame(c, selectedTags, maxQuestions, seconds, false, uuid.UUID{})
}
func createSharedGameData(c *fiber.Ctx, tags []string, maxQuestions int, seconds int) error {
shareKey := utils.RandString(4)
_, err := db.Queries.AppFlagsNewSharedData(context.TODO(), queries.AppFlagsNewSharedDataParams{
ShareKey: shareKey,
Tags: tags,
Questions: int32(maxQuestions),
Seconds: int32(seconds),
})
if err != nil {
return err
}
data := *web.Common(c)
data["Title"] = "tmp"
data["ShareKey"] = shareKey
return c.Render("apps/flags/shared", data, "layouts/base")
}
func setupGame(c *fiber.Ctx, tags []string, maxQuestions int, seconds int, useGameSeed bool, gameSeed uuid.UUID) error {
2024-08-26 14:22:24 +02:00
var Quid = sql.NullString{}
uid, err := user.GetSession(c)
if err == nil {
Quid.Valid = true
Quid.String = uid
}
2024-08-26 20:28:20 +02:00
createGameParams := queries.AppFlagsCreateGameWithSeedParams{
2024-08-26 14:22:24 +02:00
Uid: Quid,
2024-08-26 20:28:20 +02:00
Tags: tags,
2024-08-26 14:22:24 +02:00
QuestionAmount: int32(maxQuestions),
2024-08-26 20:28:20 +02:00
Seconds: int32(seconds),
GameSeed: uuid.New(),
}
if useGameSeed {
createGameParams.GameSeed = gameSeed
}
gameID, err := db.Queries.AppFlagsCreateGameWithSeed(context.TODO(), createGameParams)
2024-08-26 14:22:24 +02:00
if err != nil {
return err
}
c.Cookie(&fiber.Cookie{
2024-08-26 16:57:28 +02:00
Name: flagSessionCookie,
2024-08-26 20:28:20 +02:00
Value: gameID.String(),
2024-08-26 16:46:28 +02:00
//Secure: true,
2024-08-26 14:22:24 +02:00
})
2024-08-26 20:28:20 +02:00
return questionHandler(c, NewGameUUID{used: true, UUID: gameID})
2024-08-26 14:22:24 +02:00
}
2024-08-26 16:46:28 +02:00
func gameEndHandler(c *fiber.Ctx) error {
2024-08-26 16:57:28 +02:00
gameId, err := uuid.Parse(c.Cookies(flagSessionCookie))
2024-08-26 16:46:28 +02:00
if err != nil {
return err
}
2024-08-26 20:28:20 +02:00
gameSession, err := db.Queries.AppFlagsGetGame(context.TODO(), gameId)
2024-08-26 16:46:28 +02:00
if err != nil {
return err
}
data := *web.Common(c)
data["Title"] = "tmp"
data["Errors"] = gameSession.QuestionsErrors
return c.Render("apps/flags/end", data, "layouts/base")
}
func stopGameHandler(c *fiber.Ctx) error { // exit game
2024-08-26 16:57:28 +02:00
utils.ClearCookie(c, flagSessionCookie)
2024-08-26 17:43:36 +02:00
return gameStartHandler(c)
2024-08-26 14:22:24 +02:00
}
2024-08-26 16:57:28 +02:00
2024-08-26 17:43:36 +02:00
func gameStartHandler(c *fiber.Ctx) error {
2024-08-26 16:57:28 +02:00
data := *web.Common(c)
data["Title"] = "tmp"
data["SupportedTags"] = supportedTags
return c.Render("apps/flags/start", data, "layouts/base")
}