193 lines
4.1 KiB
Go
193 lines
4.1 KiB
Go
package game
|
|
|
|
import (
|
|
"fmt"
|
|
"server/GoUtil"
|
|
"server/db"
|
|
"server/game/mod/msg"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
RANK_TIME_SORT = 3000000000
|
|
)
|
|
|
|
type RankMgr struct {
|
|
*ServerMod
|
|
}
|
|
|
|
type RankData struct {
|
|
List map[int][]*Rank // 玩家排行榜
|
|
Champship map[int][]*Rank // 锦标赛排行榜
|
|
BackData map[int][]*Rank // 玩家排行榜 备份
|
|
}
|
|
|
|
type RankInfo struct {
|
|
List []*Rank
|
|
MyRank int
|
|
MyScore float64
|
|
}
|
|
|
|
const (
|
|
RANK_TYPE_USER = 1 // 玩家排行榜
|
|
RANK_TYPE_GLOBAL = 2 // 全球排行榜
|
|
|
|
RANK_USER = "rank_user" // redis玩家排行榜
|
|
)
|
|
|
|
type Rank struct {
|
|
Uid int
|
|
Score float64
|
|
Time int64
|
|
}
|
|
|
|
type RankMsg struct {
|
|
Uid int
|
|
Score float64
|
|
RankType int
|
|
}
|
|
|
|
func (r *RankMgr) Init() {
|
|
r.key = RANK_MGR_KEY
|
|
r.data = &RankData{
|
|
List: make(map[int][]*Rank, 0),
|
|
}
|
|
// 注册处理函数
|
|
r.init()
|
|
r.RegisterHandler(msg.HANDLE_TYPE_RANK, r.inRank)
|
|
r.RegisterHandler(msg.HANDLE_TYPE_RANK_INFO, r.getRankInfo)
|
|
r.RegisterHandler(msg.SERVER_ZERO_UPDATE, r.ZeroUpdate)
|
|
}
|
|
|
|
func (r *RankMgr) getData() *RankData {
|
|
return r.data.(*RankData)
|
|
}
|
|
|
|
// 零点更新 重置榜单
|
|
func (r *RankMgr) ZeroUpdate(m *msg.Msg) (interface{}, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// 获取榜单数据
|
|
func (r *RankMgr) getRank(RankType int) []*Rank {
|
|
if v, ok := r.getData().List[RankType]; ok {
|
|
len := min(100, len(v))
|
|
return v[:len]
|
|
}
|
|
return []*Rank{}
|
|
}
|
|
|
|
func (r *RankMgr) getAllRank(RankType int) []*Rank {
|
|
if v, ok := r.getData().List[RankType]; ok {
|
|
return v
|
|
}
|
|
return []*Rank{}
|
|
}
|
|
|
|
func (r *RankMgr) getMyRank(Uid, RankType int) (int, float64) {
|
|
if d, ok := r.getData().List[RankType]; ok {
|
|
for k, v := range d {
|
|
if v.Uid == Uid {
|
|
return k + 1, v.Score
|
|
}
|
|
}
|
|
}
|
|
return 0, 0.0
|
|
}
|
|
|
|
// 设置榜单数据
|
|
func (r *RankMgr) setRank(RankType int, data []*Rank) {
|
|
r.getData().List[RankType] = data
|
|
}
|
|
|
|
// 获取排行榜信息
|
|
func (r *RankMgr) getRankInfo(m *msg.Msg) (interface{}, error) {
|
|
data := m.Extra.(RankMsg)
|
|
if data.RankType == RANK_TYPE_GLOBAL {
|
|
return r.getRedisRankInfo(m)
|
|
}
|
|
rankList := r.getRank(data.RankType)
|
|
MyRank, MyScore := r.getMyRank(m.From, data.RankType)
|
|
return &RankInfo{
|
|
List: rankList,
|
|
MyRank: MyRank,
|
|
MyScore: MyScore,
|
|
}, nil
|
|
}
|
|
|
|
func (r *RankMgr) getRedisRankInfo(m *msg.Msg) (interface{}, error) {
|
|
RedisList, err := db.RedisZRevRangeWithScores(RANK_USER, 0, 100)
|
|
if err != nil {
|
|
return &RankInfo{}, nil
|
|
}
|
|
sort.Slice(RedisList, func(i, j int) bool { // 排序 从大到小
|
|
return RedisList[i].Score > RedisList[j].Score
|
|
})
|
|
rankList := make([]*Rank, 0)
|
|
for _, v := range RedisList {
|
|
rankList = append(rankList, &Rank{
|
|
Uid: GoUtil.Int(v.Member),
|
|
Score: v.Score,
|
|
Time: GoUtil.Now(),
|
|
})
|
|
}
|
|
MyRank, MyScore, _ := db.RedisZRankWithScores(RANK_USER, strconv.Itoa(m.From))
|
|
return &RankInfo{
|
|
List: rankList,
|
|
MyRank: int(MyRank),
|
|
MyScore: MyScore,
|
|
}, nil
|
|
}
|
|
|
|
// 进入排行榜
|
|
func (r *RankMgr) inRank(m *msg.Msg) (interface{}, error) {
|
|
data := m.Extra.(RankMsg)
|
|
rankList := r.getRank(data.RankType)
|
|
inRank := false
|
|
for _, v := range rankList {
|
|
if v.Uid == data.Uid {
|
|
if v.Score < data.Score {
|
|
v.Score = data.Score
|
|
v.Time = m.SendT
|
|
inRank = true
|
|
break
|
|
}
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
if !inRank {
|
|
rankList = append(rankList, &Rank{Uid: data.Uid, Score: data.Score, Time: m.SendT})
|
|
}
|
|
sort.Slice(rankList, func(i, j int) bool { // 排序 从大到小 数值相等按时间排序
|
|
if rankList[i].Score > rankList[j].Score {
|
|
return true
|
|
} else if rankList[i].Score == rankList[j].Score {
|
|
return rankList[i].Time < rankList[j].Time
|
|
}
|
|
return false
|
|
})
|
|
|
|
// if len(rankList) >= 100 {
|
|
// rankList = rankList[:100]
|
|
// }
|
|
r.setRank(data.RankType, rankList)
|
|
if data.RankType == RANK_TYPE_USER {
|
|
Uid := strconv.Itoa(data.Uid)
|
|
TimeSort := fmt.Sprintf("0.%d", RANK_TIME_SORT-GoUtil.Now())
|
|
TimeSortF, _ := strconv.ParseFloat(TimeSort, 64)
|
|
db.RedisZAdd(RANK_USER, Uid, data.Score+TimeSortF)
|
|
}
|
|
r.update = true
|
|
return nil, nil
|
|
}
|
|
|
|
func (r *RankMgr) ClearRank(RankType int) {
|
|
// if RankType == RANK_TYPE_GLOBAL {
|
|
// db.RedisDel(RANK_USER)
|
|
// return
|
|
// }
|
|
r.setRank(RankType, []*Rank{})
|
|
}
|