Files
gralias/handlers/handlers.go
2025-07-03 08:15:54 +03:00

130 lines
3.2 KiB
Go

package handlers
import (
"gralias/broker"
"gralias/config"
"gralias/models"
"gralias/repos"
"html/template"
"log/slog"
"net/http"
"os"
)
var (
log *slog.Logger
cfg *config.Config
// memcache cache.Cache
Notifier *broker.Broker
repo repos.AllRepos
)
func init() {
log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelDebug,
AddSource: true,
}))
// memcache = cache.MemCache
cfg = config.LoadConfigOrDefault("")
Notifier = broker.Notifier
// cache.MemCache.StartBackupRoutine(15 * time.Second) // Reduced backup interval
// bot loader
// check the rooms if it has bot_{digits} in them, create bots if have
repo = repos.NewRepoProvider("sqlite3://../gralias.db")
recoverBots()
// if player has a roomID, but no team and role, try to recover
// recoverPlayers()
}
func HandlePing(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write([]byte("pong")); err != nil {
log.Error("failed to write ping response", "error", err)
}
}
func HandleHome(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
fi, err := getFullInfoByCtx(r.Context())
if err != nil {
log.Error("failed to fetch fi", "error", err)
}
if fi != nil && fi.Room != nil && fi.State != nil {
fi.Room.UpdateCounter()
if fi.State.Role == "mime" {
fi.Room.MimeView() // there must be a better way
} else {
fi.Room.GuesserView()
}
}
if fi != nil && fi.Room == nil {
rooms, err := repo.RoomList(r.Context())
if err != nil {
log.Error("failed to list rooms;", "error", err)
}
fi.List = rooms
}
if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
log.Error("failed to exec templ;", "error", err, "templ", "base")
}
}
func HandleExit(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
fi, err := getFullInfoByCtx(r.Context())
if err != nil {
abortWithError(w, err.Error())
return
}
if fi.Room.IsRunning {
abortWithError(w, "cannot leave when game is running")
return
}
var creatorLeft bool
if fi.Room.CreatorName == fi.State.Username {
creatorLeft = true
}
exitedRoom := fi.ExitRoom()
// if err := saveRoom(exitedRoom); err != nil {
// abortWithError(w, err.Error())
// return
// }
if creatorLeft {
if err := repo.RoomDeleteByID(r.Context(), exitedRoom.ID); err != nil {
log.Error("failed to remove room", "error", err)
}
// removeRoom(exitedRoom.ID)
// TODO: notify users if creator left
// and throw them away
notify(models.NotifyRoomListUpdate, "")
}
// scary to update the whole room
fiToSave := &models.FullInfo{
Room: exitedRoom,
}
if err := saveFullInfo(r.Context(), fiToSave); err != nil {
abortWithError(w, err.Error())
return
}
if err := repo.PlayerExitRoom(r.Context(), fi.State.Username); err != nil {
abortWithError(w, err.Error())
return
}
// fi.List = listRooms(false)
fi.List, err = repo.RoomList(r.Context())
if err != nil {
abortWithError(w, err.Error())
return
}
if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
log.Error("failed to exec templ;", "error", err, "templ", "base")
}
}