package web import ( "net/http" "pete/internal/games/blackjack" "pete/internal/storage" ) // The casino's two pages. Both require a signed-in visitor — there is money in // here, and a player has to be somebody gogobee's ledger can name. // // Neither page renders any game state server-side. The felt is drawn by the // browser from /api/games/table, because a hand is a thing that *happens*: cards // are dealt one at a time and the table plays that back. A server-rendered hand // would arrive fully formed, which is the one thing a card table must never do. // gameTeaser is a table that isn't open yet. They're on the lobby because an // empty casino with one game reads as broken, and this reads as early. type gameTeaser struct { Name string Emoji string Blurb string } var comingSoon = []gameTeaser{ {Name: "Hold'em", Emoji: "♠️", Blurb: "Six seats, and Pete's bots know how to play."}, {Name: "UNO", Emoji: "🎴", Blurb: "Normal rules, or no mercy."}, {Name: "Trivia", Emoji: "🧠", Blurb: "Faster answers score higher."}, {Name: "Hangman", Emoji: "🪢", Blurb: "Guess the phrase before Pete finishes drawing."}, } // betDenominations are the chips you build a bet out of. var betDenominations = []int64{5, 25, 100, 500} type gamesPage struct { pageData Cap int64 RakePct int Soon []gameTeaser Denominations []int64 } // requirePlayer sends an anonymous visitor to sign in and comes back here after. // Anyone who is signed in but carries a session from before the casino existed // has no username in it, so they get sent through sign-in too — which mints one. func (s *Server) requirePlayer(w http.ResponseWriter, r *http.Request) bool { if !s.gamesReady() { http.NotFound(w, r) return false } u := s.auth.userFromRequest(r) if u != nil && u.MatrixUser(s.cfg.Games.MatrixServer) != "" { return true } http.Redirect(w, r, "/auth/login?next="+r.URL.Path, http.StatusFound) return false } func (s *Server) gamesPage(r *http.Request) gamesPage { base := s.base(r) base.NoIndex = true // the casino is for players, not for search engines return gamesPage{ pageData: base, Cap: storage.MaxChipsOnTable, RakePct: int(blackjack.DefaultRules().RakePct * 100), Soon: comingSoon, Denominations: betDenominations, } } func (s *Server) handleLobby(w http.ResponseWriter, r *http.Request) { if !s.requirePlayer(w, r) { return } s.render(w, "games", s.gamesPage(r)) } func (s *Server) handleBlackjack(w http.ResponseWriter, r *http.Request) { if !s.requirePlayer(w, r) { return } s.render(w, "blackjack", s.gamesPage(r)) }