| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- package model
- import (
- "rocommon/service"
- "rocommon/util"
- "roserver/baseserver/model"
- "roserver/serverproto"
- "sort"
- "time"
- )
- 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
- startupTimeDate, nowTimeDate time.Time
- curSeasonId, lastSeasonId int32
- seasonStartTime, seasonEndTime time.Time
- }
- func newCrossMag() *CrossManager {
- mag := &CrossManager{}
- mag.updateTimer = util.NewDurationTimer(util.GetCurrentTime(), 5000)
- return mag
- }
- func (this *CrossManager) init(ms uint64) {
- startUpTime := service.GetServiceStartupTime()
- if startUpTime > 0 {
- this.initSeason(startUpTime)
- }
- }
- func (this *CrossManager) initSeasonTime(serviceStartUpTime uint64) {
- loc := util.GetLoc()
- //获取当前处于第几个赛季
- this.nowTimeDate = util.GetCurrentTimeNow()
- deltaTime := model.ConvertArenaSeason.DiffDurationDay + int64((model.ConvertArenaSeason.Reset+1)*24*3600)
- //startTime := model.ConvertArenaSeason.StartTime
- //endTime := model.ConvertArenaSeason.EndTime
- //根据开服时间计算赛季开始时间和结束时间
- _, startHourTimeStr := util.GetDayAndHourByTimeStr(model.ConvertArenaSeason.StartTimeStr)
- serviceStartUpDayTime := util.GetDayByTimeStr2(serviceStartUpTime)
- tmpStartTimeStr := serviceStartUpDayTime.Format(util.DATE_FORMAT1) + " " + startHourTimeStr
- startTime := util.GetTimeByStr(tmpStartTimeStr)
- util.DebugF("tmpStartTime=%v", startTime.String())
- _, endHourTimeStr := util.GetDayAndHourByTimeStr(model.ConvertArenaSeason.EndTimeStr)
- tmpEndTime := time.Unix(serviceStartUpDayTime.Unix()+model.ConvertArenaSeason.DiffDurationDay, 0).In(loc)
- tmpEndTimeStr := tmpEndTime.Format(util.DATE_FORMAT1) + " " + endHourTimeStr
- endTime := util.GetTimeByStr(tmpEndTimeStr)
- util.DebugF("tmpStartTime=%v", endTime.String())
- model.ConvertArenaSeason.StartTime = startTime
- model.ConvertArenaSeason.EndTime = endTime
- var seasonIdx int32 = 0
- //循环赛季
- for {
- seasonIdx++
- if this.nowTimeDate.After(startTime) && this.nowTimeDate.Before(endTime) {
- this.curSeasonId = seasonIdx
- this.seasonStartTime = startTime
- this.seasonEndTime = endTime
- util.InfoF("curSeasonId=%v stime=%v etime=%v", seasonIdx, startTime.Unix(), endTime.Unix())
- break
- } else if this.nowTimeDate.Before(startTime) {
- break
- } else if this.nowTimeDate.After(endTime) {
- this.lastSeasonId = seasonIdx
- }
- startTime = time.Unix(startTime.Unix()+deltaTime, 0).In(loc)
- endTime = time.Unix(endTime.Unix()+deltaTime, 0).In(loc)
- }
- }
- func (this *CrossManager) getNextSeasonTime() (time.Time, time.Time) {
- loc := util.GetLoc()
- if this.lastSeasonId <= 0 {
- return model.ConvertArenaSeason.StartTime, model.ConvertArenaSeason.EndTime
- } else {
- tempSeasonId := this.lastSeasonId
- if this.curSeasonId != 0 {
- tempSeasonId = this.curSeasonId
- }
- resetTime := int64((model.ConvertArenaSeason.Reset + 1) * HourMs)
- diffDurationDay := model.ConvertArenaSeason.DiffDurationDay
- deltaTime := (diffDurationDay + resetTime) * int64(tempSeasonId)
- startTime := time.Unix(model.ConvertArenaSeason.StartTime.Unix()+deltaTime, 0).In(loc)
- endTime := time.Unix(model.ConvertArenaSeason.EndTime.Unix()+deltaTime, 0).In(loc)
- return startTime, endTime
- }
- }
- func (this *CrossManager) getSeasonTime(seasonId int32) (time.Time, time.Time) {
- resetTime := int64((model.ConvertArenaSeason.Reset + 1) * HourMs)
- diffDurationDay := model.ConvertArenaSeason.DiffDurationDay
- deltaTime := (diffDurationDay + resetTime) * int64(seasonId-1)
- loc := util.GetLoc()
- startTime := time.Unix(model.ConvertArenaSeason.StartTime.Unix()+deltaTime, 0).In(loc)
- endTime := time.Unix(model.ConvertArenaSeason.EndTime.Unix()+deltaTime, 0).In(loc)
- return startTime, endTime
- }
- func (this *CrossManager) initSeason(serviceStartUpTime uint64) {
- if model.ConvertArenaSeason == nil {
- util.ErrorF("ConvertArenaSeason zone=%v data not found", service.GetServiceConfig().Node.Zone)
- return
- }
- loc := util.GetLoc()
- //ServiceStartTime
- this.startupTimeDate = time.Unix(int64(serviceStartUpTime/1000), 0).In(loc)
- //util.InfoF("ServiceStartTime=%v", this.startupTimeDate)
- this.initStartUp = true
- //获取当前处于第几个赛季
- this.initSeasonTime(serviceStartUpTime)
- }
- 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)
- }
- }
- // this.nowTimeDate = util.GetCurrentTimeNow()
- //
- // if this.curSeasonId > 0 {
- // //logUtil.InfoF("curSeasonId:%v endTime:%v", this.curSeasonId, this.seasonEndTime)
- // //赛季结算
- // if this.nowTimeDate.After(this.seasonEndTime) {
- // util.InfoF("ServiceStartTimeReward curseasonid=%v seasonendtime=%v", this.curSeasonId, this.seasonEndTime)
- // this.lastSeasonId = this.curSeasonId
- // this.DoSeasonReward(this.curSeasonId)
- //
- // // this.lastSeasonId = this.curSeasonId
- // this.curSeasonId = 0
- // }
- // } else {
- // sTime, eTime := this.getNextSeasonTime()
- // //开启新赛季
- // //logUtil.InfoF("openNewSeason id:%v s:%v e:%v", this.lastSeasonId+1, sTime, eTime)
- // if this.nowTimeDate.After(sTime) {
- // util.InfoF("ServiceStartTimeNewSeason lastseasonid=%v starttime=%v", this.lastSeasonId, sTime)
- // this.curSeasonId = this.lastSeasonId + 1
- // this.seasonStartTime = sTime
- // this.seasonEndTime = eTime
- // this.DoSeasonRefresh()
- // }
- // }
- //}
- }
- func (this *CrossManager) GetSeason() int32 {
- if this.curSeasonId <= 0 {
- return this.lastSeasonId
- }
- return this.curSeasonId
- }
- // 获取对应赛季奖励
- func (this *CrossManager) GetSeasonReward(role *Role, selfRank, rewardSeasonId int32) {
- if selfRank <= 0 || role == nil || model.ConvertArenaSeason == nil {
- return
- }
- //获取排名奖励,发送邮件
- for _, data := range model.ConvertCrossRankInfo.RewardInfo {
- if selfRank >= data.Left && selfRank <= data.Right {
- //发送邮件
- role.GetRoleMail().AddMail(model.GlobalMailIdArenaTopReward, serverproto.MailType_MailType_Arena,
- data.RewardList, []int32{selfRank, rewardSeasonId}, "", "")
- break
- }
- }
- //
- //// 赛季第一名触发称号事件
- //var value int32 = 1
- //if selfRank != 1 {
- // value = role.roleTask.GetTypeCnt(int32(serverproto.TaskType_Eve_Arean_First)) * -1
- //} else {
- // TaskMagCheck(role, serverproto.TaskType_Eve_Arean_First_Cnt, 1)
- //}
- //role.roleTask.AddTypeCnt(serverproto.TaskType_Eve_Arean_First, value)
- //TaskMagCheck(role, serverproto.TaskType_Eve_Arean_First, rewardSeasonId)
- }
- // 赛季结算
- func (this *CrossManager) DoSeasonReward(seasonId int32) {
- ssMsg := &serverproto.SSArenaRankUpdateReq{
- LastSeasonId: seasonId,
- }
- sendNum := 0
- for _, chRole := range RoleMag.channelRoleList {
- if chRole.GetState() != ROLE_STATE_ONLINE {
- continue
- }
- //段位奖励
- //chRole.(*Role).GetRoleArena().ScoreLevelReward()
- //top排行奖励
- //if chRole.(*Role).GetRoleArena().arenaInfo.Score >= model.MinTopRankScore {
- if chRole.(*Role).GetRoleArena().arenaInfo.Score > 0 {
- ssMsg.RewardPlayerList = append(ssMsg.RewardPlayerList, chRole.GetUUid())
- sendNum++
- if sendNum >= 50 {
- SendRankService(ssMsg)
- sendNum = 0
- ssMsg.RewardPlayerList = ssMsg.RewardPlayerList[:0]
- }
- }
- }
- //rank处理结算数据
- SendRankService(ssMsg)
- }
- // 开启新赛季
- func (this *CrossManager) DoSeasonRefresh() {
- for _, chRole := range RoleMag.channelRoleList {
- if chRole.GetState() == ROLE_STATE_ONLINE ||
- chRole.GetState() == ROLE_STATE_OFFLINE {
- chRole.(*Role).GetRoleArena().DoSeasonRefresh()
- }
- }
- }
|