Files
gralias/handlers/elements.go
2025-06-14 11:37:42 +03:00

195 lines
5.1 KiB
Go

package handlers
import (
"errors"
"fmt"
"gralias/llmapi"
"gralias/models"
"html/template"
"net/http"
)
func HandleShowCreateForm(w http.ResponseWriter, r *http.Request) {
show := true
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
if err := tmpl.ExecuteTemplate(w, "createform", show); err != nil {
log.Error("failed to execute createform template", "error", err)
}
}
func HandleHideCreateForm(w http.ResponseWriter, r *http.Request) {
show := false
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
if err := tmpl.ExecuteTemplate(w, "createform", show); err != nil {
log.Error("failed to execute createform template", "error", err)
}
}
func HandleShowColor(w http.ResponseWriter, r *http.Request) {
word := r.URL.Query().Get("word")
ctx := r.Context()
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
fi, err := getFullInfoByCtx(ctx)
if err != nil {
abortWithError(w, err.Error())
return
}
if fi.State.Role != "guesser" {
err = errors.New("need to be guesser to open the card")
abortWithError(w, err.Error())
return
}
// whos move it is?
if fi.State.Team != models.UserTeam(fi.Room.TeamTurn) {
err = errors.New("not your team's move")
abortWithError(w, err.Error())
return
}
if !fi.Room.MimeDone {
abortWithError(w, "wait for the clue")
return
}
color, exists := fi.Room.WCMap[word]
log.Debug("got show-color request", "word", word, "color", color)
if !exists {
abortWithError(w, "word is not found")
return
}
cardword := models.WordCard{
Word: word,
Color: color,
Revealed: true,
}
fi.Room.RevealSpecificWord(word)
fi.Room.UpdateCounter()
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: string(color),
Action: "guessed",
Word: word,
}
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
// if opened card is of color of opp team, change turn
oppositeColor := fi.Room.GetOppositeTeamColor()
fi.Room.OpenedThisTurn++
if fi.Room.ThisTurnLimit >= fi.Room.OpenedThisTurn {
// end turn
fi.Room.TeamTurn = oppositeColor
fi.Room.MimeDone = false
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
}
switch string(color) {
case "black":
// game over
fi.Room.IsRunning = false
fi.Room.IsOver = true
fi.Room.TeamWon = oppositeColor
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: "black",
Action: "game over",
}
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
case "white", string(oppositeColor):
// end turn
fi.Room.TeamTurn = oppositeColor
fi.Room.MimeDone = false
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
// check if no cards left => game over
if fi.Room.BlueCounter == 0 {
// blue won
fi.Room.IsRunning = false
fi.Room.IsOver = true
fi.Room.TeamWon = "blue"
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: "blue",
Action: "game over",
}
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
}
if fi.Room.RedCounter == 0 {
// red won
fi.Room.IsRunning = false
fi.Room.IsOver = true
fi.Room.TeamWon = "red"
action := models.Action{
Actor: fi.State.Username,
ActorColor: string(fi.State.Team),
WordColor: "red",
Action: "game over",
}
fi.Room.OpenedThisTurn = 0
fi.Room.ThisTurnLimit = 0
fi.Room.ActionHistory = append(fi.Room.ActionHistory, action)
}
}
if err := saveFullInfo(fi); err != nil {
abortWithError(w, err.Error())
return
}
// get mime bot for opp team and notify it
notifyBotIfNeeded(fi)
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
if err := tmpl.ExecuteTemplate(w, "cardword", cardword); err != nil {
log.Error("failed to execute cardword template", "error", err)
}
}
func HandleActionHistory(w http.ResponseWriter, r *http.Request) {
fi, err := getFullInfoByCtx(r.Context())
if err != nil {
abortWithError(w, err.Error())
return
}
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
if err := tmpl.ExecuteTemplate(w, "actionhistory", fi.Room.ActionHistory); err != nil {
log.Error("failed to execute actionhistory template", "error", err)
}
}
func HandleAddBot(w http.ResponseWriter, r *http.Request) {
// get team; // get role; make up a name
team := r.URL.Query().Get("team")
role := r.URL.Query().Get("role")
log.Debug("got add-bot request", "team", team, "role", role)
fi, err := getFullInfoByCtx(r.Context())
if err != nil {
abortWithError(w, err.Error())
return
}
botname := fmt.Sprintf("bot_%d", len(llmapi.SignalChanMap)+1) // what if many rooms?
bot, err := llmapi.NewBot(role, team, botname, fi.Room.ID, cfg)
if err != nil {
abortWithError(w, err.Error())
return
}
go bot.StartBot()
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
}