/* 1.所有人的赢金总额 都记录起来 2.不扣本金 不算输金 */ package gamelogic import ( "encoding/json" "sort" "sync" "time" "bet24.com/log" "bet24.com/redis" "bet24.com/servers/games/greedy/common" "bet24.com/servers/games/greedy/config" ) const WinPoolKey = "winPool" const RankCount = 10 type Rank struct { UserId int WinAmount int } // 赢金榜 每天刷新一次 type winPool struct { Day int // 奖池日期 WinList map[int]int // 所有玩家的赢金总额 不扣本金 不算输金 lock *sync.RWMutex } func newWinPool() *winPool { ret := new(winPool) ret.lock = &sync.RWMutex{} ret.WinList = make(map[int]int) //如果是私人场则不做Redis存储 if !config.Server.IsPrivateRoom { // 从redis中获取奖池数据 key := WinPoolKey data, _ := redis.String_Get(common.GetRedisKey(key)) if data != "" { // redis中有奖池数据 wp := &winPool{ Day: 0, WinList: make(map[int]int), } err := json.Unmarshal([]byte(data), wp) if err != nil { log.Release("winPool json.Unmarshal err:%v", err) } if wp.Day != time.Now().Day() { // 奖池数据不是今天的,重新初始化 ret.Day = time.Now().Day() log.Debug("====newWinPool.Refresh Day[%d] ====", wp.Day) ret.winPoolToRedis() } else { // 奖池数据是今天的,直接赋值 ret.Day = wp.Day ret.WinList = wp.WinList } //起一个定时器,每天0点发奖并且清空奖池 ret.startTimer() return ret } } // redis中没有奖池数据 ret.Day = time.Now().Day() ret.winPoolToRedis() //起一个定时器,每天0点发奖并且清空奖池 ret.startTimer() return ret } func (wp *winPool) startTimer() { wp.refreshPool() go time.AfterFunc(1*time.Minute, wp.startTimer) } // 添加用户 func (wp *winPool) addUser(userId int) { wp.lock.RLock() _, ok := wp.WinList[userId] wp.lock.RUnlock() if !ok { wp.lock.Lock() wp.WinList[userId] = 0 wp.lock.Unlock() } } // 移除用户 func (wp *winPool) removeUser(userId int) { wp.lock.Lock() delete(wp.WinList, userId) wp.lock.Unlock() // log.Release("winPool.removeUser %d not found", userId) } // 是否上榜 func (wp *winPool) isRank(userId int) bool { _, myRank, _ := wp.getRankList(userId, -1) return myRank <= RankCount } // 每次结算时 将赢金数据保存到历史奖池中 func (wp *winPool) addWinPool(userId int, winAmount int) { wp.lock.RLock() data, ok := wp.WinList[userId] wp.lock.RUnlock() // 检查用户是否已经投注过 if ok { wp.lock.Lock() data += winAmount wp.WinList[userId] = data wp.lock.Unlock() } else { wp.lock.Lock() wp.WinList[userId] = winAmount // log.Release("addWinPool failed wp.WinList is nil userId:%v,winAmount:%d", userId, winAmount) wp.lock.Unlock() } } func (wp *winPool) winPoolToRedis() { if config.Server.IsPrivateRoom { return } key := WinPoolKey wp.lock.RLock() data, err := json.Marshal(wp) wp.lock.RUnlock() if err != nil { log.Debug("winPool json.Marshal err:%v", err) return } redis.String_Set(common.GetRedisKey(key), string(data)) } // 获取排名列表 func (wp *winPool) getRankList(userId, count int) ([]Rank, int, int) { var myRank = RankCount var rankCount = RankCount if count != 0 { rankCount = count } var myWinAmount = 0 var rankList []Rank wp.lock.RLock() for k, v := range wp.WinList { rankList = append(rankList, Rank{k, v}) } wp.lock.RUnlock() if len(rankList) == 0 { return rankList, myRank, myWinAmount } // 将投注金额从大到小排序 sort.Slice(rankList, func(i, j int) bool { return rankList[i].WinAmount > rankList[j].WinAmount }) // 查询自己的下注额度和排名 if userId > 0 { for i, win := range rankList { if win.UserId == userId { myRank = i + 1 myWinAmount = win.WinAmount break } } } if rankCount == -1 { return nil, myRank, myWinAmount } // 截取排名在前N名的数据 if len(rankList) > rankCount { rankList = rankList[:rankCount] } return rankList, myRank, myWinAmount } // 清空奖池 func (wp *winPool) refreshPool() { if wp.Day == 0 || wp.Day == time.Now().Day() { return } log.Debug("====WinPool.refreshPool Day[%d]====", wp.Day) // 清空奖池 wp.lock.Lock() wp.Day = time.Now().Day() wp.WinList = make(map[int]int) wp.lock.Unlock() //清空奖池打印日志 log.Debug("====Refresh WinPool Day[%d]====", wp.Day) wp.winPoolToRedis() }