commit f866aa18855118a1c6faf2f7c093ba4c24d3bccf
parent c5cb3cceb41e371228b30bc37dacf625ed80013f
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Wed, 27 Dec 2023 01:29:06 -0500
rake back
Diffstat:
14 files changed, 272 insertions(+), 27 deletions(-)
diff --git a/cmd/dkf/migrations/157.sql b/cmd/dkf/migrations/157.sql
@@ -0,0 +1,8 @@
+-- +migrate Up
+ALTER TABLE users ADD COLUMN poker_referred_by INTEGER NULL;
+ALTER TABLE users ADD COLUMN poker_referral_token VARCHAR(50) NULL;
+ALTER TABLE users ADD COLUMN poker_rake_back INTEGER NOT NULL DEFAULT 0;
+
+CREATE UNIQUE INDEX users_poker_referral_token_uniq ON users (poker_referral_token);
+
+-- +migrate Down
diff --git a/go.mod b/go.mod
@@ -9,6 +9,7 @@ require (
github.com/alecthomas/chroma v0.9.2
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
+ github.com/chehsunliu/poker v0.1.0
github.com/dustin/go-humanize v1.0.0
github.com/fogleman/gg v1.3.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
@@ -30,6 +31,7 @@ require (
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/stretchr/testify v1.7.0
github.com/t-tiger/gorm-bulk-insert v1.3.0
+ github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569
github.com/ulule/limiter v2.2.2+incompatible
github.com/urfave/cli/v2 v2.3.0
github.com/valyala/quicktemplate v1.7.0
@@ -45,7 +47,6 @@ require (
github.com/alecthomas/repr v0.0.0-20200325044227-4184120f674c // indirect
github.com/andybalholm/cascadia v1.1.0 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
- github.com/chehsunliu/poker v0.1.0 // indirect
github.com/cloudflare/circl v1.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
diff --git a/go.sum b/go.sum
@@ -239,6 +239,7 @@ github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/loganjspears/joker v0.0.0-20180219043703-3f2f69a75914 h1:yAIlIiOkdoJvqd5xtWzM9tNDpLZrFfJdpnNSKha78G8=
github.com/loganjspears/joker v0.0.0-20180219043703-3f2f69a75914/go.mod h1:76SAnflG7ZFhgtnaVCpP6A5Z1S/VMFzRBN7KGm5j4oc=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
@@ -292,6 +293,7 @@ github.com/nicksnyder/go-i18n/v2 v2.0.0-20190611170653-0c6ce6ac1e8c h1:MtOLrfLzA
github.com/nicksnyder/go-i18n/v2 v2.0.0-20190611170653-0c6ce6ac1e8c/go.mod h1:JXS4+OKhbcwDoVTEj0sLFWL1vOwec2g/YBAxZ9owJqY=
github.com/notnil/chess v1.8.0 h1:wU50vrPpH3kiT0WRC/6EN9kJpb7EBxFLCRf05TwXys8=
github.com/notnil/chess v1.8.0/go.mod h1:cRuJUIBFq9Xki05TWHJxHYkC+fFpq45IWwk94DdlCrA=
+github.com/notnil/joker v0.0.0-20180219043703-3f2f69a75914 h1:xXPuFr3PVM4p6Vw3j0CP29oWYRVKO3cPZjR6D7BxggQ=
github.com/notnil/joker v0.0.0-20180219043703-3f2f69a75914/go.mod h1:L0Sdr2nYdktjerdXpIn9wOCn+GebPs/nCL2qH6RTGa0=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
@@ -395,6 +397,8 @@ github.com/t-tiger/gorm-bulk-insert v1.3.0 h1:9k7BaVEhw/3fsvh6GTOBwJ2RXk3asc5xs5
github.com/t-tiger/gorm-bulk-insert v1.3.0/go.mod h1:ruDlk8xDl+8sX4bA7PQuYly9YEb3pbp1eP2LCyeRrFY=
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
+github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI=
+github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulule/limiter v2.2.2+incompatible h1:1lk9jesmps1ziYHHb4doL7l5hFkYYYA3T8dkNyw7ffY=
@@ -518,6 +522,7 @@ golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go
@@ -130,6 +130,9 @@ type User struct {
ChessSoundsEnabled bool
PokerSoundsEnabled bool
PokerXmrSubAddress string
+ PokerReferredBy *UserID
+ PokerReferralToken *string
+ PokerRakeBack PokerChip
HighlightOwnMessages bool `gorm:"-"`
}
@@ -340,6 +343,11 @@ func (d *DkfDB) GetUserByID(userID UserID) (out User, err error) {
return
}
+func (d *DkfDB) GetUserByPokerReferralToken(token string) (out User, err error) {
+ err = d.db.First(&out, "poker_referral_token = ?", token).Error
+ return
+}
+
func (d *DkfDB) GetUserByPokerXmrSubAddress(pokerXmrSubAddress string) (out User, err error) {
err = d.db.First(&out, "poker_xmr_sub_address = ?", pokerXmrSubAddress).Error
return
@@ -730,3 +738,19 @@ func (d *DkfDB) SetPokerSubAddress(userID UserID, subAddress string) (err error)
func (u *User) GetUserChips(isTest bool) PokerChip {
return utils.Ternary(isTest, u.ChipsTest, u.XmrBalance.ToPokerChip())
}
+
+func (d *DkfDB) GetUsersRakeBack() (out PokerChip, err error) {
+ var tmp struct{ PokerRakeBack PokerChip }
+ err = d.db.Raw(`SELECT SUM(poker_rake_back) as poker_rake_back FROM users`).Scan(&tmp).Error
+ return tmp.PokerRakeBack, err
+}
+
+func (d *DkfDB) ClaimRakeBack(userID UserID) (err error) {
+ err = d.db.Exec(`UPDATE users SET xmr_balance = xmr_balance + (poker_rake_back * 10000000), poker_rake_back = 0 WHERE id = ?`, int64(userID)).Error
+ return
+}
+
+func (d *DkfDB) IncrUserRakeBack(referredBy UserID, rakeBack PokerChip) (err error) {
+ err = d.db.Exec(`UPDATE users SET poker_rake_back = poker_rake_back + ? WHERE id = ?`, uint64(rakeBack), int64(referredBy)).Error
+ return
+}
diff --git a/pkg/web/handlers/admin.go b/pkg/web/handlers/admin.go
@@ -494,9 +494,11 @@ func AdminPokerTransactionsHandler(c echo.Context) error {
data.SumOut, _ = db.GetPokerXmrTransactionsSumOut()
data.DiffInOut = data.SumIn - data.SumOut
sumXmrBalance, _ := db.GetUsersXmrBalance()
+ sumRakeBack, _ := db.GetUsersRakeBack()
sumTableAccounts, sumTableBets, _ := db.GetPokerTableAccountSums()
data.Discrepancy = (int64(data.SumIn) - int64(data.SumOut)) -
int64(sumXmrBalance) -
+ int64(sumRakeBack.ToPiconero()) -
int64(data.PokerCasino.Rake.ToPiconero()) -
int64(sumTableAccounts.ToPiconero()) -
int64(sumTableBets.ToPiconero())
diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go
@@ -956,6 +956,13 @@ type TmpTable struct {
NbSeated int
}
+type pokerRakeBackData struct {
+ ReferralToken string
+ ReferralURL string
+ RakeBackPct float64
+ SetReferralError string
+}
+
type pokerTableData struct {
PokerTableSlug string
}
@@ -965,6 +972,7 @@ type pokerData struct {
XmrBalance database.Piconero
PokerXmrSubAddress string
Img string
+ RakeBack database.PokerChip
ChipsTest database.PokerChip
Tables []TmpTable
Transactions []database.PokerXmrTransaction
@@ -980,6 +988,7 @@ type pokerData struct {
HelperpXmr string
HelperChips database.PokerChip
HelperUsd string
+ RakeBackPct float64
}
type powHelperData struct {
diff --git a/pkg/web/handlers/poker.go b/pkg/web/handlers/poker.go
@@ -18,6 +18,7 @@ import (
"github.com/labstack/echo"
wallet1 "github.com/monero-ecosystem/go-monero-rpc-client/wallet"
"github.com/sirupsen/logrus"
+ "github.com/teris-io/shortid"
"image"
"image/png"
"math/rand"
@@ -44,9 +45,11 @@ func PokerHomeHandler(c echo.Context) error {
}
const minWithdrawAmount = 1
var data pokerData
+ data.RakeBackPct = poker.RakeBackPct * 100
data.XmrPrice = fmt.Sprintf("$%.2f", config.MoneroPrice.Load())
data.Transactions, _ = db.GetUserPokerXmrTransactions(authUser.ID)
data.PokerXmrSubAddress = authUser.PokerXmrSubAddress
+ data.RakeBack = authUser.PokerRakeBack
data.ChipsTest = authUser.ChipsTest
data.XmrBalance = authUser.XmrBalance
withdrawUnique := rand.Int63()
@@ -131,6 +134,12 @@ func PokerHomeHandler(c echo.Context) error {
authUser.ChipsTest = 1000
authUser.DoSave(db)
return c.Redirect(http.StatusFound, c.Request().Referer())
+
+ } else if formName == "claim_rake_back" {
+ if err := db.ClaimRakeBack(authUser.ID); err != nil {
+ logrus.Error(err)
+ }
+ return c.Redirect(http.StatusFound, c.Request().Referer())
}
if config.PokerWithdrawEnabled.IsFalse() {
@@ -318,6 +327,66 @@ func doCashOut(db *database.DkfDB, pokerTableSlug string, userID database.UserID
return err
}
+func PokerRakeBackHandler(c echo.Context) error {
+ authUser := c.Get("authUser").(*database.User)
+ db := c.Get("database").(*database.DkfDB)
+
+ var data pokerRakeBackData
+ data.RakeBackPct = poker.RakeBackPct * 100
+ pokerReferralToken := authUser.PokerReferralToken
+ if pokerReferralToken != nil {
+ data.ReferralToken = *pokerReferralToken
+ data.ReferralURL = fmt.Sprintf("%s/poker?r=%s", config.DkfOnion, *pokerReferralToken)
+ }
+
+ if c.Request().Method == http.MethodGet {
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+
+ formName := c.Request().PostFormValue("form_name")
+ if formName == "generate_referral_url" {
+ if pokerReferralToken != nil {
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+ }
+ token, err := shortid.Generate()
+ if err != nil {
+ logrus.Error(err)
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+ }
+ authUser.PokerReferralToken = &token
+ authUser.DoSave(db)
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+
+ } else if formName == "set_referrer" {
+ referralToken := c.Request().PostFormValue("referral_token")
+ if len(referralToken) != 9 {
+ data.SetReferralError = "Invalid referral token"
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+ if authUser.PokerReferredBy != nil {
+ data.SetReferralError = "You are already giving your rake back"
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+ if pokerReferralToken != nil && referralToken == *pokerReferralToken {
+ data.SetReferralError = "Yon can't give yourself the rake back"
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+ referrer, err := db.GetUserByPokerReferralToken(referralToken)
+ if err != nil {
+ data.SetReferralError = "no user found with this referral token"
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+ if referrer.ID == authUser.ID {
+ data.SetReferralError = "Yon can't give yourself the rake back"
+ return c.Render(http.StatusOK, "poker-rake-back", data)
+ }
+ authUser.PokerReferredBy = &referrer.ID
+ authUser.DoSave(db)
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+ }
+ return c.Redirect(http.StatusFound, c.Request().Referer())
+}
+
func PokerTableHandler(c echo.Context) error {
roomID := c.Param("roomID")
var data pokerTableData
@@ -602,7 +671,7 @@ func PokerSitHandler(c echo.Context) error {
return c.HTML(http.StatusOK, html)
}
if c.Request().Method == http.MethodPost {
- g.Sit(authUser.ID, authUser.Username, pos)
+ g.Sit(authUser.ID, authUser.Username, authUser.PokerReferredBy, pos)
}
return c.HTML(http.StatusOK, html)
}
diff --git a/pkg/web/handlers/poker/poker.go b/pkg/web/handlers/poker/poker.go
@@ -35,6 +35,7 @@ const DealerStackX = 250
const DealerStackY = 30
const NbCardsPerPlayer = 2
const animationTime = 1000 * time.Millisecond
+const RakeBackPct = 0.15
type Poker struct {
sync.Mutex
@@ -196,13 +197,14 @@ func (g *Game) getEligibles() (out seatedPlayers) {
}
type seatedPlayer struct {
- seatIdx int
- userID database.UserID
- username database.Username
- cash rwmtx.RWMtxUInt64[database.PokerChip]
- status rwmtx.RWMtx[string]
- hasChecked bool
- lastActionTS time.Time
+ seatIdx int
+ userID database.UserID
+ username database.Username
+ cash rwmtx.RWMtxUInt64[database.PokerChip]
+ status rwmtx.RWMtx[string]
+ hasChecked bool
+ lastActionTS time.Time
+ pokerReferredBy *database.UserID
}
func (p *seatedPlayer) getCash() (out database.PokerChip) {
@@ -226,6 +228,7 @@ type PokerPlayer struct {
unsit atomic.Bool
gameBet database.PokerChip
allInMaxGain database.PokerChip
+ rakePaid database.PokerChip
countChancesToAction int
}
@@ -566,7 +569,7 @@ func (g *Game) incrDealerIdx() (smallBlindIdx, bigBlindIdx int) {
return
}
-func (g *Game) Sit(userID database.UserID, username database.Username, pos int) {
+func (g *Game) Sit(userID database.UserID, username database.Username, pokerReferredBy *database.UserID, pos int) {
if err := g.Players.WithE(func(gPlayers *seatedPlayers) error {
pokerTable, err := g.db.GetPokerTableBySlug(g.roomID.String())
if err != nil {
@@ -589,11 +592,12 @@ func (g *Game) Sit(userID database.UserID, username database.Username, pos int)
return errors.New("seat already taken")
}
(*gPlayers)[pos] = &seatedPlayer{
- seatIdx: pos,
- userID: userID,
- username: username,
- cash: rwmtx.RWMtxUInt64[database.PokerChip]{rwmtx.New(tableAccount.Amount)},
- lastActionTS: time.Now(),
+ seatIdx: pos,
+ userID: userID,
+ username: username,
+ cash: rwmtx.RWMtxUInt64[database.PokerChip]{rwmtx.New(tableAccount.Amount)},
+ lastActionTS: time.Now(),
+ pokerReferredBy: pokerReferredBy,
}
PubSub.Pub(g.roomID.Topic(), PokerSeatTakenEvent{})
@@ -1345,9 +1349,10 @@ func dealerThread(g *Game, eligiblePlayers seatedPlayers) {
END:
winners := ongoing.computeWinners()
- mainPot := ongoing.mainPot.Get()
- playersGain, rake := processPot(winners, mainPot, bigBlindBet, collectRake, len(ongoing.players))
- winnersStr, winnerHand := applyGains(g, playersGain, mainPot, rake)
+ mainPotOrig := ongoing.mainPot.Get()
+ mainPot, rake := computeRake(g.ongoing.players, bigBlindBet, mainPotOrig, collectRake)
+ playersGain := processPot(winners, mainPot)
+ winnersStr, winnerHand := applyGains(g, playersGain, mainPotOrig, rake)
ongoing.mainPot.Set(0)
@@ -1378,6 +1383,20 @@ func (g *ongoingGame) gameStr() string {
return out
}
+func computeRake(players []*PokerPlayer, pokerTableMinBet, mainPotIn database.PokerChip, collectRake bool) (mainPotOut, rake database.PokerChip) {
+ if !collectRake {
+ return mainPotIn, 0
+ }
+ rake = calculateRake(mainPotIn, pokerTableMinBet, len(players))
+ for _, p := range players {
+ pctOfPot := float64(p.gameBet) / float64(mainPotIn)
+ pctOfRake := pctOfPot * float64(rake)
+ p.rakePaid = database.PokerChip(pctOfRake)
+ }
+ mainPotOut = mainPotIn - rake
+ return mainPotOut, rake
+}
+
func applySmallBlindBet(g *Game, bigBlindBet database.PokerChip, sbIdx int) {
applyBlindBet(g, sbIdx, bigBlindBet/2, "small blind")
}
@@ -1438,10 +1457,24 @@ func applyGains(g *Game, playersGain []PlayerGain, mainPot, rake database.PokerC
winnerHand = utils.Ternary(nbPlayersGain == 1, playersGain[0].HandStr, "Split pot")
if g.tableType == TableTypeRake {
+ rakeOrig := rake
if !g.pokerTableIsTest {
+ rakeBackMap := make(map[database.UserID]database.PokerChip)
+ for _, p := range g.ongoing.players {
+ if p.pokerReferredBy != nil {
+ rakeBack := database.PokerChip(RakeBackPct * float64(p.rakePaid))
+ rakeBackMap[*p.pokerReferredBy] += rakeBack
+ rake -= rakeBack
+ }
+ }
+ for userID, totalRakeBack := range rakeBackMap {
+ if err := tx.IncrUserRakeBack(userID, totalRakeBack); err != nil {
+ rake += totalRakeBack
+ }
+ }
_ = tx.IncrPokerCasinoRake(rake)
}
- g.newLogEvent(fmt.Sprintf("Rake %d (%.2f%%)", rake, (float64(rake)/float64(mainPot))*100))
+ g.newLogEvent(fmt.Sprintf("Rake %d (%.2f%%)", rakeOrig, (float64(rakeOrig)/float64(mainPot))*100))
}
for _, el := range playersGain {
@@ -1497,17 +1530,12 @@ func calculateRake(mainPot, pokerTableMinBet database.PokerChip, nbPlayers int)
return rake
}
-func processPot(winners []gameResult, mainPot, pokerTableMinBet database.PokerChip, collectRake bool, nbPlayers int) (res []PlayerGain, rake database.PokerChip) {
+func processPot(winners []gameResult, mainPot database.PokerChip) (res []PlayerGain) {
if len(winners) == 0 {
logrus.Error("winners has len 0")
return
}
- if collectRake {
- rake = calculateRake(mainPot, pokerTableMinBet, nbPlayers)
- mainPot -= rake
- }
-
isOnlyPlayerAlive := len(winners) == 1 && len(winners[0].players) == 1
for groupIdx, group := range winners {
if mainPot == 0 {
diff --git a/pkg/web/handlers/signup.go b/pkg/web/handlers/signup.go
@@ -87,6 +87,8 @@ func signupHandler(c echo.Context) error {
hbCookie, hbCookieErr := c.Cookie(hutils.HBCookieName)
hasHBCookie := hbCookieErr == nil && hbCookie.Value != ""
+ pokerReferralCookie, _ := hutils.GetPokerReferralCookie(c)
+
signupInfo, _ := signupCache.Get(signupToken)
data.HasSolvedCaptcha = signupInfo.hasSolvedCaptcha
@@ -157,6 +159,14 @@ func signupHandler(c echo.Context) error {
newUser.DoSave(db)
}
+ if pokerReferralCookie != nil {
+ if referredByUser, err := db.GetUserByPokerReferralToken(pokerReferralCookie.Value); err == nil {
+ newUser.PokerReferredBy = &referredByUser.ID
+ newUser.DoSave(db)
+ c.SetCookie(hutils.DeleteCookie(hutils.PokerReferralName))
+ }
+ }
+
invitationToken := c.Param("invitationToken")
if invitationToken != "" {
if invitation, err := db.GetUnusedInvitationByToken(invitationToken); err == nil {
diff --git a/pkg/web/handlers/utils/utils.go b/pkg/web/handlers/utils/utils.go
@@ -26,6 +26,7 @@ import (
const (
HBCookieName = "dkft" // dkf troll
WaitCookieName = "wait-token"
+ PokerReferralName = "poker-referral-token"
AuthCookieName = "auth-token"
AprilFoolCookieName = "april_fool"
ByteRoadCookieName = "challenge_byte_road_session"
@@ -143,6 +144,14 @@ func GetLastMsgCookie(c echo.Context, roomName string) (*http.Cookie, error) {
return c.Cookie(getLastMsgCookieName(roomName))
}
+func CreatePokerReferralCookie(c echo.Context, v string) {
+ c.SetCookie(CreateCookie(PokerReferralName, v, utils.OneDaySecs))
+}
+
+func GetPokerReferralCookie(c echo.Context) (*http.Cookie, error) {
+ return c.Cookie(PokerReferralName)
+}
+
func GetAprilFoolCookie(c echo.Context) int {
v, err := c.Cookie(AprilFoolCookieName)
if err != nil {
diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go
@@ -283,6 +283,12 @@ func IsAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
if strings.HasPrefix(c.Path(), "/api/") {
return c.String(http.StatusUnauthorized, "unauthorized")
}
+ referralToken := c.QueryParam("r")
+ if strings.HasPrefix(c.Path(), "/poker") && referralToken != "" {
+ if len(referralToken) == 9 {
+ hutils.CreatePokerReferralCookie(c, referralToken)
+ }
+ }
return c.Redirect(http.StatusFound, "/?redirect="+c.Request().URL.String())
}
diff --git a/pkg/web/public/views/pages/poker-rake-back.gohtml b/pkg/web/public/views/pages/poker-rake-back.gohtml
@@ -0,0 +1,62 @@
+{{ define "extra-head" }}
+{{ end }}
+
+{{ define "title" }}dkf - Poker rake back{{ end }}
+
+{{ define "content" }}
+ <div class="container mb-5">
+
+ <nav aria-label="breadcrumb">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><a href="/poker">Poker</a></li>
+ <li class="breadcrumb-item active">Rake back</li>
+ </ol>
+ </nav>
+
+ <h3>Rake back</h3>
+
+ <p>
+ When someone register using your referral code/url,
+ you will receive <strong>{{ .Data.RakeBackPct }}%</strong> of the rake
+ that this person generates while playing poker.
+ </p>
+
+ <hr />
+
+ {{ if .Data.ReferralURL }}
+ <div class="form-group">
+ <label>Your referral token:</label>
+ <input type="text" value="{{ .Data.ReferralToken }}" class="form-control" readonly />
+ </div>
+ <div class="form-group">
+ <label>Your referral URL:</label>
+ <input type="text" value="{{ .Data.ReferralURL }}" class="form-control" readonly />
+ </div>
+ {{ else }}
+ <form method="post">
+ <input type="hidden" name="csrf" value="{{ .CSRF }}" />
+ <input type="hidden" name="form_name" value="generate_referral_url" />
+ <button class="btn btn-primary">Generate referral URL</button>
+ </form>
+ {{ end }}
+ <hr />
+
+ <p>
+ If you wish to give your rake back to someone, enter their referral token here.
+ </p>
+
+ {{ if .Data.SetReferralError }}
+ <div class="alert alert-danger">{{ .Data.SetReferralError }}</div>
+ {{ end }}
+ <form method="post">
+ <input type="hidden" name="csrf" value="{{ .CSRF }}" />
+ <input type="hidden" name="form_name" value="set_referrer" />
+ <div class="input-group">
+ <input type="text" name="referral_token" class="form-control" placeholder="Referral token (9 characters)" maxlength="9" />
+ <div class="input-group-append">
+ <button class="btn btn-primary">Set referrer</button>
+ </div>
+ </div>
+ </form>
+ </div>
+{{ end }}
diff --git a/pkg/web/public/views/pages/poker.gohtml b/pkg/web/public/views/pages/poker.gohtml
@@ -18,10 +18,11 @@
rake is capped<br />
2 confirmations needed for deposits under 0.2 XMR (~4min)<br />
10 confirmations needed for deposits over 0.2 XMR (~20min)<br />
+ Rake back percentage is <strong>{{ .Data.RakeBackPct }}%</strong><br />
<div class="clearfix"></div>
</div>
<div class="mb-3">
- <table>
+ <table class="mb-3">
<tr>
<td>
<span style="vertical-align: middle;">Balance: <span style="color: #eaac45;">{{ .Data.XmrBalance }} <small>pXMR</small></span></span><br />
@@ -30,7 +31,16 @@
<td style="vertical-align: middle;"><span class="ml-3" style="font-size: 30px; color: #1ee91e;">{{ .Data.XmrBalance.UsdStr }}</span></td>
</tr>
</table>
- <br />
+ <div class="mb-3">
+ <a href="/poker/rake-back">Rake back</a>: <span style="color: #eaac45;">{{ .Data.RakeBack }} <small>chips</small></span>
+ {{ if gt .Data.RakeBack 0 }}
+ <form method="post" class="d-inline ml-3">
+ <input type="hidden" name="csrf" value="{{ .CSRF }}" />
+ <input type="hidden" name="form_name" value="claim_rake_back" />
+ <button class="btn btn-primary btn-sm">Claim chips</button>
+ </form>
+ {{ end }}
+ </div>
Free tables balance: <span style="color: #eaac45;">{{ .Data.ChipsTest }} <small>chips</small></span>
<form method="post" class="d-inline ml-3">
<input type="hidden" name="csrf" value="{{ .CSRF }}" />
diff --git a/pkg/web/web.go b/pkg/web/web.go
@@ -99,6 +99,8 @@ func getMainServer(db *database.DkfDB, i18nBundle *i18n.Bundle, renderer *tmp.Te
authGroup.GET("/shop", handlers.ShopHandler)
authGroup.GET("/poker", handlers.PokerHomeHandler)
authGroup.POST("/poker", handlers.PokerHomeHandler, middlewares.AuthRateLimitMiddleware(time.Second, 1))
+ authGroup.GET("/poker/rake-back", handlers.PokerRakeBackHandler)
+ authGroup.POST("/poker/rake-back", handlers.PokerRakeBackHandler)
authGroup.GET("/poker/:roomID", handlers.PokerTableHandler)
authGroup.GET("/poker/:roomID/stream", handlers.PokerStreamHandler)
authGroup.GET("/poker/:roomID/logs", handlers.PokerLogsHandler)