package usermanager import ( "bet24.com/log" "bet24.com/redis" "bet24.com/servers/fishhall/config" "encoding/json" "fmt" "sync" ) // redis存储用户局数信息 type game_count struct { GameId int `json:"id,omitempty"` Count int `json:"c,omitempty"` } // animal dfdc fafafa panda dragon, rezeki tribal var slot_ids = []int{50, 51, 52, 55, 56, 58, 87} type user_spin_count struct { Counts []game_count `json:"c,omitempty"` IsValid bool `json:"v,omitempty"` isDirty bool } func (usc *user_spin_count) isNeedUpdate() bool { if !usc.isDirty { //log.Debug("isNeedUpdate !isNeedUpdate") return false } //log.Debug("user_spin_count.isNeedUpdate %d", len(usc.Counts)) return len(usc.Counts) != 0 } func (usc *user_spin_count) addCount(gameId int, count int) { usc.isDirty = true usc.IsValid = true for i := 0; i < len(usc.Counts); i++ { if gameId == usc.Counts[i].GameId { usc.Counts[i].Count += count return } } // 没找到,添加一条 usc.Counts = append(usc.Counts, game_count{GameId: gameId, Count: count}) } func (usc *user_spin_count) getCount(gameId int) int { for _, v := range usc.Counts { if v.GameId == gameId { return v.Count } } return 0 } type count_manager struct { users map[int]*user_spin_count lock *sync.RWMutex } func newCountManager() *count_manager { ret := new(count_manager) ret.users = make(map[int]*user_spin_count) ret.lock = &sync.RWMutex{} return ret } func (cm *count_manager) getUser(userId int) *user_spin_count { cm.lock.RLock() u, ok := cm.users[userId] cm.lock.RUnlock() if !ok { return nil } return u } func (cm *count_manager) onUserEnter(userId int) { if userId == 0 { return } u := cm.getUser(userId) if u != nil { return } // 从redis读取信息 u = new(user_spin_count) saveData, _ := redis.String_Get(getUserSlotCountRedisKey(userId)) if saveData != "" { err := json.Unmarshal([]byte(saveData), u) if err != nil { log.Release("count_manager.onUserEnter[%d] Unmarshal failed %v", userId, err) } } log.Debug("count_manager.onUserEnter %d,%s", userId, saveData) cm.lock.Lock() cm.users[userId] = u cm.lock.Unlock() cm.loadOldFormatAndDelete(userId, u) } func (cm *count_manager) onUserExit(userId int) { u := cm.getUser(userId) if u == nil { //log.Release("count_manager.onUserExit %d not exist", userId) return } // 写入 if u.isNeedUpdate() { d, _ := json.Marshal(u) redis.String_Set(getUserSlotCountRedisKey(userId), string(d)) } cm.lock.Lock() delete(cm.users, userId) cm.lock.Unlock() } func (cm *count_manager) addTotalCount(userId, gameId int) { cm.addTotalCountMulti(userId, gameId, 1) } func (cm *count_manager) addTotalCountMulti(userId, gameId int, count int) { u := cm.getUser(userId) if u == nil { cm.onUserEnter(userId) u = cm.getUser(userId) if u == nil { return } } u.addCount(gameId, count) } func (cm *count_manager) getTotalCount(userId, gameId int) int { u := cm.getUser(userId) if u == nil { cm.onUserEnter(userId) u = cm.getUser(userId) if u == nil { return 0 } } return u.getCount(gameId) } func getUserSlotCountRedisKey(userId int) string { t := "gold" if config.Server.IsChipRoom > 0 { t = "chip" } return fmt.Sprintf("userslotcount:%d:%s", userId, t) } func getOldRedisKey(userId int, gameId int) string { t := "gold" if config.Server.IsChipRoom > 0 { t = "chip" } return fmt.Sprintf("userslot:%s:totalBetCount:%d:%d", t, userId, gameId) } // 加载老的局数信息并删除 func (cm *count_manager) loadOldFormatAndDelete(userId int, user *user_spin_count) { if user.IsValid { return } log.Debug("loadOldFormatAndDelete %d", userId) for _, gameId := range slot_ids { key := getOldRedisKey(userId, gameId) count := redis.String_GetInt(key) if count == 0 { continue } cm.addTotalCountMulti(userId, gameId, count) redis.Key_Del(key) } }