| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- package model
- import (
- "math/rand"
- "rocommon/service"
- "rocommon/util"
- "roserver/baseserver/model"
- "roserver/serverproto"
- "strconv"
- )
- const (
- TopTowerForceWinRankListMaxNum = 20
- )
- type TopTowerManager struct {
- lastRefreshRankStamp uint64 //上次刷新跨服战力排行榜
- bInit bool
- updateTimer util.ServerTimer //主循环定时器
- }
- func newTopTowerManager() *TopTowerManager {
- mag := &TopTowerManager{}
- mag.updateTimer = util.NewDurationTimer(util.GetCurrentTime(), 5000)
- return mag
- }
- func (this *TopTowerManager) Update(ms uint64) {
- if !this.bInit {
- if this.initDataFromDB() {
- this.bInit = true
- }
- this.lastRefreshRankStamp = util.GetTimeMilliseconds()
- return
- }
- if !this.updateTimer.IsStart() || !this.updateTimer.IsExpired(ms) {
- return
- }
- if model.IsDailyResetHour5(this.lastRefreshRankStamp) {
- this.lastRefreshRankStamp = ms
- //刷新战力排行榜,保留昨天和当前
- RefreshMaxFightPowerRank()
- }
- }
- func (this *TopTowerManager) initDataFromDB() bool {
- timeStamp, bOk := GetCommonInfoTopTower()
- if !bOk {
- return false
- }
- this.lastRefreshRankStamp = timeStamp
- return true
- }
- func (this *TopTowerManager) GetUidByRankIdx(uid uint64, ssAckMsg *serverproto.SSCrossTopTowerMatchFightAck) serverproto.ErrorCode {
- if uid <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- keyStr := strconv.FormatUint(uid, 10)
- //获取自身排名(不在榜上直接使用机器人)
- selfRank, err := service.GetRedis().ZRevRank(CrossMaxFightPowerRankOldPrefix, keyStr).Result()
- if err != nil {
- //service.NIL
- util.InfoF("uid=%v TopTowerManagerGetUidByRankIdx selfRankErr=%v", uid, err)
- return serverproto.ErrorCode_ERROR_OK
- }
- //获取自身所在区间段
- var matchList []*model.MatchSection
- for idx := 0; idx < len(model.ConvertTopTowerDataList); idx++ {
- tmpInfo := model.ConvertTopTowerDataList[idx]
- tmpSelfRank := selfRank + 1
- if tmpInfo.SelfRankSection.InSection(int32(tmpSelfRank)) {
- matchList = tmpInfo.MatchSection
- break
- }
- }
- //获取匹配对手列表
- //没有匹配到的,返回game后处理成机器人
- for idx := 0; idx < len(matchList); idx++ {
- matchInfo := matchList[idx]
- leftVal := matchInfo.LeftSection + int32(selfRank)
- rightVal := matchInfo.RightSection + int32(selfRank)
- if leftVal > rightVal {
- util.ErrorF("uid=%v TopTowerManagerGetUidByRankIdx err matchInfo=%v", matchInfo)
- continue
- }
- randVal := rightVal - leftVal + 1
- if randVal <= 0 {
- util.ErrorF("uid=%v TopTowerManagerGetUidByRankIdx err matchInfo=%v", matchInfo)
- continue
- }
- randIdx := rand.Int31n(randVal) + leftVal
- matchRankUid := this.getUidByRank(int64(randIdx))
- util.InfoF("TopTowerManagerGetUidByRankIdx uid=%v matchRankUid=%v matchInfo=%v", uid, matchRankUid, matchInfo)
- if matchRankUid <= 0 {
- continue
- }
- matchUidFightInfo := GetFightInfo(matchRankUid)
- if matchUidFightInfo == nil || matchUidFightInfo.BriefInfo == nil {
- util.InfoF("TopTowerManagerGetUidByRankIdx uid=%v matchRankUid=%v info=%v", uid, matchRankUid)
- continue
- }
- fightInfo := &serverproto.TopTowerFightRoleInfo{
- Idx: matchInfo.LevelRank,
- FightInfo: matchUidFightInfo,
- }
- ssAckMsg.FightInfoList = append(ssAckMsg.FightInfoList, fightInfo)
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *TopTowerManager) getUidByRank(randRankIdx int64) uint64 {
- mathUidDataList, err := service.GetRedis().ZRevRange(CrossMaxFightPowerRankOldPrefix, randRankIdx, randRankIdx).Result()
- if err != nil {
- util.InfoF("TopTowerManagerGetUidByRankIdx err=%v randRankIdx=%v", err, randRankIdx)
- return 0
- }
- if len(mathUidDataList) <= 0 {
- return 0
- }
- rankUid, _ := strconv.ParseUint(mathUidDataList[0], 10, 64)
- return rankUid
- }
- func (this *TopTowerManager) GetForceWinRankList(uid uint64, startIdx int32, ssAckMsg *serverproto.SSCrossTopTowerForceWinRankListAck) {
- totalRank, err := service.GetRedis().ZCard(TopTowerWinRankPrefix).Result()
- if err != nil {
- return
- }
- ssAckMsg.TotalRank = uint32(totalRank)
- //rank list
- rankList := this.getRankList(startIdx)
- ssAckMsg.RankList = append(ssAckMsg.RankList, rankList...)
- //self
- keyStr := strconv.FormatUint(uid, 10)
- tmpScore, err := service.GetRedis().ZScore(TopTowerWinRankPrefix, keyStr).Result()
- if err != nil {
- util.ErrorF("uid=%v GetForceWinRankList err=%v", uid, err)
- return
- }
- ssAckMsg.SelfScore = model.GetValByRankScoreCommon(tmpScore)
- selfRank, err := service.GetRedis().ZRevRank(TopTowerWinRankPrefix, keyStr).Result()
- if err != nil {
- return
- }
- ssAckMsg.SelfRank = uint32(selfRank + 1)
- }
- func (this *TopTowerManager) getRankList(startIdx int32) []*serverproto.CommonRankInfo {
- if startIdx <= 0 {
- startIdx = 1
- }
- begin := int64(startIdx)
- end := int64(startIdx + TopTowerForceWinRankListMaxNum)
- var rankList []*serverproto.CommonRankInfo
- topListWithScoreList, err := service.GetRedis().ZRevRangeWithScores(TopTowerWinRankPrefix, begin-1, end-1).Result()
- if err != nil {
- return rankList
- }
- for idx := range topListWithScoreList {
- rankUid, _ := strconv.ParseUint(topListWithScoreList[idx].Member.(string), 10, 64)
- score := model.GetValByRankScoreCommon(topListWithScoreList[idx].Score)
- rankInfo := &serverproto.CommonRankInfo{
- Rank: int32(idx+1) + int32(begin-1),
- Score: int32(score),
- }
- fightInfo := GetFightInfo(rankUid)
- if fightInfo != nil {
- rankInfo.BriefInfo = fightInfo.BriefInfo
- }
- rankList = append(rankList, rankInfo)
- }
- return rankList
- }
|