gold2chipwheelmgr.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. package gold2chipwheel
  2. import (
  3. "encoding/json"
  4. "math/rand"
  5. "os"
  6. "strconv"
  7. "sync"
  8. "time"
  9. "bet24.com/log"
  10. "bet24.com/servers/common"
  11. inventory "bet24.com/servers/micros/item_inventory/proto"
  12. item "bet24.com/servers/micros/item_inventory/proto"
  13. cash "bet24.com/servers/micros/money/proto"
  14. platformconfig "bet24.com/servers/micros/platformconfig/proto"
  15. )
  16. const refresh_config_sec = 600
  17. const config_key = "gold2chipwheel_config"
  18. type Prize struct {
  19. Id int
  20. Chance int `json:",omitempty"`
  21. Items []item.ItemPack
  22. ReWheel int `json:",omitempty"`
  23. MaxChip int `json:",omitempty"`
  24. }
  25. type BetPrize struct {
  26. Accumulate int
  27. Bet int // 投注额
  28. Prizes []Prize
  29. pool []*Prize
  30. }
  31. func (bp *BetPrize) makePool() {
  32. bp.pool = []*Prize{}
  33. for j := 0; j < len(bp.Prizes); j++ {
  34. for i := 0; i < bp.Prizes[j].Chance; i++ {
  35. bp.pool = append(bp.pool, &bp.Prizes[j])
  36. }
  37. bp.Prizes[j].Chance = 0
  38. }
  39. }
  40. func (bp *BetPrize) getRandomPrize(acc int) int {
  41. count := len(bp.pool)
  42. if count == 0 {
  43. return 0
  44. }
  45. var ret *Prize
  46. loopCount := 0
  47. for {
  48. ret = bp.pool[rand.Intn(count)]
  49. if acc == 0 {
  50. break
  51. }
  52. if ret.MaxChip == 0 {
  53. break
  54. }
  55. if ret.MaxChip >= acc {
  56. break
  57. }
  58. loopCount++
  59. if loopCount > 20 {
  60. log.Release("BetPrize.getRandomPrize loopCount > 20 acc[%d] maxChip[%d]", acc, ret.MaxChip)
  61. break
  62. }
  63. }
  64. return ret.Id
  65. }
  66. type gold2chipwheelmgr struct {
  67. betPrizes []*BetPrize
  68. lock *sync.RWMutex
  69. freeWheels map[int]int
  70. prizes map[int]*Prize
  71. historyMgr *historymanager
  72. accumulate *dayaccumulation
  73. }
  74. func newPrizeWheelManager() *gold2chipwheelmgr {
  75. w := new(gold2chipwheelmgr)
  76. w.lock = &sync.RWMutex{}
  77. w.freeWheels = make(map[int]int)
  78. w.prizes = make(map[int]*Prize)
  79. w.historyMgr = newHistoryManager()
  80. w.accumulate = newDayAccumulation()
  81. w.loadPrizes()
  82. log.Debug("gold2chipwheelmgr manager running")
  83. return w
  84. }
  85. func (w *gold2chipwheelmgr) loadPrizes() {
  86. defer func() {
  87. time.AfterFunc(refresh_config_sec*time.Second, w.loadPrizes)
  88. }()
  89. configString := platformconfig.GetConfig(config_key)
  90. if configString == "" {
  91. data, err := os.ReadFile("fishconf/gold2chipwheel.json")
  92. if err != nil {
  93. log.Release("gold2chipwheelmgr.loadData read gold2chipwheel failed")
  94. return
  95. }
  96. configString = string(data)
  97. platformconfig.SetConfig(config_key, configString)
  98. } else {
  99. log.Debug("gold2chipwheelmgr loading config from redis")
  100. }
  101. w.lock.Lock()
  102. defer w.lock.Unlock()
  103. err := json.Unmarshal([]byte(configString), &w.betPrizes)
  104. if err != nil {
  105. log.Release("gold2chipwheelmgr.loadData Unmarshal gold2chipwheel failed err:%v", err)
  106. return
  107. }
  108. id := 1
  109. //for _, v := range w.betPrizes {
  110. for j := 0; j < len(w.betPrizes); j++ {
  111. v := w.betPrizes[j]
  112. v.makePool()
  113. for i := 0; i < len(v.Prizes); i++ {
  114. v.Prizes[i].Id = id
  115. w.prizes[id] = &v.Prizes[i]
  116. id++
  117. }
  118. }
  119. }
  120. func (w *gold2chipwheelmgr) isFreeWheel(userId int) int {
  121. w.lock.RLock()
  122. bet, ok := w.freeWheels[userId]
  123. w.lock.RUnlock()
  124. if !ok || bet == 0 {
  125. return 0
  126. }
  127. w.lock.Lock()
  128. delete(w.freeWheels, userId)
  129. w.lock.Unlock()
  130. return bet
  131. }
  132. func (w *gold2chipwheelmgr) getPrizeById(id int) *Prize {
  133. w.lock.RLock()
  134. defer w.lock.RUnlock()
  135. ret, ok := w.prizes[id]
  136. if !ok {
  137. return nil
  138. }
  139. return ret
  140. }
  141. func (w *gold2chipwheelmgr) addFreeWheel(userId int, bet int) {
  142. w.lock.Lock()
  143. w.freeWheels[userId] = bet
  144. w.lock.Unlock()
  145. }
  146. func (w *gold2chipwheelmgr) getPrizes() string {
  147. w.lock.RLock()
  148. defer w.lock.RUnlock()
  149. d, _ := json.Marshal(w.betPrizes)
  150. return string(d)
  151. }
  152. func (w *gold2chipwheelmgr) getBetPrize(bet int) *BetPrize {
  153. w.lock.RLock()
  154. defer w.lock.RUnlock()
  155. for _, v := range w.betPrizes {
  156. if v.Bet == bet {
  157. return v
  158. }
  159. }
  160. return nil
  161. }
  162. // 摇奖,返回中奖结果
  163. func (w *gold2chipwheelmgr) wheel(userId, bet int, ipAddress string) int {
  164. freeBet := w.isFreeWheel(userId)
  165. if freeBet > 0 {
  166. log.Debug("gold2chipwheelmgr.wheel userId[%d] freeWheel [%d]", userId, freeBet)
  167. bet = freeBet
  168. } else {
  169. if !cash.ReduceMoney(userId, bet, common.LOGTYPE_GOLD_WHEEL, "gold2chipwheel", "wheel", ipAddress) {
  170. log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] not enough gold", userId, bet)
  171. return 0
  172. }
  173. }
  174. bp := w.getBetPrize(bet)
  175. if bp == nil {
  176. log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] not found", userId, bet)
  177. if freeBet == 0 {
  178. cash.GiveMoney(userId, bet, common.LOGTYPE_GOLD_WHEEL, "gold2chipwheel", "return", ipAddress)
  179. }
  180. return 0
  181. }
  182. p := w.getPrizeById(bp.getRandomPrize(w.accumulate.getAccumulate(userId)))
  183. if p == nil {
  184. log.Release("gold2chipwheelmgr.wheel userId[%d] bet[%d] prize not found", userId, bet)
  185. return 0
  186. }
  187. // 给奖励
  188. if len(p.Items) > 0 {
  189. time.AfterFunc(time.Second*9, func() {
  190. inventory.AddItems(userId, p.Items, "gold2chipwheel", common.LOGTYPE_GOLD_WHEEL)
  191. w.historyMgr.addHistory(userId, bet, p.Items)
  192. })
  193. for _, v := range p.Items {
  194. if v.ItemId == item.Item_Chip {
  195. w.accumulate.addAccumulate(userId, v.Count)
  196. }
  197. }
  198. }
  199. if p.ReWheel > 0 {
  200. w.addFreeWheel(userId, bet)
  201. }
  202. return p.Id
  203. }
  204. func (w *gold2chipwheelmgr) dump(param1, param2 string) {
  205. log.Release("-------------------------------")
  206. log.Release("gold2chipwheelmgr.dump %s %s", param1, param2)
  207. defer func() {
  208. log.Release("+++++++++++++++++++++++++++++++")
  209. log.Release("")
  210. }()
  211. if param1 == "test" {
  212. count, err := strconv.Atoi(param2)
  213. if err != nil {
  214. count = 10000
  215. }
  216. w.test(count)
  217. return
  218. }
  219. if param1 == "" {
  220. w.lock.RLock()
  221. for _, v := range w.betPrizes {
  222. log.Release(" Bet:%d", v.Bet)
  223. for _, v1 := range v.Prizes {
  224. log.Release(" %d:Chance[%d],%v", v1.Id, v1.Chance, v1)
  225. }
  226. }
  227. w.lock.RUnlock()
  228. return
  229. }
  230. userId, err := strconv.Atoi(param1)
  231. if err == nil {
  232. log.Release(" User[%d]:Accumulate[%d]", userId, w.accumulate.getAccumulate(userId))
  233. }
  234. }
  235. func (w *gold2chipwheelmgr) getRecord(userId int) string {
  236. return w.historyMgr.getHistory(userId)
  237. }
  238. func (w *gold2chipwheelmgr) flush() {
  239. w.historyMgr.flush()
  240. w.accumulate.flush()
  241. }
  242. func (w *gold2chipwheelmgr) test(count int) {
  243. win := 0
  244. bet := 0
  245. for _, v := range w.betPrizes {
  246. b, w := w.testOne(count, v)
  247. bet += b
  248. win += w
  249. }
  250. log.Release("gold2chipwheelmgr test total bet[%d] win[%d]", bet, win)
  251. }
  252. func (w *gold2chipwheelmgr) testOne(count int, bet *BetPrize) (int, int) {
  253. totalBet := bet.Bet * count
  254. totalWin := 0
  255. for i := 0; i < count; i++ {
  256. p := w.getPrizeById(bet.getRandomPrize(0))
  257. if p == nil {
  258. i--
  259. continue
  260. }
  261. for _, v := range p.Items {
  262. totalWin += v.Count
  263. }
  264. }
  265. log.Release(" testOne[%d] bet[%d] win[%d]", bet.Bet, totalBet, totalWin)
  266. return totalBet, totalWin
  267. }