153 lines
3.2 KiB
Go
153 lines
3.2 KiB
Go
package game
|
|
|
|
import (
|
|
"server/db"
|
|
"server/game/mod/msg"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
type RankMgr struct {
|
|
*ServerMod
|
|
}
|
|
|
|
type RankData struct {
|
|
List map[int][]*Rank // 玩家排行榜
|
|
Champship map[int][]*Rank // 锦标赛排行榜
|
|
BackData map[int][]*Rank // 玩家排行榜 备份
|
|
}
|
|
|
|
const (
|
|
RANK_TYPE_USER = 1 // 玩家排行榜
|
|
RANK_TYPE_CHAMPSHIP = 2 // 锦标赛排行榜
|
|
RANK_TYPE_GLOBAL = 3 // 全球排行榜
|
|
|
|
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) {
|
|
r.getData().BackData[RANK_TYPE_CHAMPSHIP] = r.getData().List[RANK_TYPE_CHAMPSHIP]
|
|
r.getData().List[RANK_TYPE_CHAMPSHIP] = []*Rank{}
|
|
r.update = true
|
|
return nil, nil
|
|
}
|
|
|
|
// 获取榜单数据
|
|
func (r *RankMgr) getRank(RankType int) []*Rank {
|
|
if v, ok := r.getData().List[RankType]; ok {
|
|
return v
|
|
}
|
|
return []*Rank{}
|
|
}
|
|
|
|
func (r *RankMgr) getLastChampshipRank() []*Rank {
|
|
if v, ok := r.getData().BackData[RANK_TYPE_CHAMPSHIP]; ok {
|
|
return v
|
|
}
|
|
return []*Rank{}
|
|
}
|
|
|
|
func (r *RankMgr) getMyRank(Uid, RankType int) int {
|
|
if d, ok := r.getData().List[RankType]; ok {
|
|
for k, v := range d {
|
|
if v.Uid == Uid {
|
|
return k + 1
|
|
}
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (r *RankMgr) getLastChampship(Uid int) int {
|
|
if d, ok := r.getData().List[RANK_TYPE_CHAMPSHIP]; ok {
|
|
for k, v := range d {
|
|
if v.Uid == Uid {
|
|
return k + 1
|
|
}
|
|
}
|
|
}
|
|
return 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)
|
|
rankList := r.getRank(data.RankType)
|
|
return rankList, 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)
|
|
db.RedisZAdd(RANK_USER, Uid, data.Score)
|
|
}
|
|
r.update = true
|
|
return nil, nil
|
|
}
|