freechips.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. 免费筹码逻辑
  3. 1.每天0点6点12点18点重置免费筹码,过期清零,写入Redis
  4. 2.每天免费配额为500,配额为0时,则表示没有免费筹码,不显示使用次数,前端自己判断
  5. 3.使用免费筹码下注时,只要下注额大于免费配额,则允许下注,否则提示下注失败,下注成功返回剩余额度
  6. 4.免费筹码下注时,记下注次数,不计入下注额度,写下注记录时下注额为0
  7. 5.获胜则按照实际下注额返还金币
  8. 6.用户登录时,检查是否有免费配额,有则显示具体金额,0也算有效,没有记录则重置免费配额,并写入Redis
  9. */
  10. package gamelogic
  11. import (
  12. "encoding/json"
  13. "fmt"
  14. "sync"
  15. "time"
  16. "bet24.com/log"
  17. "bet24.com/redis"
  18. "bet24.com/servers/games/masharie_table/common"
  19. "bet24.com/servers/games/masharie_table/config"
  20. "bet24.com/servers/transaction"
  21. )
  22. const FreeChipsKey = "freeChips"
  23. type freeChips struct {
  24. Chips map[int]int
  25. LastHour int //前一次刷新时间
  26. lock *sync.RWMutex
  27. changeCallback func()
  28. roomInfo *config.RoomInfo
  29. }
  30. func newFreeChips(roomInfo *config.RoomInfo, callback func()) *freeChips {
  31. ret := new(freeChips)
  32. ret.lock = &sync.RWMutex{}
  33. ret.Chips = make(map[int]int)
  34. ret.roomInfo = roomInfo
  35. //获得最接近的时间0 6 12 18
  36. ret.LastHour = getNearHour()
  37. // 从redis中获取数据
  38. key := FreeChipsKey
  39. data, _ := redis.String_Get(common.GetRedisKey(key))
  40. if data == "" {
  41. // redis中没有数据
  42. ret.freeChipsToRedis()
  43. } else {
  44. // redis中有数据
  45. err := json.Unmarshal([]byte(data), ret)
  46. if err != nil {
  47. log.Release("freeChips json.Unmarshal err:%v", err)
  48. }
  49. }
  50. // 保存回调函数
  51. ret.changeCallback = callback
  52. //起一个定时器,固定时间清除数据
  53. ret.startTimer()
  54. return ret
  55. }
  56. func (fc *freeChips) startTimer() {
  57. fc.checkFreeChips()
  58. go time.AfterFunc(1*time.Minute, fc.startTimer)
  59. }
  60. // 检查免费筹码数量
  61. func (fc *freeChips) checkFreeChipsNum(userId int) (int, int) {
  62. fc.lock.RLock()
  63. data, ok := fc.Chips[userId]
  64. fc.lock.RUnlock()
  65. if ok {
  66. return data, fc.LastHour
  67. }
  68. fc.lock.Lock()
  69. //不存在则重置
  70. freeChipsLimit := fc.roomInfo.FreeChipsLimit
  71. fc.Chips[userId] = freeChipsLimit
  72. fc.lock.Unlock()
  73. fc.freeChipsToRedis()
  74. go transaction.WriteFreeChipRecord(userId, common.GAMEID, freeChipsLimit, 1)
  75. return freeChipsLimit, fc.LastHour
  76. }
  77. // 扣除免费筹码
  78. func (fc *freeChips) useFreeChips(userId int, bet int) (bool, int) {
  79. fc.lock.RLock()
  80. data, ok := fc.Chips[userId]
  81. fc.lock.RUnlock()
  82. if ok {
  83. if data >= bet {
  84. data -= bet
  85. fc.lock.Lock()
  86. fc.Chips[userId] = data
  87. fc.lock.Unlock()
  88. fc.freeChipsToRedis()
  89. go transaction.WriteFreeChipRecord(userId, common.GAMEID, bet, -1)
  90. return true, data
  91. }
  92. return false, data
  93. }
  94. return false, 0
  95. }
  96. // 扣除免费筹码 有多少扣多少 并返回实际扣除的数量
  97. func (fc *freeChips) useFreeChipsFromInventory(userId int, bet int) (bool, int) {
  98. fc.lock.RLock()
  99. data, ok := fc.Chips[userId]
  100. fc.lock.RUnlock()
  101. if ok {
  102. if data >= bet {
  103. data -= bet
  104. fc.lock.Lock()
  105. fc.Chips[userId] = data
  106. fc.lock.Unlock()
  107. fc.freeChipsToRedis()
  108. go transaction.WriteFreeChipRecord(userId, common.GAMEID, bet, -1)
  109. return true, bet
  110. } else {
  111. fc.lock.Lock()
  112. fc.Chips[userId] = 0
  113. fc.lock.Unlock()
  114. fc.freeChipsToRedis()
  115. go transaction.WriteFreeChipRecord(userId, common.GAMEID, data, -1)
  116. return true, data
  117. }
  118. }
  119. return false, 0
  120. }
  121. // 下注失败返还筹码
  122. func (fc *freeChips) addFreeChips(userId int, bet int) {
  123. fc.lock.RLock()
  124. data, ok := fc.Chips[userId]
  125. fc.lock.RUnlock()
  126. if ok {
  127. data += bet
  128. fc.lock.Lock()
  129. fc.Chips[userId] = data
  130. fc.lock.Unlock()
  131. fc.freeChipsToRedis()
  132. go transaction.WriteFreeChipRecord(userId, common.GAMEID, bet, 1)
  133. }
  134. }
  135. // 检查免费卷是否需要刷新
  136. func (fc *freeChips) checkFreeChips() {
  137. now := time.Now()
  138. hour := now.Hour()
  139. lastHour := fc.LastHour
  140. //每天0点6点12点18点重置免费筹码,重置过,则跳过
  141. if hour == 0 || hour == 6 || hour == 12 || hour == 18 {
  142. if lastHour != hour {
  143. fc.resetFreeChips()
  144. fc.changeCallback()
  145. }
  146. return
  147. }
  148. }
  149. // 每天0点6点12点18点重置免费筹码
  150. func (fc *freeChips) resetFreeChips() {
  151. fc.lock.Lock()
  152. fc.Chips = make(map[int]int)
  153. fc.LastHour = time.Now().Hour()
  154. fc.lock.Unlock()
  155. fc.freeChipsToRedis()
  156. }
  157. func (fc *freeChips) freeChipsToRedis() {
  158. key := FreeChipsKey
  159. fc.lock.RLock()
  160. data, err := json.Marshal(fc)
  161. fc.lock.RUnlock()
  162. if err != nil {
  163. fmt.Println("freeChips json.Marshal err:", err)
  164. return
  165. }
  166. redis.String_Set(common.GetRedisKey(key), string(data))
  167. }
  168. func getNearHour() int {
  169. now := time.Now()
  170. hour := now.Hour()
  171. if hour < 6 {
  172. return 0
  173. } else if hour < 12 {
  174. return 6
  175. } else if hour < 18 {
  176. return 12
  177. } else {
  178. return 18
  179. }
  180. }