package battlepass import ( "bet24.com/log" "bet24.com/redis" "encoding/json" "sync" ) type usermanager struct { Users map[int]*user SeasonId int lock *sync.RWMutex } func newUserManager() *usermanager { ret := new(usermanager) ret.ctor() return ret } func (um *usermanager) ctor() { log.Debug("battlepass.usermanager.ctor") um.Users = make(map[int]*user) um.lock = &sync.RWMutex{} // 从redis中读取 data, ok := redis.String_Get(um.getRedisKey()) if data != "" && ok { err := json.Unmarshal([]byte(data), &um) if err != nil { log.Release("battlepass.usermanager.initData Unmarshal failed %v[%s]", err, data) } } // 是否已失效 s := mgr.sm.getValidSeason() if s == nil || s.SeasonId != um.SeasonId { um.clear() } if s != nil { um.SeasonId = s.SeasonId } } func (um *usermanager) onUserEnter(userId int) { um.lock.RLock() u, ok := um.Users[userId] um.lock.RUnlock() if ok { u.isOnline = true return } um.lock.Lock() um.Users[userId] = newUser(userId) um.lock.Unlock() } func (um *usermanager) onUserExit(userId int) { u := um.getUser(userId) if u == nil { return } u.isOnline = false } func (um *usermanager) getUser(userId int) *user { um.lock.RLock() u, ok := um.Users[userId] um.lock.RUnlock() if !ok { return nil } return u } func (um *usermanager) getUserGrowthTerms(userId int) []*UserGrowthTerm { u := um.getUser(userId) if u == nil { log.Debug("usermanager.getUserGrowthTerms userId[%d] not exist", userId) return []*UserGrowthTerm{} } return u.Terms } func (um *usermanager) buyGrowthPack(userId int, productId string) (int, string) { pack := mgr.getGrowthPackByProduct(productId) if pack == nil { log.Debug("battlepass_usermanager.buyGrowthPack userId[%d] productId[%s] invalid", userId, productId) return 0, "invalid package ID" } u := um.getUser(userId) if u == nil { um.onUserEnter(userId) u = um.getUser(userId) } userTerms := u.Terms for _, v := range userTerms { if v.GrowthPackId == pack.Id { log.Debug("battlepass_usermanager.buyGrowthPack userId[%d] packId[%d] perchased", userId, pack.Id) return 0, "already bought" } } for _, v := range pack.Terms { u.addTerm(&UserGrowthTerm{ UserId: userId, GrowthPackId: pack.Id, TermIndex: v.TermIndex, Status: GrowthTermStatus_none, NeedExp: v.NeedExp, }) } return 1, "success" } func (um *usermanager) userAwardTerm(userId int, growthPackId, index int) (bool, string) { u := um.getUser(userId) if u == nil { return false, "user not exist" } return u.rewardTerm(growthPackId, index) } func (um *usermanager) clear() { um.SeasonId = 0 var toRemove []int um.lock.RLock() for k, v := range um.Users { if !v.isOnline { toRemove = append(toRemove, k) continue } v.initData() } um.lock.RUnlock() um.lock.Lock() for _, v := range toRemove { delete(um.Users, v) } um.lock.Unlock() um.flush() } func (um *usermanager) flush() { um.lock.RLock() d, _ := json.Marshal(um) um.lock.RUnlock() redis.String_Set(um.getRedisKey(), string(d)) } func (um *usermanager) getRedisKey() string { return "battlepass:usermanager" } func (um *usermanager) addExp(userId int, exp int) { if um.SeasonId == 0 { return } u := um.getUser(userId) if u == nil { um.onUserEnter(userId) u = um.getUser(userId) } u.addExp(exp) }