dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 19b759500e2ec6cd9f3104f195fc81e1aa0bfba9
parent 92fa825091d1f5f8b86b4cf7b1b7d789ff95da46
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sun,  3 Dec 2023 21:42:59 -0500

test poker

Diffstat:
Mpkg/web/handlers/handlers.go | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/web/middlewares/middlewares.go | 1+
Mpkg/web/web.go | 1+
3 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -8,9 +8,11 @@ import ( "dkforest/pkg/database" dutils "dkforest/pkg/database/utils" "dkforest/pkg/odometer" + "dkforest/pkg/pubsub" "dkforest/pkg/utils" hutils "dkforest/pkg/web/handlers/utils" "encoding/base64" + "errors" "fmt" humanize "github.com/dustin/go-humanize" "github.com/labstack/echo" @@ -28,6 +30,7 @@ import ( "os" "path/filepath" "regexp" + "strconv" "strings" "time" ) @@ -751,3 +754,151 @@ func BHCHandler(c echo.Context) error { data.Success = fmt.Sprintf("Good answer, go back to BHC and use '%s' as your username", username+h[:3]) return c.Render(http.StatusOK, "bhc", data) } + +type PokerEvent struct { + ID string + Name string +} + +var PokerPubSub = pubsub.NewPubSub[PokerEvent]() + +func PokerHandler(c echo.Context) error { + // players 2-10 + // $5 -> 1000 chips + // generate deck + // hash the deck and show hash + //return c.Render(http.StatusOK, "poker", nil) + + authUser := c.Get("authUser").(*database.User) + + send := func(s string) { + _, _ = c.Response().Write([]byte(s)) + } + + names := []string{ + "A♠", "2♠", "3♠", "4♠", "5♠", "6♠", "7♠", "8♠", "9♠", "10♠", "J♠", "Q♠", "K♠", + "A♥", "2♥", "3♥", "4♥", "5♥", "6♥", "7♥", "8♥", "9♥", "10♥", "J♥", "Q♥", "K♥", + "A♣", "2♣", "3♣", "4♣", "5♣", "6♣", "7♣", "8♣", "9♣", "10♣", "J♣", "Q♣", "K♣", + "A♦", "2♦", "3♦", "4♦", "5♦", "6♦", "7♦", "8♦", "9♦", "10♦", "J♦", "Q♦", "K♦", + } + + quit := hutils.CloseSignalChan(c) + myTopic := "room_" + authUser.ID.String() + + go func() { + for i := 1; i <= 5; i++ { + select { + case <-time.After(2 * time.Second): + case <-quit: + return + } + PokerPubSub.Pub(myTopic, PokerEvent{ID: "card" + strconv.Itoa(i), Name: utils.RandChoice(names)}) + } + }() + + sub := PokerPubSub.Subscribe([]string{myTopic}) + defer sub.Close() + + c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8) + c.Response().WriteHeader(http.StatusOK) + c.Response().Header().Set("Transfer-Encoding", "chunked") + c.Response().Header().Set("Connection", "keep-alive") + + send(cssReset) + send(`<style> +body { + background:linear-gradient(135deg, #449144 33%,#008a00 95%); + padding:4% 10%; +} +@keyframes fly-in { + 0% { + transform: rotateY(180deg) rotateX(0) translateZ(0) translateX(0) translateY(0); + } + 100% { + transform: rotateY(0) rotateX(0) translateZ(0) translateX(0) translateY(0); + } +} +.card-holder{ + transform: rotateY( 180deg ); + transform-style: preserve-3d; + backface-visibility: hidden; + position:relative; + width:100px; + height:140px; + display:inline-block; + box-shadow:1px 2px 2px rgba(0,0,0,.8); + margin:2px; +} +.card { + box-shadow: inset 2px 2px 0 #fff, inset -2px -2px 0 #fff; + transform-style: preserve-3d; + position:absolute; + top:0; + left:0; + bottom:0; + right:0; + backface-visibility: hidden; + background-color:#fcfcfc; + border-radius:2%; + display:block; + width:100%; + height:100%; + border:1px solid black; +} +.back{ + position:absolute; + top:0; + left:0; + bottom:0; + right:0; + width:100%; + height:100%; + backface-visibility: hidden; + transform: rotateY( 180deg ); + background: #36c; + background: + linear-gradient(135deg, #f26c32 0%,#c146a1 50%,#a80077 51%,#f9703e 100%); + border-radius:2%; + box-shadow: inset 3px 3px 0 #fff, inset -3px -3px 0 #fff; + display:block; + border:1px solid black; +} +</style>`) + send(` +<div class="card-holder" id="card1"><div class="back"></div><div class="card ace clubs"></div></div> +<div class="card-holder" id="card2"><div class="back"></div><div class="card ace clubs"></div></div> +<div class="card-holder" id="card3"><div class="back"></div><div class="card ace clubs"></div></div> +<div class="card-holder" id="card4"><div class="back"></div><div class="card ace clubs"></div></div> +<div class="card-holder" id="card5"><div class="back"></div><div class="card ace clubs"></div></div> +`) + c.Response().Flush() +Loop: + for { + select { + case <-quit: + break Loop + default: + } + + _, payload, err := sub.ReceiveTimeout2(1*time.Second, quit) + if err != nil { + if errors.Is(err, pubsub.ErrCancelled) { + break Loop + } + continue + } + fmt.Println(payload) + send(`<style> +#` + payload.ID + ` { + animation-name:fly-in; + animation-duration:1s; + animation-direction:alternate; + animation-timing-function:ease-in-out; + animation-fill-mode: forwards; +} +#` + payload.ID + ` .card:before { content: "` + payload.Name + `"; } +</style>`) + c.Response().Flush() + } + return nil +} diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go @@ -33,6 +33,7 @@ var GzipMiddleware = middleware.GzipWithConfig( c.Path() == "/vip/challenges/re-1/:filename" || c.Path() == "/chess/:key" || c.Path() == "/chess/:key/analyze" || + c.Path() == "/poker" || c.Path() == "/api/v1/chat/messages/:roomName/stream" || c.Path() == "/uploads/:filename" || c.Path() == "/" { diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -97,6 +97,7 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te authGroup.POST("/captcha", handlers.CaptchaHandler, middlewares.AuthRateLimitMiddleware(time.Second, 1)) authGroup.GET("/donate", handlers.DonateHandler) authGroup.GET("/shop", handlers.ShopHandler) + authGroup.GET("/poker", handlers.PokerHandler) authGroup.GET("/chess", handlers.ChessHandler) authGroup.POST("/chess", handlers.ChessHandler) authGroup.GET("/chess/analyze", handlers.ChessAnalyzeHandler)