| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- package gold2chipwheel
- import (
- "encoding/json"
- "math/rand"
- "os"
- "strconv"
- "sync"
- "time"
- "bet24.com/log"
- "bet24.com/servers/common"
- inventory "bet24.com/servers/micros/item_inventory/proto"
- item "bet24.com/servers/micros/item_inventory/proto"
- cash "bet24.com/servers/micros/money/proto"
- platformconfig "bet24.com/servers/micros/platformconfig/proto"
- )
- const refresh_config_sec = 600
- const config_key = "gold2chipwheel_config"
- type Prize struct {
- Id int
- Chance int `json:",omitempty"`
- Items []item.ItemPack
- ReWheel int `json:",omitempty"`
- MaxChip int `json:",omitempty"`
- }
- type BetPrize struct {
- Accumulate int
- Bet int // 投注额
- Prizes []Prize
- pool []*Prize
- }
- func (bp *BetPrize) makePool() {
- bp.pool = []*Prize{}
- for j := 0; j < len(bp.Prizes); j++ {
- for i := 0; i < bp.Prizes[j].Chance; i++ {
- bp.pool = append(bp.pool, &bp.Prizes[j])
- }
- bp.Prizes[j].Chance = 0
- }
- }
- func (bp *BetPrize) getRandomPrize(acc int) int {
- count := len(bp.pool)
- if count == 0 {
- return 0
- }
- var ret *Prize
- loopCount := 0
- for {
- ret = bp.pool[rand.Intn(count)]
- if acc == 0 {
- break
- }
- if ret.MaxChip == 0 {
- break
- }
- if ret.MaxChip >= acc {
- break
- }
- loopCount++
- if loopCount > 20 {
- log.Release("BetPrize.getRandomPrize loopCount > 20 acc[%d] maxChip[%d]", acc, ret.MaxChip)
- break
- }
- }
- return ret.Id
- }
- type gold2chipwheelmgr struct {
- betPrizes []*BetPrize
- lock *sync.RWMutex
- freeWheels map[int]int
- prizes map[int]*Prize
- historyMgr *historymanager
- accumulate *dayaccumulation
- }
- func newPrizeWheelManager() *gold2chipwheelmgr {
- w := new(gold2chipwheelmgr)
- w.lock = &sync.RWMutex{}
- w.freeWheels = make(map[int]int)
- w.prizes = make(map[int]*Prize)
- w.historyMgr = newHistoryManager()
- w.accumulate = newDayAccumulation()
- w.loadPrizes()
- log.Debug("gold2chipwheelmgr manager running")
- return w
- }
- func (w *gold2chipwheelmgr) loadPrizes() {
- defer func() {
- time.AfterFunc(refresh_config_sec*time.Second, w.loadPrizes)
- }()
- configString := platformconfig.GetConfig(config_key)
- if configString == "" {
- data, err := os.ReadFile("fishconf/gold2chipwheel.json")
- if err != nil {
- log.Release("gold2chipwheelmgr.loadData read gold2chipwheel failed")
- return
- }
- configString = string(data)
- platformconfig.SetConfig(config_key, configString)
- } else {
- log.Debug("gold2chipwheelmgr loading config from redis")
- }
- w.lock.Lock()
- defer w.lock.Unlock()
- err := json.Unmarshal([]byte(configString), &w.betPrizes)
- if err != nil {
- log.Release("gold2chipwheelmgr.loadData Unmarshal gold2chipwheel failed err:%v", err)
- return
- }
- id := 1
- //for _, v := range w.betPrizes {
- for j := 0; j < len(w.betPrizes); j++ {
- v := w.betPrizes[j]
- v.makePool()
- for i := 0; i < len(v.Prizes); i++ {
- v.Prizes[i].Id = id
- w.prizes[id] = &v.Prizes[i]
- id++
- }
- }
- }
- func (w *gold2chipwheelmgr) isFreeWheel(userId int) int {
- w.lock.RLock()
- bet, ok := w.freeWheels[userId]
- w.lock.RUnlock()
- if !ok || bet == 0 {
- return 0
- }
- w.lock.Lock()
- delete(w.freeWheels, userId)
- w.lock.Unlock()
- return bet
- }
- func (w *gold2chipwheelmgr) getPrizeById(id int) *Prize {
- w.lock.RLock()
- defer w.lock.RUnlock()
- ret, ok := w.prizes[id]
- if !ok {
- return nil
- }
- return ret
- }
- func (w *gold2chipwheelmgr) addFreeWheel(userId int, bet int) {
- w.lock.Lock()
- w.freeWheels[userId] = bet
- w.lock.Unlock()
- }
- func (w *gold2chipwheelmgr) getPrizes() string {
- w.lock.RLock()
- defer w.lock.RUnlock()
- d, _ := json.Marshal(w.betPrizes)
- return string(d)
- }
- func (w *gold2chipwheelmgr) getBetPrize(bet int) *BetPrize {
- w.lock.RLock()
- defer w.lock.RUnlock()
- for _, v := range w.betPrizes {
- if v.Bet == bet {
- return v
- }
- }
- return nil
- }
- // 摇奖,返回中奖结果
- func (w *gold2chipwheelmgr) wheel(userId, bet int, ipAddress string) int {
- freeBet := w.isFreeWheel(userId)
- if freeBet > 0 {
- log.Debug("gold2chipwheelmgr.wheel userId[%d] freeWheel [%d]", userId, freeBet)
- bet = freeBet
- } else {
- if !cash.ReduceMoney(userId, bet, common.LOGTYPE_GOLD_WHEEL, "gold2chipwheel", "wheel", ipAddress) {
- log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] not enough gold", userId, bet)
- return 0
- }
- }
- bp := w.getBetPrize(bet)
- if bp == nil {
- log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] not found", userId, bet)
- if freeBet == 0 {
- cash.GiveMoney(userId, bet, common.LOGTYPE_GOLD_WHEEL, "gold2chipwheel", "return", ipAddress)
- }
- return 0
- }
- p := w.getPrizeById(bp.getRandomPrize(w.accumulate.getAccumulate(userId)))
- if p == nil {
- log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] prize not found", userId, bet)
- return 0
- }
- // 给奖励
- if len(p.Items) > 0 {
- time.AfterFunc(time.Second*9, func() {
- inventory.AddItems(userId, p.Items, "gold2chipwheel", common.LOGTYPE_GOLD_WHEEL)
- w.historyMgr.addHistory(userId, bet, p.Items)
- })
- for _, v := range p.Items {
- if v.ItemId == item.Item_Chip {
- w.accumulate.addAccumulate(userId, v.Count)
- }
- }
- }
- if p.ReWheel > 0 {
- w.addFreeWheel(userId, bet)
- }
- return p.Id
- }
- func (w *gold2chipwheelmgr) dump(param1, param2 string) {
- log.Release("-------------------------------")
- log.Release("gold2chipwheelmgr.dump %s %s", param1, param2)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param1 == "test" {
- count, err := strconv.Atoi(param2)
- if err != nil {
- count = 10000
- }
- w.test(count)
- return
- }
- if param1 == "" {
- w.lock.RLock()
- for _, v := range w.betPrizes {
- log.Release(" Bet:%d", v.Bet)
- for _, v1 := range v.Prizes {
- log.Release(" %d:Chance[%d],%v", v1.Id, v1.Chance, v1)
- }
- }
- w.lock.RUnlock()
- return
- }
- userId, err := strconv.Atoi(param1)
- if err == nil {
- log.Release(" User[%d]:Accumulate[%d]", userId, w.accumulate.getAccumulate(userId))
- }
- }
- func (w *gold2chipwheelmgr) getRecord(userId int) string {
- return w.historyMgr.getHistory(userId)
- }
- func (w *gold2chipwheelmgr) flush() {
- w.historyMgr.flush()
- w.accumulate.flush()
- }
- func (w *gold2chipwheelmgr) test(count int) {
- win := 0
- bet := 0
- for _, v := range w.betPrizes {
- b, w := w.testOne(count, v)
- bet += b
- win += w
- }
- log.Release("gold2chipwheelmgr test total bet[%d] win[%d]", bet, win)
- }
- func (w *gold2chipwheelmgr) testOne(count int, bet *BetPrize) (int, int) {
- totalBet := bet.Bet * count
- totalWin := 0
- for i := 0; i < count; i++ {
- p := w.getPrizeById(bet.getRandomPrize(0))
- if p == nil {
- i--
- continue
- }
- for _, v := range p.Items {
- totalWin += v.Count
- }
- }
- log.Release(" testOne[%d] bet[%d] win[%d]", bet.Bet, totalBet, totalWin)
- return totalBet, totalWin
- }
|