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 }