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, })) cfg = config.LoadConfigOrDefault("") Notifier = broker.Notifier // repo = repos.NewRepoProvider("sqlite3://../gralias.db") repo = repos.RP recoverBots() } 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) } // there must be a better way if fi != nil && fi.Room != nil && fi.Room.ID != "" && 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 } // if creator leaves, remove all players from room and delete room if fi.Room.CreatorName == fi.State.Username { players, err := repo.PlayerListByRoom(r.Context(), fi.Room.ID) if err != nil { log.Error("failed to list players in room", "error", err) abortWithError(w, err.Error()) return } for _, p := range players { if p.IsBot { if err := repo.PlayerDelete(r.Context(), p.Username); err != nil { log.Error("failed to delete bot", "error", err) } continue } if err := repo.PlayerExitRoom(r.Context(), p.Username); err != nil { log.Error("failed to exit room", "error", err) } } if err := repo.RoomDeleteByID(r.Context(), fi.Room.ID); err != nil { log.Error("failed to remove room", "error", err) } notify(models.NotifyRoomListUpdate, "") } else { // if regular player leaves, just exit room if err := repo.PlayerExitRoom(r.Context(), fi.State.Username); err != nil { log.Error("failed to exit room", "error", err) abortWithError(w, err.Error()) return } } fi.Room = nil fi.State.RoomID = nil 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") } } func HandleStats(w http.ResponseWriter, r *http.Request) { log.Debug("got stats call") tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) return } stats, err := repo.GetAllPlayerStats(r.Context()) if err != nil { log.Error("failed to get all player stats", "error", err) abortWithError(w, "failed to retrieve player stats") return } fi, err := getFullInfoByCtx(r.Context()) if err != nil || fi == nil { log.Error("failed to fetch fi", "error", err) http.Redirect(w, r, "/", 302) return } // there must be a better way if fi != nil && fi.Room != nil && fi.Room.ID != "" && 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 } fi.List = nil if err := tmpl.ExecuteTemplate(w, "stats", stats); err != nil { log.Error("failed to exec templ;", "error", err, "templ", "base") } }