pet_home_server/src/server/game/champship_mgr.go
2026-03-09 11:47:05 +08:00

875 lines
24 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package game
import (
"fmt"
"math"
champshipCfg "server/conf/champship"
randnameCfg "server/conf/randname"
"server/db"
"server/game/mod/msg"
GoUtil "server/game_util"
proto "server/msg"
"server/pkg/github.com/name5566/leaf/log"
"sort"
"sync"
"time"
)
const (
RANK_PLAYER_ROBOT = 2
)
type ChampshipMgr struct {
*ServerMod
}
type ChampshipData struct {
mu sync.RWMutex
AutoId int
RobotId int
Rank map[int][]*ChampshipRank // 锦标赛排行榜
PreRank map[int][]*ChampshipRank // 锦标赛排行榜 备份
Pool map[int]*GroupInfo // 锦标赛未分配玩家
GroupInfo map[int]int // 锦标赛分组信息
PreGroupInfo map[int]int // 锦标赛分组信息 备份
Robot map[int]*ChampshipRobot // 机器人
PreRobot map[int]*ChampshipRobot // 机器人 备份
ZeroTime int64
}
type ChampshipRank struct {
Uid int
Score float64
Time int64
Type int
}
type ChampshipRobot struct {
Max float64
Type int
Name string
Avatar int
Face int
Level int
GroupId int
Time int64
Score float64
PerScore float64
}
type GroupInfo struct {
Uid int
Score float64
Time int64
N int
H int
}
type CRank struct {
Uid int
Score float64
N int
H int
}
func (c *ChampshipMgr) Init() {
c.key = CHAMPSHIP_MGR_KEY
c.data = &ChampshipData{
Rank: make(map[int][]*ChampshipRank, 0),
PreRank: make(map[int][]*ChampshipRank, 0),
Pool: make(map[int]*GroupInfo, 0),
GroupInfo: make(map[int]int),
PreGroupInfo: make(map[int]int),
Robot: make(map[int]*ChampshipRobot, 0),
PreRobot: make(map[int]*ChampshipRobot, 0),
}
// 注册处理函数
c.init()
Now := GoUtil.Now()
ZeroTime := GoUtil.ZeroTimestamp()
if c.getData().ZeroTime != ZeroTime {
c.ZeroUpdate()
}
Remain := Now - ZeroTime
Remain1 := 1800 - Remain%1800
c.mDispatr.AfterFunc(time.Duration(Remain1)*time.Second, func() { // 30分钟后重新分组
c.group(false)
})
c.mDispatr.AfterFunc(time.Duration(60)*time.Second, func() {
c.ai()
})
c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
c.ZeroUpdate()
})
}
func (c *ChampshipMgr) NotifyAll() (interface{}, error) {
NotifyAllPlayerMsg(&msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY,
HandleType: msg.HANDLE_MOD_PLAYER_MSG,
End: GoUtil.Now() + onehour,
})
return nil, nil
}
func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) {
c.group(true)
log.Debug("ChampshipMgr ZeroUpdate")
data := c.getData()
data.mu.Lock()
data.ZeroTime = GoUtil.ZeroTimestamp()
// 深拷贝 map避免多个协程持有同一个 map 引用导致并发读写
oldRank := make(map[int][]*ChampshipRank, len(data.Rank))
for k, v := range data.Rank {
oldRank[k] = v
}
oldRobot := make(map[int]*ChampshipRobot, len(data.Robot))
for k, v := range data.Robot {
oldRobot[k] = v
}
oldGroupInfo := make(map[int]int, len(data.GroupInfo))
for k, v := range data.GroupInfo {
oldGroupInfo[k] = v
}
data.PreRank = oldRank
data.PreRobot = oldRobot
data.PreGroupInfo = oldGroupInfo
data.AutoId = 0
data.RobotId = 1
data.Robot = make(map[int]*ChampshipRobot, 0)
data.Rank = make(map[int][]*ChampshipRank, 0)
data.GroupInfo = make(map[int]int, 0)
c.update = true
// 0点更新排行榜缓存
for k := range data.PreGroupInfo {
c.SetRankCache(k)
}
data.mu.Unlock()
c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
c.ZeroUpdate()
})
c.mDispatr.AfterFunc(time.Duration(1800)*time.Second, func() {
c.NotifyAll()
})
// 在锁外通知玩家,避免在持有锁时调用外部函数
go c.NotifyPlayer()
return nil, nil
}
func (c *ChampshipMgr) NotifyPlayer() {
data := c.getData()
data.mu.RLock()
// 深拷贝需要通知的数据,避免在锁外访问 map
notifyList := make([]struct {
Uid int
Rank int
}, 0)
for _, v := range data.PreRank {
for i := 0; i < 3 && i < len(v); i++ {
if v[i].Type == RANK_PLAYER_ROBOT {
continue
}
notifyList = append(notifyList, struct {
Uid int
Rank int
}{Uid: v[i].Uid, Rank: i + 1})
}
}
data.mu.RUnlock()
// 在锁外通知,避免持锁时间过长
for _, item := range notifyList {
NotifyChampshipResult(item.Uid, item.Rank)
}
}
func (c *ChampshipMgr) ai() (interface{}, error) {
ChampshipData := c.getData()
ChampshipData.mu.Lock()
defer ChampshipData.mu.Unlock()
Now := GoUtil.Now()
uids := make(map[int]struct{})
for k, v := range ChampshipData.Rank {
Notify := make(map[int]int)
for e, r := range v {
if r.Type == RANK_PLAYER_ROBOT {
AddScore := 0.0
Robot := ChampshipData.Robot[r.Uid]
if Robot == nil {
continue
}
if Robot.Type == 2 && Robot.Time+60 < Now {
AddScore = Robot.PerScore
Robot.Time = Now
}
if Robot.Type == 3 && Robot.Time+1800 < Now {
AddScore = Robot.PerScore
Robot.Time = Now
}
r.Score += AddScore
} else {
Notify[r.Uid] = e
}
}
sort.Slice(v, func(i, j int) bool { // 排序 从大到小 数值相等按时间排序
if v[i].Score > v[j].Score {
return true
} else if v[i].Score == v[j].Score {
return v[i].Time < v[j].Time
}
return false
})
for e, r := range v {
if r.Type == RANK_PLAYER_ROBOT {
continue
}
if Notify[r.Uid] != e {
c.SetRankCache(r.Uid)
uids[r.Uid] = struct{}{}
}
}
ChampshipData.Rank[k] = v
}
now := GoUtil.Now()
// 在锁外通知玩家,避免在持锁时启动 goroutine 访问可能被并发修改的数据
for uid := range uids {
go NotifyPlayer(uid, &msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY,
End: now + onehour,
})
}
c.mDispatr.AfterFunc(time.Duration(60)*time.Second, func() {
c.ai()
})
return nil, nil
}
func (c *ChampshipMgr) GetPreRankMsg(Uid int) *proto.ResChampshipPreRank {
ChampshipData := c.getData()
ChampshipData.mu.RLock()
defer ChampshipData.mu.RUnlock()
GroupId := ChampshipData.PreGroupInfo[Uid]
if GroupId == 0 {
return &proto.ResChampshipPreRank{}
}
RankList, ok := ChampshipData.PreRank[GroupId]
if !ok {
return &proto.ResChampshipPreRank{}
}
MyRank := 0
MyScore := 0.0
RL := make(map[int32]*proto.ResPlayerRank, 0)
for k, v := range RankList {
if v.Uid == Uid {
MyRank = k + 1
MyScore = v.Score
}
if v.Type == RANK_PLAYER_ROBOT {
Robot := ChampshipData.PreRobot[v.Uid]
if Robot == nil {
continue
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Name: Robot.Name,
Avatar: int32(Robot.Avatar),
Face: int32(Robot.Face),
Level: int32(Robot.Level),
Type: int32(v.Type),
}
} else {
SimplePlayer := G_GameLogicPtr.GetResSimplePlayerByUid(v.Uid)
if SimplePlayer == nil {
continue
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Name: SimplePlayer.Name,
Avatar: int32(SimplePlayer.Avatar),
Face: int32(SimplePlayer.Face),
Level: int32(SimplePlayer.Level),
Type: int32(v.Type),
}
}
}
return &proto.ResChampshipPreRank{
MyRank: int32(MyRank),
MyScore: float32(MyScore),
RankList: RL,
}
}
// TODO 待优化
func (c *ChampshipMgr) GetRankMsg(Uid int) *proto.ResChampshipRank {
ChampshipData := c.getData()
ChampshipData.mu.RLock()
defer ChampshipData.mu.RUnlock()
GroupId := ChampshipData.GroupInfo[Uid]
if GroupId == 0 {
return &proto.ResChampshipRank{}
}
RankList, ok := ChampshipData.Rank[GroupId]
if !ok {
return &proto.ResChampshipRank{}
}
MyRank := 0
MyScore := 0.0
RL := make(map[int32]*proto.ResPlayerRank, 0)
for k, v := range RankList {
if v.Uid == Uid {
MyRank = k + 1
MyScore = v.Score
}
if v.Type == RANK_PLAYER_ROBOT {
Robot := ChampshipData.Robot[v.Uid]
if Robot == nil {
continue
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Name: Robot.Name,
Avatar: int32(Robot.Avatar),
Face: int32(Robot.Face),
Level: int32(Robot.Level),
Type: int32(v.Type),
}
} else {
SimplePlayer := G_GameLogicPtr.GetResSimplePlayerByUid(v.Uid)
if SimplePlayer == nil {
continue
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Name: SimplePlayer.Name,
Avatar: int32(SimplePlayer.Avatar),
Face: int32(SimplePlayer.Face),
Level: int32(SimplePlayer.Level),
Type: int32(v.Type),
}
}
}
return &proto.ResChampshipRank{
MyRank: int32(MyRank),
MyScore: float32(MyScore),
RankList: RL,
}
}
// 分组
func (c *ChampshipMgr) group(iszero bool) (interface{}, error) {
Now := GoUtil.Now()
Zero := GoUtil.ZeroTimestamp()
if Now-Zero < 1800 && !iszero { // 0点30分钟内不分组
return nil, nil
}
c.mDispatr.AfterFunc(time.Duration(1800)*time.Second, func() { // 30分钟后重新分组
c.group(false)
})
ChampshipData := c.getData()
ChampshipData.mu.Lock()
defer ChampshipData.mu.Unlock()
log.Debug("ChampshipMgr group, player num:%d", len(ChampshipData.Pool))
if len(ChampshipData.Pool) == 0 { // 未分配玩家池为空
return nil, nil
}
g := make(map[int][]int, 0)
for k, v := range ChampshipData.Pool { // step 1:根据数值分配玩家
x := 0
n := champshipCfg.GetGroupId(v.N)
h := champshipCfg.GetGroupId(v.H)
if n < h {
x = min(max(n-1, h-2), 1)
} else {
x = n
}
_, ok := g[x]
if !ok {
g[x] = make([]int, 0)
}
g[x] = append(g[x], k)
}
for i := 11; i > 0; i-- {
if len(g[i]) == 0 {
continue
}
// 少于10个的元素合并到下一组
if len(g[i]) < 10 && i > 1 {
g[i-1] = append(g[i-1], g[i]...)
continue
}
// 不被10整除的元素分到下一组
if len(g[i])%10 != 0 && i > 1 {
remainder := len(g[i]) % 10
g[i-1] = append(g[i-1], g[i][len(g[i])-remainder:]...)
g[i] = g[i][:len(g[i])-remainder]
}
ChampshipData.AutoId++
StartId := ChampshipData.AutoId
for j := 0; j < len(g[i]); j++ {
ChampshipData.GroupInfo[g[i][j]] = ChampshipData.AutoId
UserData := ChampshipData.Pool[g[i][j]]
ChampshipData.Rank[ChampshipData.AutoId] = append(ChampshipData.Rank[ChampshipData.AutoId], &ChampshipRank{
Uid: UserData.Uid,
Score: UserData.Score,
Time: UserData.Time,
})
if len(ChampshipData.Rank[ChampshipData.AutoId]) == 10 {
ChampshipData.AutoId++
}
}
for j := StartId; j <= ChampshipData.AutoId; j++ { // 填充机器人
RobotNum := 30 - len(ChampshipData.Rank[j])
RobotList := CreateRobotList(i, RobotNum, j)
for _, v := range RobotList {
ChampshipData.Robot[ChampshipData.RobotId] = v
ChampshipData.Rank[j] = append(ChampshipData.Rank[j], &ChampshipRank{
Uid: ChampshipData.RobotId,
Score: v.Score,
Time: v.Time,
Type: RANK_PLAYER_ROBOT,
})
ChampshipData.RobotId++
}
sort.Slice(ChampshipData.Rank[j], func(x, y int) bool { // 排序 从大到小 数值相等按时间排序
if ChampshipData.Rank[j][x].Score > ChampshipData.Rank[j][y].Score {
return true
} else if ChampshipData.Rank[j][x].Score == ChampshipData.Rank[j][y].Score {
return ChampshipData.Rank[j][x].Time < ChampshipData.Rank[j][y].Time
}
return false
})
}
}
// 收集需要通知的玩家
notifyList := make([]int, 0, len(ChampshipData.Pool))
for k := range ChampshipData.Pool {
c.SetRankCache(k) // SetRankCache 使用 unsafe 方法,在持有锁时是安全的
notifyList = append(notifyList, k)
}
c.getData().Pool = make(map[int]*GroupInfo) // 清空未分配池
// 在锁外通知玩家,避免在持有锁时调用外部函数
for _, uid := range notifyList {
go NotifyPlayer(uid, &msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY,
End: GoUtil.Now() + onehour,
})
}
return nil, nil
}
// 获取分组ID
func (c *ChampshipMgr) getGroupId(Uid int) int {
ChampshipData := c.getData()
ChampshipData.mu.RLock()
defer ChampshipData.mu.RUnlock()
GroupId, ok := ChampshipData.GroupInfo[Uid]
if ok {
return GroupId
}
return 0
}
// 进去榜单
func (c *ChampshipMgr) inRank(m *msg.Msg) (interface{}, error) {
data := m.Extra.(CRank)
// 在加锁前获取 GroupId避免在持有写锁时调用会获取读锁的 getGroupId 导致死锁
GroupId := c.getGroupId(data.Uid)
ChampshipData := c.getData()
ChampshipData.mu.Lock()
defer ChampshipData.mu.Unlock()
// 再次检查 GroupId因为可能在等待锁期间被其他协程修改
if currentGroupId, ok := ChampshipData.GroupInfo[data.Uid]; ok {
GroupId = currentGroupId
}
if GroupId == 0 {
ChampshipData.Pool[data.Uid] = &GroupInfo{
Uid: data.Uid,
Score: data.Score,
Time: GoUtil.Now(),
N: data.N,
H: data.H,
}
return nil, nil
}
RankList, ok := ChampshipData.Rank[GroupId]
if !ok {
ChampshipData.Rank[GroupId] = make([]*ChampshipRank, 0)
}
inRank := false
Notify := make(map[int]int)
for k, v := range RankList {
if v.Uid == data.Uid {
if v.Score < data.Score {
v.Score = data.Score
v.Time = GoUtil.Now()
inRank = true
break
}
return nil, nil
}
Notify[v.Uid] = k
}
if !inRank {
RankList = append(RankList, &ChampshipRank{
Uid: data.Uid,
Score: data.Score,
Time: GoUtil.Now(),
})
}
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
})
ChampshipData.Rank[GroupId] = RankList
// 收集需要通知的玩家
notifyList := make([]int, 0)
for k, v := range RankList {
if Notify[v.Uid] != k && v.Type != RANK_PLAYER_ROBOT {
c.SetRankCache(v.Uid)
notifyList = append(notifyList, v.Uid)
}
}
// 在锁外通知玩家
for _, uid := range notifyList {
go NotifyPlayer(uid, &msg.Msg{
Type: msg.HANDLE_TYPE_CHAMPSHIP_NOTIFY,
End: GoUtil.Now() + onehour,
})
}
return nil, nil
}
func (c *ChampshipMgr) getMyRank(Uid int) int {
ChampshipData := c.getData()
ChampshipData.mu.RLock()
defer ChampshipData.mu.RUnlock()
GroupId := ChampshipData.GroupInfo[Uid]
if GroupId == 0 {
return 0
}
RankList, ok := ChampshipData.Rank[GroupId]
if !ok {
return 0
}
for k, v := range RankList {
if v.Uid == Uid {
return k + 1
}
}
return 0
}
func (c *ChampshipMgr) unsafe_getMyRank(Uid int) int {
ChampshipData := c.getData()
GroupId := ChampshipData.GroupInfo[Uid]
if GroupId == 0 {
return 0
}
RankList, ok := ChampshipData.Rank[GroupId]
if !ok {
return 0
}
for k, v := range RankList {
if v.Uid == Uid {
return k + 1
}
}
return 0
}
func (c *ChampshipMgr) getLastMyRank(Uid int) int {
ChampshipData := c.getData()
ChampshipData.mu.RLock()
defer ChampshipData.mu.RUnlock()
GroupId := ChampshipData.PreGroupInfo[Uid]
if GroupId == 0 {
return 0
}
RankList, ok := ChampshipData.PreRank[GroupId]
if !ok {
return 0
}
for k, v := range RankList {
if v.Uid == Uid {
return k + 1
}
}
return 0
}
func (c *ChampshipMgr) unsafe_getLastMyRank(Uid int) int {
ChampshipData := c.getData()
GroupId := ChampshipData.PreGroupInfo[Uid]
if GroupId == 0 {
return 0
}
RankList, ok := ChampshipData.PreRank[GroupId]
if !ok {
return 0
}
for k, v := range RankList {
if v.Uid == Uid {
return k + 1
}
}
return 0
}
func (c *ChampshipMgr) getData() *ChampshipData {
return c.data.(*ChampshipData)
}
func CreateRobotList(G, Num, GroupId int) []*ChampshipRobot {
r := make([]*ChampshipRobot, 0)
switch G {
case 1:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
for i := 0; i < 6; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < 5; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 2:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
for i := 0; i < 6; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
n := Num - 10
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 3:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
for i := 0; i < 6; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
n := Num - 10
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.15); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 4:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
n := Num - 4
for i := 0; i < int(float64(n)*0.35); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 5:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
n := Num - 3
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
}
for i := 0; i < int(float64(n)*0.3); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.2); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 6:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
n := Num - 2
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
}
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
}
for i := 0; i < int(float64(n)*0.3); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.25); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 7:
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
n := Num - 1
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
}
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
}
for i := 0; i < int(float64(n)*0.3); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.2); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
case 8, 9, 10, 11:
M10 := GoUtil.RandMap(map[int]int{0: 98, 1: 2})
if M10 == 1 {
r = append(r, CreateRobot(float64(GoUtil.RandNum(35131, 64980)), GroupId))
}
n := Num
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(12181, 21680)), GroupId))
}
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(7531, 12180)), GroupId))
}
for i := 0; i < int(float64(n)*0.05); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(4631, 7530)), GroupId))
}
for i := 0; i < int(float64(n)*0.1); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(2781, 4630)), GroupId))
}
for i := 0; i < int(float64(n)*0.3); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(1731, 2780)), GroupId))
}
for i := 0; i < int(float64(n)*0.15); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(581, 1730)), GroupId))
}
for i := 0; i < int(float64(n)*0.2); i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(241, 580)), GroupId))
}
Last := Num - len(r)
for i := 0; i < Last; i++ {
r = append(r, CreateRobot(float64(GoUtil.RandNum(20, 240)), GroupId))
}
}
return r
}
func CreateRobot(M float64, GroupId int) *ChampshipRobot {
Type := GoUtil.RandMap(map[int]int{1: 25, 2: 50, 3: 25})
Score := M / 10
PerScore := 0.0
if Type == 2 {
PerScore = math.Round((M/10*0.34)/(float64(GoUtil.NextZeroTimestampDuration())/60)*100) / 100
Score = M / 10 * 0.66
}
if Type == 3 {
PerScore = math.Round((M/10*0.34)/(float64(GoUtil.NextZeroTimestampDuration())/1800)*100) / 100
Score = 2
}
return &ChampshipRobot{
Max: M / 10,
Type: Type,
Name: randnameCfg.GetRandName(),
Avatar: GoUtil.RandNum(1, 10),
Face: GoUtil.RandNum(1, 10),
Level: GoUtil.RandNum(1, 10),
GroupId: GroupId,
Time: GoUtil.Now(),
Score: Score,
PerScore: PerScore,
}
}
func (c *ChampshipMgr) SetRankCache(Uid int) {
PreRank := c.unsafe_getLastMyRank(Uid)
Rank := c.unsafe_getMyRank(Uid)
PreGroupId := c.getData().PreGroupInfo[Uid]
GroupId := c.getData().GroupInfo[Uid]
key := fmt.Sprintf("champship_rank_cache_%d", Uid)
log.Debug("SetRankCache key:%s; data:%s", key, fmt.Sprintf("%d_%d_%d_%d", PreRank, Rank, PreGroupId, GroupId))
db.RedisSetKey(key, fmt.Sprintf("%d_%d_%d_%d", PreRank, Rank, PreGroupId, GroupId), time.Second*172800)
}
func GetRankCache(Uid int) (int, int, int, int) {
key := fmt.Sprintf("champship_rank_cache_%d", Uid)
data, err := db.RedisGetKey(key)
if err != nil || data == "" {
return 0, 0, 0, 0
}
var PreRank, Rank, PreGroupId, GroupId int
fmt.Sscanf(data, "%d_%d_%d_%d", &PreRank, &Rank, &PreGroupId, &GroupId)
return PreRank, Rank, PreGroupId, GroupId
}