302 lines
8.2 KiB
Go

package model
import (
"rocommon/util"
"roserver/baseserver/model"
"roserver/serverproto"
"sort"
)
const (
Expired_Time = 10 * 60 * 1000
TrialRankExpired_Time = 1 * 60 * 1000
)
////远航试炼缓存
var NtfViewUidList = map[uint64]uint64{}
func AddNtfUid(uid uint64) {
NtfViewUidList[uid] = util.GetTimeMilliseconds()
}
func DelNtfUid(uid uint64) {
delete(NtfViewUidList, uid)
}
func NtfMsg(msg interface{}) {
nowTime := util.GetTimeMilliseconds()
for uid, oldTime := range NtfViewUidList {
role := RoleMag.GetRoleFromUUid(uid)
if role == nil {
delete(NtfViewUidList, uid)
continue
}
role.ReplayGate(msg, true)
if oldTime+Expired_Time <= nowTime {
DelNtfUid(uid)
}
}
}
var cacheCrossYuanHangTrialViewList []*serverproto.YuanHangTrialData
var refreshCacheTime uint64
func SetYuanHangTrialViewList(viewList []*serverproto.YuanHangTrialData) {
cacheCrossYuanHangTrialViewList = viewList
refreshCacheTime = util.GetTimeMilliseconds()
}
func GetYuanHangTrialViewList() []*serverproto.YuanHangTrialData {
//每30s重新获取一次可见列表
nowTime := util.GetTimeMilliseconds()
if refreshCacheTime+30*1000 < nowTime {
return nil
}
return cacheCrossYuanHangTrialViewList
}
func UpdateTrialViewItem(viewDataList []*serverproto.YuanHangTrialData) {
for idx := 0; idx < len(viewDataList); idx++ {
bFind := false
for k := 0; k < len(cacheCrossYuanHangTrialViewList); k++ {
if cacheCrossYuanHangTrialViewList[k].Uid == viewDataList[idx].Uid {
cacheCrossYuanHangTrialViewList[k] = viewDataList[idx]
bFind = true
break
}
}
if !bFind {
cacheCrossYuanHangTrialViewList = append(cacheCrossYuanHangTrialViewList, viewDataList[idx])
}
ntfRole := RoleMag.GetRoleFromUUid(viewDataList[idx].Uid)
if ntfRole == nil {
ntfRole = RoleMag.GetRoleFromOffline(viewDataList[idx].Uid)
if ntfRole != nil {
ntfRole.(*Role).GetRoleCross().UpdateTrialInfo(viewDataList[idx].BeChallengeNum)
}
}
}
}
var cacheCrossYuanHangTrialRankList []*cacheTrialRank
type cacheTrialRank struct {
StartIdx int32
RefreshTime uint64
rankList []*serverproto.CommonRankInfo
}
func UpdateYuanHangTrialRankList(startIdx int32, rankList []*serverproto.CommonRankInfo) {
bFind := false
for idx := 0; idx < len(cacheCrossYuanHangTrialRankList); idx++ {
if cacheCrossYuanHangTrialRankList[idx].StartIdx == startIdx {
cacheCrossYuanHangTrialRankList[idx].rankList = rankList
cacheCrossYuanHangTrialRankList[idx].RefreshTime = util.GetTimeMilliseconds()
bFind = true
break
}
}
if !bFind {
cacheCrossYuanHangTrialRankList = append(cacheCrossYuanHangTrialRankList,
&cacheTrialRank{
StartIdx: startIdx,
rankList: rankList,
RefreshTime: util.GetTimeMilliseconds(),
})
}
}
func GetYuanHangTrialRankList(startIdx int32) []*serverproto.CommonRankInfo {
for idx := 0; idx < len(cacheCrossYuanHangTrialRankList); idx++ {
if cacheCrossYuanHangTrialRankList[idx].StartIdx == startIdx {
nowTime := util.GetTimeMilliseconds()
if cacheCrossYuanHangTrialRankList[idx].RefreshTime+TrialRankExpired_Time <= nowTime {
return nil
}
return cacheCrossYuanHangTrialRankList[idx].rankList
}
}
return nil
}
//全局跨服使用GCrossRouter
//服务器列表状态缓存
type ServerStateCache struct {
ServerType int32
ServerState *serverproto.SCGCrossGetServerStateAck
RefreshTime uint64
}
var ServerStateCacheList = map[int32]*ServerStateCache{}
//force是否判断过期需要重新获取
func GetServerStateListByType(serverType int32, force bool) *serverproto.SCGCrossGetServerStateAck {
nowTime := util.GetTimeMilliseconds()
if dataList, ok := ServerStateCacheList[serverType]; ok {
if dataList.ServerState == nil || (force && dataList.RefreshTime < nowTime) {
return nil
}
return dataList.ServerState
} else {
return nil
}
}
func GetServerStateByTypeAndLine(serverType, lineNum int32) string {
retSID := ""
listData := GetServerStateListByType(serverType, false)
if listData == nil {
return retSID
}
for idx := 0; idx < len(listData.ServerList); idx++ {
tmpNodeId := listData.ServerList[idx]
beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
if beginLineNum <= lineNum && lineNum <= endLineNum {
retSID = tmpNodeId.Sid
break
}
}
return retSID
}
//选择线路未满的房间(线路号从小达到)
func GetServerStateByType(serverType int32) (string, int32) {
retSID := ""
listData := GetServerStateListByType(serverType, false)
if listData == nil {
return retSID, 0
}
var lineNum int32 = 0
for idx := 0; idx < len(listData.ServerList); idx++ {
tmpNodeId := listData.ServerList[idx]
beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
for lineIdx := beginLineNum; lineIdx <= endLineNum; lineIdx++ {
bFull := false
for k := 0; k < len(tmpNodeId.StateList); k++ {
if tmpNodeId.StateList[k].Line == lineIdx {
if tmpNodeId.StateList[k].CurNum >= tmpNodeId.MaxSpaceEntityNum {
bFull = true
}
break
}
}
if !bFull {
retSID = tmpNodeId.Sid
lineNum = lineIdx
break
}
}
}
return retSID, lineNum
}
func UpdateServerStateListByType(serverType int32, serverStateData *serverproto.SSGetGServerStateAck) {
if len(serverStateData.ServerList) <= 0 {
return
}
nowTime := util.GetTimeMilliseconds()
if dataList, ok := ServerStateCacheList[serverType]; ok {
dataList.ServerState.ServerList = serverStateData.ServerList
dataList.RefreshTime = nowTime + 5*1000
} else {
ServerStateCacheList[serverType] = &ServerStateCache{
ServerType: serverType,
RefreshTime: nowTime + 5*1000,
ServerState: &serverproto.SCGCrossGetServerStateAck{
ServerType: serverType,
ServerList: serverStateData.ServerList,
},
}
sort.Slice(ServerStateCacheList[serverType].ServerState.ServerList, func(i, j int) bool {
return ServerStateCacheList[serverType].ServerState.ServerList[i].Id <
ServerStateCacheList[serverType].ServerState.ServerList[j].Id
})
}
//人数为0的线路初始化
listData := ServerStateCacheList[serverType].ServerState
for idx := 0; idx < len(listData.ServerList); idx++ {
tmpNodeId := listData.ServerList[idx]
if len(tmpNodeId.StateList) >= int(tmpNodeId.MaxLineNum) {
continue
}
beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
for lineIdx := beginLineNum; lineIdx <= endLineNum; lineIdx++ {
bFind := false
for k := 0; k < len(tmpNodeId.StateList); k++ {
if tmpNodeId.StateList[k].Line == lineIdx {
bFind = true
break
}
}
if !bFind {
tmpNodeId.StateList = append(tmpNodeId.StateList, &serverproto.StateDetailDesc{Line: lineIdx})
}
}
}
}
//分发来自跨服的消息
func SendMsgFromCrossRouter(msg interface{}, cliId model.ClientID) {
if cliId.SessID > 0 {
role := RoleMag.GetRole(cliId)
if role == nil {
return
}
util.DebugF("uid=%v receive SSGCrossMapEnterNtf ms=%v", role.GetUUid(), msg)
role.ReplayGate(msg, true)
} else if len(cliId.SessIdList) > 0 {
var clientIdLIstMap = map[string][]uint64{}
//只发送当前game相关的玩家
for idx := 0; idx < len(cliId.SessIdList); idx++ {
role := RoleMag.GetRoleFromUUid(cliId.SessIdList[idx])
if role == nil {
continue
}
serviceId := role.CliID().ServiceID
clientIdLIstMap[serviceId] = append(clientIdLIstMap[serviceId], role.CliID().SessID)
}
for key, dataList := range clientIdLIstMap {
ReplayGateList(msg, dataList, key, true)
}
}
}
type CrossManager struct {
updateTimer util.ServerTimer //更新定时器
initStartUp bool
}
func newCrossMag() *CrossManager {
mag := &CrossManager{}
mag.updateTimer = util.NewDurationTimer(util.GetCurrentTime(), 1000)
return mag
}
func (this *CrossManager) init(ms uint64) {
if this.initStartUp {
return
}
this.initStartUp = true
}
func (this *CrossManager) Update(ms uint64) {
if !this.initStartUp {
this.init(ms)
}
if this.initStartUp && this.updateTimer.IsStart() && this.updateTimer.IsExpired(ms) {
if len(ServerStateCacheList) <= 0 {
ssStateMsg := &serverproto.SSGetGServerStateReq{
ServerType: model.SERVICE_NODE_TYPE_GLOBALCROSSMAP,
}
SendSocial(ssStateMsg)
}
}
}