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, _ := getFullInfoByCtx(r.Context()) 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") } }