usertotalcount_manager.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package usermanager
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/redis"
  5. "bet24.com/servers/fishhall/config"
  6. "encoding/json"
  7. "fmt"
  8. "sync"
  9. )
  10. // redis存储用户局数信息
  11. type game_count struct {
  12. GameId int `json:"id,omitempty"`
  13. Count int `json:"c,omitempty"`
  14. }
  15. // animal dfdc fafafa panda dragon, rezeki tribal
  16. var slot_ids = []int{50, 51, 52, 55, 56, 58, 87}
  17. type user_spin_count struct {
  18. Counts []game_count `json:"c,omitempty"`
  19. IsValid bool `json:"v,omitempty"`
  20. isDirty bool
  21. }
  22. func (usc *user_spin_count) isNeedUpdate() bool {
  23. if !usc.isDirty {
  24. //log.Debug("isNeedUpdate !isNeedUpdate")
  25. return false
  26. }
  27. //log.Debug("user_spin_count.isNeedUpdate %d", len(usc.Counts))
  28. return len(usc.Counts) != 0
  29. }
  30. func (usc *user_spin_count) addCount(gameId int, count int) {
  31. usc.isDirty = true
  32. usc.IsValid = true
  33. for i := 0; i < len(usc.Counts); i++ {
  34. if gameId == usc.Counts[i].GameId {
  35. usc.Counts[i].Count += count
  36. return
  37. }
  38. }
  39. // 没找到,添加一条
  40. usc.Counts = append(usc.Counts, game_count{GameId: gameId, Count: count})
  41. }
  42. func (usc *user_spin_count) getCount(gameId int) int {
  43. for _, v := range usc.Counts {
  44. if v.GameId == gameId {
  45. return v.Count
  46. }
  47. }
  48. return 0
  49. }
  50. type count_manager struct {
  51. users map[int]*user_spin_count
  52. lock *sync.RWMutex
  53. }
  54. func newCountManager() *count_manager {
  55. ret := new(count_manager)
  56. ret.users = make(map[int]*user_spin_count)
  57. ret.lock = &sync.RWMutex{}
  58. return ret
  59. }
  60. func (cm *count_manager) getUser(userId int) *user_spin_count {
  61. cm.lock.RLock()
  62. u, ok := cm.users[userId]
  63. cm.lock.RUnlock()
  64. if !ok {
  65. return nil
  66. }
  67. return u
  68. }
  69. func (cm *count_manager) onUserEnter(userId int) {
  70. if userId == 0 {
  71. return
  72. }
  73. u := cm.getUser(userId)
  74. if u != nil {
  75. return
  76. }
  77. // 从redis读取信息
  78. u = new(user_spin_count)
  79. saveData, _ := redis.String_Get(getUserSlotCountRedisKey(userId))
  80. if saveData != "" {
  81. err := json.Unmarshal([]byte(saveData), u)
  82. if err != nil {
  83. log.Release("count_manager.onUserEnter[%d] Unmarshal failed %v", userId, err)
  84. }
  85. }
  86. log.Debug("count_manager.onUserEnter %d,%s", userId, saveData)
  87. cm.lock.Lock()
  88. cm.users[userId] = u
  89. cm.lock.Unlock()
  90. cm.loadOldFormatAndDelete(userId, u)
  91. }
  92. func (cm *count_manager) onUserExit(userId int) {
  93. u := cm.getUser(userId)
  94. if u == nil {
  95. //log.Release("count_manager.onUserExit %d not exist", userId)
  96. return
  97. }
  98. // 写入
  99. if u.isNeedUpdate() {
  100. d, _ := json.Marshal(u)
  101. redis.String_Set(getUserSlotCountRedisKey(userId), string(d))
  102. }
  103. cm.lock.Lock()
  104. delete(cm.users, userId)
  105. cm.lock.Unlock()
  106. }
  107. func (cm *count_manager) addTotalCount(userId, gameId int) {
  108. cm.addTotalCountMulti(userId, gameId, 1)
  109. }
  110. func (cm *count_manager) addTotalCountMulti(userId, gameId int, count int) {
  111. u := cm.getUser(userId)
  112. if u == nil {
  113. cm.onUserEnter(userId)
  114. u = cm.getUser(userId)
  115. if u == nil {
  116. return
  117. }
  118. }
  119. u.addCount(gameId, count)
  120. }
  121. func (cm *count_manager) getTotalCount(userId, gameId int) int {
  122. u := cm.getUser(userId)
  123. if u == nil {
  124. cm.onUserEnter(userId)
  125. u = cm.getUser(userId)
  126. if u == nil {
  127. return 0
  128. }
  129. }
  130. return u.getCount(gameId)
  131. }
  132. func getUserSlotCountRedisKey(userId int) string {
  133. t := "gold"
  134. if config.Server.IsChipRoom > 0 {
  135. t = "chip"
  136. }
  137. return fmt.Sprintf("userslotcount:%d:%s", userId, t)
  138. }
  139. func getOldRedisKey(userId int, gameId int) string {
  140. t := "gold"
  141. if config.Server.IsChipRoom > 0 {
  142. t = "chip"
  143. }
  144. return fmt.Sprintf("userslot:%s:totalBetCount:%d:%d", t, userId, gameId)
  145. }
  146. // 加载老的局数信息并删除
  147. func (cm *count_manager) loadOldFormatAndDelete(userId int, user *user_spin_count) {
  148. if user.IsValid {
  149. return
  150. }
  151. log.Debug("loadOldFormatAndDelete %d", userId)
  152. for _, gameId := range slot_ids {
  153. key := getOldRedisKey(userId, gameId)
  154. count := redis.String_GetInt(key)
  155. if count == 0 {
  156. continue
  157. }
  158. cm.addTotalCountMulti(userId, gameId, count)
  159. redis.Key_Del(key)
  160. }
  161. }