usermgr.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. package userinfo
  2. import (
  3. "encoding/json"
  4. "os"
  5. "strconv"
  6. "sync"
  7. "time"
  8. "bet24.com/log"
  9. audioroomPb "bet24.com/servers/micros/audioroom/proto"
  10. item "bet24.com/servers/micros/item_inventory/proto"
  11. notification "bet24.com/servers/micros/notification/proto"
  12. platformconfig "bet24.com/servers/micros/platformconfig/proto"
  13. pb "bet24.com/servers/micros/userservices/proto"
  14. )
  15. const config_key = "switchlevel_config"
  16. type usermgr struct {
  17. lock *sync.RWMutex
  18. userlist map[int]*userInfo
  19. SwitchLevelLists []pb.SwitchLevel
  20. }
  21. func newUserMgr() *usermgr {
  22. obj := new(usermgr)
  23. obj.lock = &sync.RWMutex{}
  24. obj.userlist = make(map[int]*userInfo)
  25. obj.checkTimeout()
  26. obj.loadConfig()
  27. return obj
  28. }
  29. func (this *usermgr) loadConfig() {
  30. go time.AfterFunc(5*time.Minute, this.loadConfig)
  31. if data := platformconfig.GetConfig(config_key); data != "" {
  32. if err := json.Unmarshal([]byte(data), &this.SwitchLevelLists); err == nil {
  33. return
  34. }
  35. return
  36. }
  37. data, err := os.ReadFile("serviceconf/switchlevel_config.json")
  38. if err != nil {
  39. log.Release("read config failed serviceconf/switchlevel_config.json %v", err)
  40. }
  41. if err = json.Unmarshal(data, &this.SwitchLevelLists); err == nil {
  42. platformconfig.SetConfig(config_key, string(data))
  43. return
  44. }
  45. log.Release("Unmarshal config [%s] err:%v", string(data), err)
  46. }
  47. func (this *usermgr) getInfo(userId int) *pb.UserHotInfo {
  48. u := this.getUserInfo(userId)
  49. if u == nil {
  50. u = newUserHotInfo(userId)
  51. if u == nil {
  52. return nil
  53. }
  54. this.lock.Lock()
  55. this.userlist[userId] = u
  56. this.lock.Unlock()
  57. } else {
  58. u.updateTick()
  59. }
  60. return &u.UserHotInfo
  61. }
  62. func (this *usermgr) getUserInfoInBulk(userIds []int) []pb.UserHotInfo {
  63. var ret []pb.UserHotInfo
  64. for _, v := range userIds {
  65. ui := this.getInfo(v)
  66. if ui != nil {
  67. ret = append(ret, *ui)
  68. }
  69. }
  70. return ret
  71. }
  72. func (this *usermgr) getUserInfo(userId int) *userInfo {
  73. this.lock.RLock()
  74. ret, ok := this.userlist[userId]
  75. this.lock.RUnlock()
  76. if !ok {
  77. return nil
  78. }
  79. return ret
  80. }
  81. func (this *usermgr) checkTimeout() {
  82. time.AfterFunc(60*time.Second, this.checkTimeout)
  83. var toRemove []int
  84. this.lock.RLock()
  85. for _, v := range this.userlist {
  86. if v.isTimeout() {
  87. toRemove = append(toRemove, v.UserId)
  88. }
  89. }
  90. this.lock.RUnlock()
  91. if len(toRemove) == 0 {
  92. return
  93. }
  94. log.Release("userinfo.remove timeout users %v", toRemove)
  95. this.lock.Lock()
  96. for _, v := range toRemove {
  97. delete(this.userlist, v)
  98. }
  99. this.lock.Unlock()
  100. }
  101. func (this *usermgr) clear(userId int) {
  102. this.lock.Lock()
  103. defer this.lock.Unlock()
  104. delete(this.userlist, userId)
  105. }
  106. // 保存国家地区
  107. func (this *usermgr) saveCountry(userId int, countryName, currency string) int {
  108. currency = "SAR"
  109. usr := this.getInfo(userId)
  110. if usr == nil {
  111. return 11
  112. }
  113. usr.Currency = currency
  114. return saveCountry(userId, countryName, currency, 1)
  115. }
  116. // 锁定国家地区
  117. func (this *usermgr) lockCountry(userId int, currency string) int {
  118. currency = "SAR"
  119. usr := this.getInfo(userId)
  120. if usr == nil {
  121. return 11
  122. }
  123. usr.Currency = currency
  124. return saveCountry(userId, "SA", currency, 0)
  125. }
  126. func (this *usermgr) setUserDecoration(userId int, decorationType int, itemId int) bool {
  127. if itemId > 0 && !item.CheckDecortaionType(decorationType, itemId, userId) {
  128. log.Release("usermgr.setUserDecoration CheckDecortaionType failed[%d,%d]", decorationType, itemId)
  129. return false
  130. }
  131. usr := this.getInfo(userId)
  132. if usr == nil {
  133. return false
  134. }
  135. // 设置内容
  136. found := false
  137. for k, v := range usr.Decorations {
  138. if v.Type == decorationType {
  139. found = true
  140. if itemId == 0 {
  141. usr.Decorations = append(usr.Decorations[:k], usr.Decorations[k+1:]...)
  142. } else {
  143. usr.Decorations[k].ItemId = itemId
  144. }
  145. break
  146. }
  147. }
  148. if !found && itemId == 0 {
  149. log.Release("usermgr.setUserDecoration !found && itemId == 0 [%d,%d]", decorationType, itemId)
  150. return false
  151. }
  152. if !found {
  153. usr.Decorations = append(usr.Decorations, pb.UserDecoration{Type: decorationType, ItemId: itemId})
  154. }
  155. // 写入数据库
  156. saveDecorations(userId, decorationType, itemId)
  157. switch decorationType {
  158. case item.Item_Decoration_AudioRoomDataCard: // 3=语聊房资料卡
  159. fallthrough
  160. case item.Item_Decoration_AudioRoomBackground: // 4=语聊房背景
  161. audioroomPb.OnAudioRoomMsg(userId, "NotifyRoom", "")
  162. }
  163. // 发通知给客户端
  164. this.sendUserDecorationNotify(usr)
  165. return true
  166. }
  167. func (this *usermgr) sendUserDecorationNotify(usr *pb.UserHotInfo) {
  168. var decorations struct {
  169. Decorations []pb.UserDecoration
  170. }
  171. decorations.Decorations = usr.Decorations
  172. d, _ := json.Marshal(decorations)
  173. log.Debug("usermsg.sendUserDecorationNotify %d %s", usr.UserId, string(d))
  174. notification.AddNotification(usr.UserId, notification.Notification_UserInfoChanged, string(d))
  175. }
  176. func (this *usermgr) onDecorationExpired(userId int, itemId int) {
  177. usr := this.getInfo(userId)
  178. if usr == nil {
  179. return
  180. }
  181. for i := 0; i < len(usr.Decorations); {
  182. if usr.Decorations[i].ItemId == itemId {
  183. saveDecorations(userId, usr.Decorations[i].Type, 0)
  184. usr.Decorations = append(usr.Decorations[:i], usr.Decorations[i+1:]...)
  185. this.sendUserDecorationNotify(usr)
  186. return
  187. } else {
  188. i++
  189. }
  190. }
  191. }
  192. func (this *usermgr) changeSwitchStatus(userId int, switchType string, switchStatus int) {
  193. usr := this.getInfo(userId)
  194. if usr == nil {
  195. log.Release("usermgr.changeSwitchStatus The user does not exist. userId=%d", userId)
  196. return
  197. }
  198. isNew := true
  199. log.Release("userId:%d, changeSwitchStatus:%s", userId, switchType)
  200. for i := 0; i < len(usr.Switches); i++ {
  201. if usr.Switches[i].SwitchType != switchType {
  202. continue
  203. }
  204. isNew = false
  205. usr.Switches[i].SwitchStatus = switchStatus
  206. break
  207. }
  208. // 新增
  209. if isNew {
  210. usr.Switches = append(usr.Switches, pb.SwitchInfo{
  211. SwitchType: switchType,
  212. SwitchStatus: switchStatus,
  213. })
  214. }
  215. go func() {
  216. //d, _ := json.Marshal(usr.Switches)
  217. //notification.AddNotification(userId, notification.Notification_UserInfoChanged, string(d))
  218. // 存储到数据库
  219. changeSwitchStatus(userId, switchType, switchStatus)
  220. }()
  221. return
  222. }
  223. func (this *usermgr) getSwitchLevelInfo() []pb.SwitchLevel {
  224. return this.SwitchLevelLists
  225. }
  226. func (this *usermgr) addUserCharm(userId int, charm int) {
  227. if charm < 0 {
  228. log.Release("usermgr.addUserCharm charm=%d", charm)
  229. return
  230. }
  231. usr := this.getInfo(userId)
  232. if usr == nil {
  233. log.Release("usermgr.addUserCharm The user does not exist. userId=%d", userId)
  234. return
  235. }
  236. log.Debug("usermgr.addUserCharm %d %d", userId, charm)
  237. usr.Charm += charm
  238. var charmNoti struct {
  239. Charm int
  240. }
  241. charmNoti.Charm = usr.Charm
  242. d, _ := json.Marshal(charmNoti)
  243. notification.AddNotification(userId, notification.Notification_UserInfoChanged, string(d))
  244. go updateUserCharm(userId, usr.Charm)
  245. }
  246. func (this *usermgr) dumpUser(param string) {
  247. log.Release("-------------------------------")
  248. log.Release("usermgr.dumpUser %s", param)
  249. defer func() {
  250. log.Release("+++++++++++++++++++++++++++++++")
  251. log.Release("")
  252. }()
  253. var userId int
  254. var err error
  255. userId, err = strconv.Atoi(param)
  256. if err == nil {
  257. uv := this.getUserInfo(userId)
  258. if uv == nil {
  259. log.Release("user %d not exist", userId)
  260. return
  261. }
  262. uv.dump()
  263. return
  264. }
  265. this.lock.RLock()
  266. for _, v := range this.userlist {
  267. v.dump()
  268. }
  269. log.Release("%v", this.SwitchLevelLists)
  270. this.lock.RUnlock()
  271. }