commit bab474c070c66a26e841b2864ad6d4bebd97abee
parent 0b1ca6563b4593dafa7529440276056fae716e68
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Mon, 4 Dec 2023 21:19:04 -0500
check action & cleanup
Diffstat:
3 files changed, 112 insertions(+), 80 deletions(-)
diff --git a/pkg/web/handlers/poker.go b/pkg/web/handlers/poker.go
@@ -34,13 +34,22 @@ func (p *Poker) GetOrCreateGame(roomID string) *PokerGame {
g, found := p.Games[roomID]
if !found {
g = &PokerGame{
- Players: make([]string, NbPlayers),
+ PlayersEventCh: make(chan PlayerEvent),
+ Players: make([]string, NbPlayers),
}
p.Games[roomID] = g
}
return g
}
+type PlayerEvent struct {
+ Player string
+ Call bool
+ Check bool
+ Fold bool
+ Bet int
+}
+
var PokerInstance = NewPoker()
type Ongoing struct {
@@ -51,8 +60,10 @@ type Ongoing struct {
type PokerGame struct {
sync.Mutex
- Players []string
- Ongoing *Ongoing
+ PlayersEventCh chan PlayerEvent
+ Players []string
+ Ongoing *Ongoing
+ DealerIdx int
}
func (g *PokerGame) Deal(roomID string) {
@@ -80,6 +91,31 @@ func (g *PokerGame) Deal(roomID string) {
g.Ongoing = &Ongoing{Deck: deck, Players: players}
go func() {
+
+ waitPlayersActionFn := func() {
+ for _, p := range g.Ongoing.Players {
+ if p != "" {
+ fmt.Println("WAIT FOR ACTION", p)
+ waitCh := time.After(10 * time.Second)
+ LOOP:
+ for {
+ var evt PlayerEvent
+ select {
+ case evt = <-g.PlayersEventCh:
+ case <-waitCh:
+ fmt.Println("WAIT TOO LONG, either auto check, or fold")
+ break LOOP
+ }
+ if evt.Player != p {
+ continue
+ }
+ fmt.Println("GOT FROM", evt.Player, evt)
+ break
+ }
+ }
+ }
+ }
+
myTopic := "room_" + roomID
type Seat struct {
Top int
@@ -101,16 +137,38 @@ func (g *PokerGame) Deal(roomID string) {
//{Top: 150, Left: 550},
}
- type Data struct {
- Top int
- Left int
- Angle string
- Reveal bool
- }
-
var card string
idx := 0
+ burnCard := func() {
+ idx++
+ card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
+ evt := PokerEvent{
+ ID: "card" + strconv.Itoa(idx),
+ Name: "",
+ Idx: idx,
+ Top: 34,
+ Left: 408,
+ Burn: true,
+ }
+ PokerPubSub.Pub(myTopic, evt)
+ g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ }
+
+ dealCard := func(pos int) {
+ idx++
+ card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
+ evt := PokerEvent{
+ ID: "card" + strconv.Itoa(idx),
+ Name: card,
+ Idx: idx,
+ Top: 150,
+ Left: 100 + (pos * 55),
+ }
+ PokerPubSub.Pub(myTopic, evt)
+ g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ }
+
// Deal cards
for j := 1; j <= 2; j++ {
for i, p := range g.Ongoing.Players {
@@ -142,92 +200,43 @@ func (g *PokerGame) Deal(roomID string) {
}
}
+ // Wait for players to bet/call/check/fold...
+ waitPlayersActionFn()
+
// Burn
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt := PokerEvent{
- ID: "card" + strconv.Itoa(idx),
- Name: "",
- Idx: idx,
- Top: 30,
- Left: 400,
- Burn: true,
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ burnCard()
// Flop (3 first cards)
for i := 1; i <= 3; i++ {
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt := PokerEvent{
- ID: "card" + strconv.Itoa(idx),
- Name: card,
- Idx: idx,
- Top: 150,
- Left: 100 + (i * 55),
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ dealCard(i)
}
+ // Wait for players to bet/call/check/fold...
+ waitPlayersActionFn()
+
// Burn
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt = PokerEvent{
- ID: "card" + strconv.Itoa(idx),
- Name: "",
- Idx: idx,
- Top: 32,
- Left: 404,
- Burn: true,
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ burnCard()
// Turn (4th card)
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt = PokerEvent{
- ID: "card" + strconv.Itoa(idx), Name: card,
- Idx: idx,
- Top: 150,
- Left: 100 + (4 * 55),
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ dealCard(4)
+
+ // Wait for players to bet/call/check/fold...
+ waitPlayersActionFn()
// Burn
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt = PokerEvent{
- ID: "card" + strconv.Itoa(idx),
- Name: "",
- Idx: idx,
- Top: 34,
- Left: 408,
- Burn: true,
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ burnCard()
// River (5th card)
time.Sleep(time.Second)
- idx++
- card, g.Ongoing.Deck = g.Ongoing.Deck[0], g.Ongoing.Deck[1:]
- evt = PokerEvent{
- ID: "card" + strconv.Itoa(idx), Name: card,
- Idx: idx,
- Top: 150,
- Left: 100 + (5 * 55),
- }
- PokerPubSub.Pub(myTopic, evt)
- g.Ongoing.Events = append(g.Ongoing.Events, evt)
+ dealCard(5)
+
+ // Wait for players to bet/call/check/fold...
+ waitPlayersActionFn()
}()
}
@@ -272,6 +281,24 @@ type PokerSeatLeftEvent struct {
var PokerPubSub = pubsub.NewPubSub[any]()
+func PokerCheckHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ roomID := c.Param("roomID")
+ PokerInstance.Lock()
+ g, found := PokerInstance.Games[roomID]
+ PokerInstance.Unlock()
+ if !found {
+ return c.NoContent(http.StatusNotFound)
+ }
+ if c.Request().Method == http.MethodPost {
+ select {
+ case g.PlayersEventCh <- PlayerEvent{Player: authUser.Username.String(), Check: true}:
+ default:
+ }
+ }
+ return c.HTML(http.StatusOK, `<form method="post"><button>Check</button></form>`)
+}
+
func PokerDealHandler(c echo.Context) error {
roomID := c.Param("roomID")
PokerInstance.Lock()
@@ -468,8 +495,9 @@ body {
.takeSeat8 { position: absolute; top: 300px; left: 350px; }
.takeSeat9 { position: absolute; top: 300px; left: 300px; }
.takeSeat10 { position: absolute; top: 300px; left: 250px; }
-#dealBtn { position: absolute; top: 400px; left: 50px; }
-#unSitBtn { position: absolute; top: 430px; left: 50px; }
+#dealBtn { position: absolute; top: 400px; left: 50px; width: 50px; height: 30px; }
+#unSitBtn { position: absolute; top: 430px; left: 50px; width: 50px; height: 30px; }
+#checkBtn { width: 100px; height: 30px; }
</style>`)
drawSeats := func() {
@@ -524,7 +552,7 @@ body {
<div style="position: absolute; top: 400px; left: 200px;">
<form><input type="number" /><button>Bet</button></form>
<form><button>call</button></form>
- <form><button>check</button></form>
+ <iframe src="/poker/` + roomID + `/check" id="checkBtn"></iframe>
<form><button>fold</button></form>
</div>`
send(turnAction)
diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go
@@ -183,6 +183,7 @@ func CSRFMiddleware() echo.MiddlewareFunc {
c.Path() == "/chess/:key" ||
c.Path() == "/poker/:roomID/sit/:pos" ||
c.Path() == "/poker/:roomID/unsit" ||
+ c.Path() == "/poker/:roomID/check" ||
c.Path() == "/poker/:roomID/deal"
},
}
@@ -295,6 +296,7 @@ func IsAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
!strings.Contains(c.Path(), "/api/v1/chat/controls") &&
!strings.Contains(c.Path(), "/poker/:roomID/sit/:pos") &&
!strings.Contains(c.Path(), "/poker/:roomID/unsit") &&
+ !strings.Contains(c.Path(), "/poker/:roomID/check") &&
!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
@@ -98,6 +98,8 @@ 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", handlers.PokerHandler)
+ authGroup.GET("/poker/:roomID/check", handlers.PokerCheckHandler)
+ authGroup.POST("/poker/:roomID/check", handlers.PokerCheckHandler)
authGroup.GET("/poker/:roomID/deal", handlers.PokerDealHandler)
authGroup.POST("/poker/:roomID/deal", handlers.PokerDealHandler)
authGroup.GET("/poker/:roomID/unsit", handlers.PokerUnSitHandler)