commit 281a51d21b42c730ce02bd4c4b79173ce27827f3
parent adcbe002b68dcc6a7ee0ed317d8695f8f280ec84
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Mon, 18 Dec 2023 03:30:56 -0500
buy-in when joining room
Diffstat:
6 files changed, 123 insertions(+), 87 deletions(-)
diff --git a/pkg/database/tablePokerTables.go b/pkg/database/tablePokerTables.go
@@ -89,6 +89,11 @@ func (d *DkfDB) GetPokerTableAccount(userID UserID, pokerTableID int64) (out Pok
return
}
+func (d *DkfDB) GetPokerTableAccounts(userID UserID) (out []PokerTableAccount, err error) {
+ err = d.db.Find(&out, "user_id = ?", userID).Error
+ return
+}
+
func (d *DkfDB) GetPokerTableAccountSums() (sumAmounts, sumBets PokerChip, err error) {
var tmp struct{ SumAmounts, SumBets PokerChip }
err = d.db.Raw(`SELECT SUM(amount) AS sum_amounts, SUM(amount_bet) AS sum_bets FROM poker_table_accounts`).Scan(&tmp).Error
diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go
@@ -699,3 +699,23 @@ func (d *DkfDB) SetPokerSubAddress(userID UserID, subAddress string) (err error)
err = d.db.Exec(`UPDATE users SET poker_xmr_sub_address = ? WHERE id = ?`, subAddress, userID).Error
return
}
+
+func (u *User) GetUserChips(isTest bool) PokerChip {
+ return utils.Ternary(isTest, u.ChipsTest, u.XmrBalance.ToPokerChip())
+}
+
+func (u *User) IncrUserChips(isTest bool, v PokerChip, decrement bool) {
+ if decrement {
+ if isTest {
+ u.ChipsTest -= v
+ } else {
+ u.XmrBalance -= v.ToPiconero()
+ }
+ } else {
+ if isTest {
+ u.ChipsTest += v
+ } else {
+ u.XmrBalance += v.ToPiconero()
+ }
+ }
+}
diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go
@@ -951,7 +951,8 @@ type chessData struct {
type TmpTable struct {
database.PokerTable
- NbSeated int
+ TableBalance database.PokerChip
+ NbSeated int
}
type pokerData struct {
@@ -967,6 +968,7 @@ type pokerData struct {
WithdrawAddress string
WithdrawUnique int64
Error string
+ ErrorTable string
HelperAmount string
HelperType string
HelperXmr string
diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go
@@ -789,12 +789,20 @@ func PokerHomeHandler(c echo.Context) error {
data.HelperChips = pxmr.ToPokerChip()
data.HelperpXmr = pxmr.RawString()
data.HelperUsd = pxmr.UsdStr()
+ userTableAccounts, _ := db.GetPokerTableAccounts(authUser.ID)
for _, t := range pokerTables {
var nbSeated int
if g := poker.PokerInstance.GetGame(poker.RoomID(t.Slug)); g != nil {
nbSeated = g.CountSeated()
}
- data.Tables = append(data.Tables, TmpTable{PokerTable: t, NbSeated: nbSeated})
+ tableBalance := database.PokerChip(0)
+ for _, a := range userTableAccounts {
+ if a.PokerTableID == t.ID {
+ tableBalance = a.Amount
+ break
+ }
+ }
+ data.Tables = append(data.Tables, TmpTable{PokerTable: t, NbSeated: nbSeated, TableBalance: tableBalance})
}
if authUser.PokerXmrSubAddress != "" {
@@ -836,35 +844,87 @@ func PokerHomeHandler(c echo.Context) error {
pokerTableSlug := c.Request().PostFormValue("table_slug")
playerBuyIn := database.PokerChip(utils.DoParseUint64(c.Request().PostFormValue("buy_in")))
tx := db.Begin()
- pokerTable, _ := tx.GetPokerTableBySlug(pokerTableSlug)
+ g := poker.PokerInstance.GetGame(poker.RoomID(pokerTableSlug))
+ if g != nil {
+ g.Players.Lock()
+ defer g.Players.Unlock()
+ if g.IsSeated2(authUser.Username) {
+ tx.Rollback()
+ data.ErrorTable = "Cannot buy-in while seated"
+ return c.Render(http.StatusOK, "poker", data)
+ }
+ }
+ pokerTable, err := tx.GetPokerTableBySlug(pokerTableSlug)
+ if err != nil {
+ tx.Rollback()
+ data.ErrorTable = "table mot found"
+ return c.Render(http.StatusOK, "poker", data)
+ }
if playerBuyIn < pokerTable.MinBuyIn {
tx.Rollback()
- data.Error = "buy in too small"
+ data.ErrorTable = "buy in too small"
return c.Render(http.StatusOK, "poker", data)
}
if playerBuyIn > pokerTable.MaxBuyIn {
tx.Rollback()
- data.Error = "buy in too high"
+ data.ErrorTable = "buy in too high"
return c.Render(http.StatusOK, "poker", data)
}
- userChips := authUser.ChipsTest
- if !pokerTable.IsTest {
- userChips = authUser.XmrBalance.ToPokerChip()
- }
+ userChips := authUser.GetUserChips(pokerTable.IsTest)
if userChips < playerBuyIn {
tx.Rollback()
- data.Error = "not enough chips to buy-in"
+ data.ErrorTable = "not enough chips to buy-in"
+ return c.Render(http.StatusOK, "poker", data)
+ }
+ tableAccount, err := tx.GetPokerTableAccount(authUser.ID, pokerTable.ID)
+ if err != nil {
+ tx.Rollback()
+ data.ErrorTable = "failed to get table account"
+ return c.Render(http.StatusOK, "poker", data)
+ }
+ if tableAccount.Amount+playerBuyIn > pokerTable.MaxBuyIn {
+ tx.Rollback()
+ data.ErrorTable = "Buy-in exceed table max buy-in"
return c.Render(http.StatusOK, "poker", data)
}
- tableAccount, _ := tx.GetPokerTableAccount(authUser.ID, pokerTable.ID)
tableAccount.Amount += playerBuyIn
- if pokerTable.IsTest {
- authUser.ChipsTest -= playerBuyIn
- } else {
- authUser.XmrBalance -= playerBuyIn.ToPiconero()
+ authUser.IncrUserChips(pokerTable.IsTest, playerBuyIn, true)
+ authUser.DoSave(tx)
+ tableAccount.DoSave(tx)
+ tx.Commit()
+ return c.Redirect(http.StatusFound, "/poker/"+pokerTableSlug)
+
+ } else if formName == "cash_out" {
+ pokerTableSlug := c.Request().PostFormValue("table_slug")
+ tx := db.Begin()
+ g := poker.PokerInstance.GetGame(poker.RoomID(pokerTableSlug))
+ if g != nil {
+ g.Players.Lock()
+ defer g.Players.Unlock()
+ if g.IsSeated2(authUser.Username) {
+ tx.Rollback()
+ data.ErrorTable = "Cannot cash out while seated"
+ return c.Render(http.StatusOK, "poker", data)
+ }
+ }
+ pokerTable, err := tx.GetPokerTableBySlug(pokerTableSlug)
+ if err != nil {
+ tx.Rollback()
+ data.ErrorTable = "table mot found"
+ return c.Render(http.StatusOK, "poker", data)
+ }
+ account, err := tx.GetPokerTableAccount(authUser.ID, pokerTable.ID)
+ if err != nil {
+ tx.Rollback()
+ data.ErrorTable = "failed to get table account"
+ return c.Render(http.StatusOK, "poker", data)
}
+ authUser.IncrUserChips(pokerTable.IsTest, account.Amount, false)
+ account.Amount = 0
+ account.DoSave(tx)
authUser.DoSave(tx)
tx.Commit()
+ return c.Redirect(http.StatusFound, "/poker")
} else if formName == "reset_chips" {
authUser.ChipsTest = 1000
diff --git a/pkg/web/handlers/poker/poker.go b/pkg/web/handlers/poker/poker.go
@@ -352,6 +352,10 @@ func (g *PokerGame) IsSeated(player database.Username) bool {
return g.isSeated(player)
}
+func (g *PokerGame) IsSeated2(player database.Username) bool {
+ return g.isSeated(player)
+}
+
func (g *PokerGame) isSeated(player database.Username) bool {
return g.getPlayer(player) != nil
}
@@ -415,27 +419,9 @@ func (g *PokerGame) UnSitPlayer(username database.Username) error {
}
func (g *PokerGame) UnSitPlayer1(seatedPlayer *SeatedPlayer) error {
- db := g.DB
ongoing := g.Ongoing
- pokerTableID := g.PokerTableID
roomTopic := g.RoomID.Topic()
seatedPlayerUsername := seatedPlayer.Username
-
- db.WithE(func(tx *database.DkfDB) error {
- user, err := tx.GetUserByUsername(seatedPlayerUsername)
- if err != nil {
- return err
- }
- account, err := tx.GetPokerTableAccount(user.ID, pokerTableID)
- if err != nil {
- return err
- }
- incrUserChips(&user, g.PokerTableIsTest, account.Amount, false)
- account.Amount = 0
- account.DoSave(tx)
- user.DoSave(tx)
- return nil
- })
if ongoing != nil {
if player := ongoing.GetPlayer(seatedPlayerUsername); player != nil {
select {
@@ -1453,13 +1439,7 @@ func Refund(db *database.DkfDB) {
accounts, _ := db.GetPositivePokerTableAccounts()
db.With(func(tx *database.DkfDB) {
for _, account := range accounts {
- if user, err := tx.GetUserByID(account.UserID); err == nil {
- incrUserChips(&user, account.PokerTable.IsTest, account.Amount+account.AmountBet, false)
- account.Amount = 0
- account.AmountBet = 0
- account.DoSave(tx)
- user.DoSave(tx)
- }
+ _ = tx.PokerTableAccountRefundPartialBet(account.UserID, account.PokerTableID, account.AmountBet)
}
})
}
@@ -1508,26 +1488,6 @@ func PokerUnSitHandler(c echo.Context) error {
return c.HTML(http.StatusOK, html)
}
-func getUserChips(user *database.User, isTest bool) database.PokerChip {
- return utils.Ternary(isTest, user.ChipsTest, user.XmrBalance.ToPokerChip())
-}
-
-func incrUserChips(user *database.User, isTest bool, v database.PokerChip, decrement bool) {
- if decrement {
- if isTest {
- user.ChipsTest -= v
- } else {
- user.XmrBalance -= v.ToPiconero()
- }
- } else {
- if isTest {
- user.ChipsTest += v
- } else {
- user.XmrBalance += v.ToPiconero()
- }
- }
-}
-
func PokerSitHandler(c echo.Context) error {
db := c.Get("database").(*database.DkfDB)
html := hutils.HtmlCssReset + `<form method="post"><button>Sit</button></form>`
@@ -1547,8 +1507,6 @@ func PokerSitHandler(c echo.Context) error {
if c.Request().Method == http.MethodPost {
pokerTable, err := db.GetPokerTableBySlug(roomID.String())
- tableMinBuyIn := pokerTable.MinBuyIn
- tableMaxBuyIn := pokerTable.MaxBuyIn
tableID := pokerTable.ID
if err != nil {
return c.HTML(http.StatusOK, html)
@@ -1558,35 +1516,14 @@ func PokerSitHandler(c echo.Context) error {
logrus.Error(err)
return c.HTML(http.StatusOK, html)
}
- playerBuyIn := database.PokerChip(utils.DoParseUint64(c.QueryParam("buy-in")))
- if playerBuyIn == 0 {
- playerBuyIn = tableMinBuyIn
- }
- if playerBuyIn < tableMinBuyIn {
- PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: fmt.Sprintf("buy-in too low; min buy in: %d", tableMinBuyIn)})
- return c.HTML(http.StatusOK, html)
- }
- if playerBuyIn > tableMaxBuyIn {
- PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: fmt.Sprintf("buy-in too high; max buy in: %d", tableMaxBuyIn)})
+ if tableAccount.Amount < pokerTable.MinBet {
+ PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: fmt.Sprintf("not enough chips to sit. have: %d, need: %d", tableAccount.Amount, pokerTable.MinBet)})
return c.HTML(http.StatusOK, html)
}
- userChips := getUserChips(authUser, pokerTable.IsTest)
- totalChips := userChips + tableAccount.Amount
- if totalChips < playerBuyIn {
- PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: fmt.Sprintf("Not enough chips for the desired buy-in; want: %d; have: %d", playerBuyIn, totalChips)})
- return c.HTML(http.StatusOK, html)
- }
- needed := playerBuyIn - tableAccount.Amount
- incrUserChips(authUser, pokerTable.IsTest, needed, true)
- tableAccount.Amount += needed
if err := g.SitPlayer(authUser, pos, tableAccount.Amount); err != nil {
PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: err.Error()})
return c.HTML(http.StatusOK, html)
}
- db.With(func(tx *database.DkfDB) {
- authUser.DoSave(tx)
- tableAccount.DoSave(tx)
- })
PokerPubSub.Pub(roomTopic, PokerSeatTakenEvent{})
g.newLogEvent(fmt.Sprintf("%s sit", authUser.Username.String()))
}
diff --git a/pkg/web/public/views/pages/poker.gohtml b/pkg/web/public/views/pages/poker.gohtml
@@ -74,6 +74,9 @@
<hr />
</div>
<h3>Tables</h3>
+ {{ if .Data.ErrorTable }}
+ <div class="alert alert-danger">{{ .Data.ErrorTable }}</div>
+ {{ end }}
<table class="table table-novpadding table-sm table-hover table-striped">
<tr>
<th>Table</th>
@@ -86,7 +89,8 @@
{{ range .Data.Tables }}
<tr>
<td class="align-middle">
- {{ .Name }}
+ {{ .Name }}<br />
+ {{ if gt .TableBalance 0 }}(<span style="color: #eaac45;">{{ .TableBalance }} <small>chips</small></span>){{ end }}
</td>
<td class="text-center align-middle">{{ .NbSeated }}/6</td>
<td class="align-middle">{{ .MinBuyIn }} - {{ .MaxBuyIn }}</td>
@@ -94,7 +98,7 @@
<td class="text-center align-middle">{{ if .IsTest }}FREE{{ else }}XMR{{ end }}</td>
<td class="text-right">
<form method="post" class="d-inline-block">
- <input type="hidden" name="csrf" value="{{ .CSRF }}" />
+ <input type="hidden" name="csrf" value="{{ $.CSRF }}" />
<input type="hidden" name="form_name" value="join_table" />
<input type="hidden" name="table_slug" value="{{ .Slug }}" />
<div class="input-group">
@@ -104,6 +108,14 @@
</div>
</div>
</form>
+ {{ if gt .TableBalance 0 }}
+ <form method="post" class="d-inline-block">
+ <input type="hidden" name="csrf" value="{{ $.CSRF }}" />
+ <input type="hidden" name="form_name" value="cash_out" />
+ <input type="hidden" name="table_slug" value="{{ .Slug }}" />
+ <button class="btn btn-primary btn-sm">Cash out</button>
+ </form>
+ {{ end }}
<a href="/poker/{{ .Slug }}" class="btn btn-primary btn-sm">Spectate</a>
</td>
</tr>