dkforest

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

commit 78c297e39bf352e11dfde0fbbd3189fdd846c81d
parent 14f11896a663017c8aa8d3327d368ae7bc20066e
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Wed,  6 Dec 2023 01:03:45 -0500

logs

Diffstat:
Mpkg/web/handlers/poker/events.go | 4++++
Mpkg/web/handlers/poker/poker.go | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mpkg/web/middlewares/middlewares.go | 3+++
Mpkg/web/web.go | 1+
4 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/pkg/web/handlers/poker/events.go b/pkg/web/handlers/poker/events.go @@ -31,6 +31,10 @@ type PlayerBetEvent struct { Cash int } +type LogEvent struct { + Message string +} + type ErrorMsgEvent struct { Message string } diff --git a/pkg/web/handlers/poker/poker.go b/pkg/web/handlers/poker/poker.go @@ -220,6 +220,9 @@ OUTER: for { // Repeat until we get an event from the player we're interested in var evt PlayerEvent + roomUserTopic := "room_" + roomID + "_" + p.Username + roomLogsTopic := "room_" + roomID + "_logs" + select { case evt = <-g.PlayersEventCh: case <-waitCh: @@ -230,21 +233,24 @@ OUTER: if p.Bet < minBet { player.Folded = true PokerPubSub.Pub(roomTopic, PlayerFoldEvent{Card1Idx: player.Cards[0].Idx, Card2Idx: player.Cards[1].Idx}) + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s auto fold", p.Username)}) playerAlive-- if playerAlive == 1 { break OUTER } + break LOOP } + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s auto check", p.Username)}) break LOOP } if evt.Player != p.Username { continue } - roomUserTopic := "room_" + roomID + "_" + p.Username if evt.Fold { player.Folded = true PokerPubSub.Pub(roomTopic, PlayerFoldEvent{Card1Idx: player.Cards[0].Idx, Card2Idx: player.Cards[1].Idx}) + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s fold", p.Username)}) playerAlive-- if playerAlive == 1 { break OUTER @@ -255,6 +261,7 @@ OUTER: PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: msg}) continue } + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s check", p.Username)}) } else if evt.Call { bet := minBet - p.Bet if p.Cash < bet { @@ -267,6 +274,7 @@ OUTER: p.Cash -= bet } PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: bet, TotalBet: p.Bet, Cash: p.Cash}) + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s call", p.Username)}) } else if evt.Bet > 0 { if (p.Bet + evt.Bet) < minBet { msg := fmt.Sprintf("Bet (%d) is too low. Must bet at least %d", evt.Bet, minBet-p.Bet) @@ -280,6 +288,7 @@ OUTER: p.Bet += evt.Bet p.Cash -= evt.Bet PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: evt.Bet, TotalBet: p.Bet, Cash: p.Cash}) + PokerPubSub.Pub(roomLogsTopic, LogEvent{Message: fmt.Sprintf("%s bet %d", p.Username, evt.Bet)}) } break } @@ -1081,7 +1090,7 @@ body { #yourCard1 { font-size: 22px; display: inline-block; margin-right: 15px; } #yourCard2 { font-size: 22px; display: inline-block; } #errorMsg { position: absolute; top: 530px; left: 150px; color: darkred; } -#eventLogs { position: absolute; bottom: 5px; right: 5px; width: 200px; height: 200px; border: 1px solid black; background-color: #ccc; } +#eventLogs { position: absolute; bottom: 5px; right: 5px; width: 200px; height: 200px; border: 1px solid black; } .timer { @@ -1130,6 +1139,48 @@ body { </style>` +func PokerLogsHandler(c echo.Context) error { + roomID := c.Param("roomID") + send := func(s string) { + _, _ = c.Response().Write([]byte(s)) + } + roomLogsTopic := "room_" + roomID + "_logs" + sub := PokerPubSub.Subscribe([]string{roomLogsTopic}) + defer sub.Close() + quit := hutils.CloseSignalChan(c) + 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) + 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 + } + + switch evt := payload.(type) { + case LogEvent: + send(fmt.Sprintf(`<div>%s</div>`, evt.Message)) + c.Response().Flush() + } + } + return nil +} + func PokerHandler(c echo.Context) error { roomID := c.Param("roomID") g := PokerInstance.GetOrCreateGame(roomID) @@ -1164,7 +1215,7 @@ func PokerHandler(c echo.Context) error { actions := `<iframe src="/poker/` + roomID + `/deal" id="dealBtn"></iframe>` actions += `<iframe src="/poker/` + roomID + `/unsit" id="unSitBtn"></iframe>` send(actions) - send(`<div id="eventLogs"></div>`) + send(`<iframe src="/poker/` + roomID + `/logs" id="eventLogs"></iframe>`) send(`<div id="errorMsg"></div>`) send(`<div id="seat1Pot"></div>`) // TODO send(`<div id="seat2Pot"></div>`) // TODO diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go @@ -34,6 +34,7 @@ var GzipMiddleware = middleware.GzipWithConfig( c.Path() == "/chess/:key" || c.Path() == "/chess/:key/analyze" || c.Path() == "/poker/:roomID" || + c.Path() == "/poker/:roomID/logs" || c.Path() == "/api/v1/chat/messages/:roomName/stream" || c.Path() == "/uploads/:filename" || c.Path() == "/" { @@ -187,6 +188,7 @@ func CSRFMiddleware() echo.MiddlewareFunc { c.Path() == "/poker/:roomID/fold" || c.Path() == "/poker/:roomID/call" || c.Path() == "/poker/:roomID/bet" || + c.Path() == "/poker/:roomID/logs" || c.Path() == "/poker/:roomID/deal" }, } @@ -303,6 +305,7 @@ func IsAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc { !strings.Contains(c.Path(), "/poker/:roomID/fold") && !strings.Contains(c.Path(), "/poker/:roomID/call") && !strings.Contains(c.Path(), "/poker/:roomID/bet") && + !strings.Contains(c.Path(), "/poker/:roomID/logs") && !strings.Contains(c.Path(), "/poker/:roomID/deal") { c.Response().Header().Set("X-Frame-Options", "DENY") } diff --git a/pkg/web/web.go b/pkg/web/web.go @@ -99,6 +99,7 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te authGroup.GET("/donate", handlers.DonateHandler) authGroup.GET("/shop", handlers.ShopHandler) authGroup.GET("/poker/:roomID", poker.PokerHandler) + authGroup.GET("/poker/:roomID/logs", poker.PokerLogsHandler) authGroup.GET("/poker/:roomID/check", poker.PokerCheckHandler) authGroup.POST("/poker/:roomID/check", poker.PokerCheckHandler) authGroup.GET("/poker/:roomID/fold", poker.PokerFoldHandler)