game_sync/gamesrv/slotspkg/internal/module/player/coin.go

209 lines
4.1 KiB
Go

package player
import (
"github.com/tomas-qstarrs/boost/timex"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/gamesrv/slotspkg/internal/dao/thinkingdata"
"mongo.games.com/game/gamesrv/slotspkg/internal/generic/errors"
"mongo.games.com/game/gamesrv/slotspkg/internal/generic/key"
"mongo.games.com/game/gamesrv/slotspkg/internal/module/shared"
"sync"
)
type coinCenter struct {
imageMap sync.Map
}
// CoinCenter 仅在Player协程使用
var CoinCenter = &coinCenter{}
// Range 遍历
func (c *coinCenter) Range(f func(key, value any) bool) {
c.imageMap.Range(f)
}
// Get 在线或者离线获取CoinBag
func (c *coinCenter) Get(v any) CoinCart {
return c.fetch(v)
}
// Dec 下注 必须在线
func (c *coinCenter) Dec(s *base.SlotsSession, game *shared.Game, reason key.Reason, decCoin DecCoin) {
p := Get(s)
if p.GM.LockCoin.Get() {
return
}
if decCoin.GetCoin() < 0 {
panic(errors.CoinNegative.ErrorWith(decCoin.GetCoin()))
}
cc := c.fetch(s)
coinChange := &thinkingdata.CoinChange{}
coinChange.Reason = reason
coinChange.Type = key.CoinChangeBook
coinChange.BeforeCoin = cc.GetCoin()
coinChange.DecCoin = decCoin.GetCoin()
defer func() {
cc := c.fetch(s)
coinChange.AfterCoin = cc.GetCoin()
//thinkingdata.Track(Context(s, game), coinChange)
}()
c.commit(s, c.fetch(s).dec(decCoin))
}
// Inc 结算 必须在线
func (c *coinCenter) Inc(s *base.SlotsSession, game *shared.Game, reason key.Reason, incCoin IncCoin) {
p := Get(s)
if p.GM.LockCoin.Get() {
return
}
if incCoin.GetCoin() < 0 {
panic(errors.CoinNegative.ErrorWith(incCoin.GetCoin()))
}
cc := c.fetch(s)
coinChange := &thinkingdata.CoinChange{}
coinChange.Reason = reason
coinChange.Type = key.CoinChangeBook
coinChange.BeforeCoin = cc.GetCoin()
coinChange.IncCoin = incCoin.GetCoin()
defer func() {
cc := c.fetch(s)
coinChange.AfterCoin = cc.GetCoin()
//thinkingdata.Track(Context(s, game), coinChange)
}()
c.commit(s, c.fetch(s).inc(incCoin))
}
func (c *coinCenter) Reset(s *base.SlotsSession, coinCart CoinCart) {
rp := Get(s)
rp.Book.Coin.Set(coinCart.Coin)
c.commit(s, c.fetch(s))
}
func (c *coinCenter) Sync(s *base.SlotsSession) {
c.commit(s, c.fetch(s))
}
// fetch 获取CoinBag
func (c *coinCenter) fetch(v any) CoinCart {
switch v := v.(type) {
case int64:
uid := v
vv, ok := c.imageMap.Load(uid)
if !ok {
panic(errors.CoinBagNotFound.Error())
}
return vv.(CoinCart)
case *base.SlotsSession:
s := v
rp := Get(s)
return CoinCart{
Coin: rp.Book.Coin.Get(),
}
default:
panic(errors.CoinBagTypeError.ErrorWith(v))
}
}
func (c *coinCenter) commit(s *base.SlotsSession, cb CoinCart) {
rp := Get(s)
rp.Book.Coin.Set(cb.Coin)
cb.UpdateTime = timex.Now().Unix()
c.imageMap.Store(s.UID(), cb)
}
type CoinCart struct {
UpdateTime int64 // 更新时间
Coin int64
}
func (cc CoinCart) GetCoin() int64 {
return cc.Coin
}
func (cc CoinCart) IsCoinEnough(value int64) bool {
return cc.GetCoin() >= value
}
// dec 下注
func (cc CoinCart) dec(betCoin DecCoin) CoinCart {
cc.Coin -= betCoin.Coin
return cc
}
// inc 增加
func (cc CoinCart) inc(ic IncCoin) CoinCart {
cc.Coin += ic.Coin
return cc
}
type IncCoin struct {
Coin int64
}
func (ic *IncCoin) GetCoin() int64 {
return ic.Coin
}
func (ic IncCoin) Add(i IncCoin) IncCoin {
ic.Coin += i.Coin
return ic
}
func (ic *IncCoin) Merge(i IncCoin) {
ic.Coin += i.Coin
}
type DecCoin struct {
Coin int64
}
func NewDecCoin(cc CoinCart, value int64) DecCoin {
var fetch = func(value int64, coin int64) (int64, int64) {
if value > coin {
return coin, value - coin
}
return value, 0
}
bc := DecCoin{}
if cc.GetCoin() < value {
return bc
}
//coin
coinFetch, value := fetch(value, cc.Coin)
bc.Coin = coinFetch
if value <= 0 {
return bc
}
return bc
}
func (bc DecCoin) GetCoin() int64 {
return bc.Coin
}
func (bc DecCoin) Add(b DecCoin) DecCoin {
bc.Coin += b.Coin
return bc
}
func (bc *DecCoin) Merge(b DecCoin) {
bc.Coin += b.Coin
}
func (bc DecCoin) Rate(isFree bool, rate float64) IncCoin {
win := int64(float64(bc.GetCoin())*rate + 0.5)
win -= win % 100
if win <= 0 {
return IncCoin{}
}
var ic = IncCoin{
Coin: win,
}
return ic
}