package ladder import ( "bet24.com/log" pb "bet24.com/servers/micros/ladderservice/proto" notification "bet24.com/servers/micros/notification/proto" "encoding/json" "strconv" "sync" "time" ) var ldm *ladderMgr func getLadderManager() *ladderMgr { if ldm == nil { ldm = new(ladderMgr) ldm.ctor() } return ldm } type ladderMgr struct { lock *sync.RWMutex userlist map[int]*ladderUser } func (lm *ladderMgr) ctor() { lm.lock = &sync.RWMutex{} lm.userlist = make(map[int]*ladderUser) lm.checkExpireUser() } func (lm *ladderMgr) checkExpireUser() { time.AfterFunc(10*time.Minute, lm.checkExpireUser) var toRemove []int lm.lock.RLock() for k, v := range lm.userlist { if v.isExpired() { toRemove = append(toRemove, k) } } lm.lock.RUnlock() if len(toRemove) == 0 { return } log.Release("ladderMgr.checkExpireUser removing %v", toRemove) lm.lock.Lock() for _, v := range toRemove { delete(lm.userlist, v) } lm.lock.Unlock() } func (lm *ladderMgr) getLadderUser(userId int) *ladderUser { lm.lock.RLock() ur, ok := lm.userlist[userId] lm.lock.RUnlock() if !ok { ur = lm.loadLadderUser(userId) lm.lock.Lock() lm.userlist[userId] = ur lm.lock.Unlock() } return ur } func (lm *ladderMgr) loadLadderUser(userId int) *ladderUser { return newLadderUser(userId) } func (lm *ladderMgr) getUserLadderInfo(userId int) *pb.UserLadderInfo { u := lm.getLadderUser(userId) u.refreshPing() return &u.UserLadderInfo } func (lm *ladderMgr) dumpUser(param string) { log.Release("-------------------------------") log.Release("ladderMgr.dumpUser %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() var userId int var err error if userId, err = strconv.Atoi(param); err != nil { log.Release("atoi error %v", err) return } lm.getLadderUser(userId).dump() } func (lm *ladderMgr) dumpCal(param string) { log.Release("-------------------------------") log.Release("ladderMgr.dumpCal %s", param) defer func() { log.Release("+++++++++++++++++++++++++++++++") log.Release("") }() var point int var err error if point, err = strconv.Atoi(param); err != nil { log.Release("atoi error %v", err) return } log.Release(" point[%d] ladder[%v]", point, getLadderInfoByPoint(point)) } func (lm *ladderMgr) addUserScore(userId int, gameId int, score int, roomName string) (int, bool) { log.Debug("ladderMgr.addUserScore userId[%d] score[%d]", userId, score) usr := lm.getLadderUser(userId) // 加入连胜 getConsecutiveMgr().addUserRecord(userId, gameId, score) // 计算分数 var point int if score == 0 { point = 0 } else if score < 0 { point = getLadderConfig().LosePoint } else { point = getLadderConfig().WinPoint } // 先获取当前连胜次数 conWinCount := getConsecutiveMgr().getUserConsecutiveWinCount(userId, gameId) additionalPercent := getRoomManager().getRoomAdditionalPercent(gameId, roomName) winStreakScore := getLadderConfig().getConsecutiveWinAdditionalPoint(conWinCount) oldLadderInfo := usr.UserLadderInfo levelChanged := usr.addPoint(point, gameId, winStreakScore, additionalPercent) usr.addRecord(point, winStreakScore, additionalPercent) ladderChange := struct { Old pb.UserLadderInfo New pb.UserLadderInfo }{Old: oldLadderInfo, New: usr.UserLadderInfo} d, _ := json.Marshal(ladderChange) notification.AddNotification(userId, notification.Notification_LadderChanged, string(d)) return point, levelChanged } func (lm *ladderMgr) refreshCurConWin(userId int) { lm.getLadderUser(userId).refreshCurConWin() } func (lm *ladderMgr) getSettlementRecord(userId int) pb.SettlementRecord { u := lm.getLadderUser(userId) return u.getSettlementRecord() } func (lm *ladderMgr) getHistoricalRecord(userId int) []pb.WinningStreak { u := lm.getLadderUser(userId) return u.getHistoricalRecord() } func getLadderInfoByPoint(point int) pb.LadderInfo { var ret pb.LadderInfo for _, ladder := range getLadderConfig().LadderConfigs { for _, level := range ladder.Levels { for _, star := range level.Stars { if point >= star.Point || ret.Ladder == 0 { ret.Ladder = ladder.Ladder ret.Level = level.Level ret.Star = star.Star } else { break } } } } return ret } func (lm *ladderMgr) getUserLock(userId int) *sync.RWMutex { u := lm.getLadderUser(userId) if u == nil { return nil } return u.userLock }