263 lines
7.0 KiB
Go
263 lines
7.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"fmt"
|
|
"gralias/llmapi"
|
|
"gralias/models"
|
|
"html/template"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
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 err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
|
abortWithError(w, err.Error())
|
|
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: models.ActionTypeGuess,
|
|
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 > 0 {
|
|
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: models.WordColorBlack,
|
|
Action: models.ActionTypeGameOver,
|
|
}
|
|
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: models.WordColorBlue,
|
|
Action: models.ActionTypeGameOver,
|
|
}
|
|
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: models.WordColorRed,
|
|
Action: models.ActionTypeGameOver,
|
|
}
|
|
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 HandleMarkCard(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 err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
|
abortWithError(w, err.Error())
|
|
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{}
|
|
// check if card already was revealed
|
|
for i, card := range fi.Room.Cards {
|
|
if !strings.EqualFold(card.Word, word) {
|
|
continue
|
|
}
|
|
if card.Revealed {
|
|
abortWithError(w, "cannot mark already revealed")
|
|
return
|
|
}
|
|
// Check if the current user already has an active mark on this card
|
|
found := false
|
|
var newMarks []models.CardMark
|
|
for _, mark := range card.Mark {
|
|
if mark.Username == fi.State.Username && mark.Active {
|
|
found = true
|
|
} else {
|
|
newMarks = append(newMarks, mark)
|
|
}
|
|
}
|
|
if !found {
|
|
newMarks = append(newMarks, models.CardMark{
|
|
Username: fi.State.Username,
|
|
Active: true,
|
|
})
|
|
}
|
|
fi.Room.Cards[i].Mark = newMarks
|
|
cardword = fi.Room.Cards[i]
|
|
}
|
|
if err := saveFullInfo(fi); err != nil {
|
|
abortWithError(w, err.Error())
|
|
return
|
|
}
|
|
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?
|
|
_, err = llmapi.NewBot(role, team, botname, fi.Room.ID, cfg, false)
|
|
if err != nil {
|
|
abortWithError(w, err.Error())
|
|
return
|
|
}
|
|
// go bot.StartBot()
|
|
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
|
|
}
|
|
|
|
func HandleRemoveBot(w http.ResponseWriter, r *http.Request) {
|
|
botName := r.URL.Query().Get("bot")
|
|
log.Debug("got remove-bot request", "bot_name", botName)
|
|
fi, err := getFullInfoByCtx(r.Context())
|
|
if err != nil {
|
|
abortWithError(w, err.Error())
|
|
return
|
|
}
|
|
if err := llmapi.RemoveBot(botName, fi.Room); err != nil {
|
|
abortWithError(w, err.Error())
|
|
return
|
|
}
|
|
notify(models.NotifyRoomUpdatePrefix+fi.Room.ID, "")
|
|
}
|