cross_manager.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. package model
  2. import (
  3. "rocommon/service"
  4. "rocommon/util"
  5. "roserver/baseserver/model"
  6. "roserver/serverproto"
  7. "sort"
  8. "time"
  9. )
  10. const (
  11. Expired_Time = 10 * 60 * 1000
  12. TrialRankExpired_Time = 1 * 60 * 1000
  13. )
  14. // //远航试炼缓存
  15. var NtfViewUidList = map[uint64]uint64{}
  16. func AddNtfUid(uid uint64) {
  17. NtfViewUidList[uid] = util.GetTimeMilliseconds()
  18. }
  19. func DelNtfUid(uid uint64) {
  20. delete(NtfViewUidList, uid)
  21. }
  22. func NtfMsg(msg interface{}) {
  23. nowTime := util.GetTimeMilliseconds()
  24. for uid, oldTime := range NtfViewUidList {
  25. role := RoleMag.GetRoleFromUUid(uid)
  26. if role == nil {
  27. delete(NtfViewUidList, uid)
  28. continue
  29. }
  30. role.ReplayGate(msg, true)
  31. if oldTime+Expired_Time <= nowTime {
  32. DelNtfUid(uid)
  33. }
  34. }
  35. }
  36. var cacheCrossYuanHangTrialViewList []*serverproto.YuanHangTrialData
  37. var refreshCacheTime uint64
  38. func SetYuanHangTrialViewList(viewList []*serverproto.YuanHangTrialData) {
  39. cacheCrossYuanHangTrialViewList = viewList
  40. refreshCacheTime = util.GetTimeMilliseconds()
  41. }
  42. func GetYuanHangTrialViewList() []*serverproto.YuanHangTrialData {
  43. //每30s重新获取一次可见列表
  44. nowTime := util.GetTimeMilliseconds()
  45. if refreshCacheTime+30*1000 < nowTime {
  46. return nil
  47. }
  48. return cacheCrossYuanHangTrialViewList
  49. }
  50. func UpdateTrialViewItem(viewDataList []*serverproto.YuanHangTrialData) {
  51. for idx := 0; idx < len(viewDataList); idx++ {
  52. bFind := false
  53. for k := 0; k < len(cacheCrossYuanHangTrialViewList); k++ {
  54. if cacheCrossYuanHangTrialViewList[k].Uid == viewDataList[idx].Uid {
  55. cacheCrossYuanHangTrialViewList[k] = viewDataList[idx]
  56. bFind = true
  57. break
  58. }
  59. }
  60. if !bFind {
  61. cacheCrossYuanHangTrialViewList = append(cacheCrossYuanHangTrialViewList, viewDataList[idx])
  62. }
  63. ntfRole := RoleMag.GetRoleFromUUid(viewDataList[idx].Uid)
  64. if ntfRole == nil {
  65. ntfRole = RoleMag.GetRoleFromOffline(viewDataList[idx].Uid)
  66. if ntfRole != nil {
  67. ntfRole.(*Role).GetRoleCross().UpdateTrialInfo(viewDataList[idx].BeChallengeNum)
  68. }
  69. }
  70. }
  71. }
  72. var cacheCrossYuanHangTrialRankList []*cacheTrialRank
  73. type cacheTrialRank struct {
  74. StartIdx int32
  75. RefreshTime uint64
  76. rankList []*serverproto.CommonRankInfo
  77. }
  78. func UpdateYuanHangTrialRankList(startIdx int32, rankList []*serverproto.CommonRankInfo) {
  79. bFind := false
  80. for idx := 0; idx < len(cacheCrossYuanHangTrialRankList); idx++ {
  81. if cacheCrossYuanHangTrialRankList[idx].StartIdx == startIdx {
  82. cacheCrossYuanHangTrialRankList[idx].rankList = rankList
  83. cacheCrossYuanHangTrialRankList[idx].RefreshTime = util.GetTimeMilliseconds()
  84. bFind = true
  85. break
  86. }
  87. }
  88. if !bFind {
  89. cacheCrossYuanHangTrialRankList = append(cacheCrossYuanHangTrialRankList,
  90. &cacheTrialRank{
  91. StartIdx: startIdx,
  92. rankList: rankList,
  93. RefreshTime: util.GetTimeMilliseconds(),
  94. })
  95. }
  96. }
  97. func GetYuanHangTrialRankList(startIdx int32) []*serverproto.CommonRankInfo {
  98. for idx := 0; idx < len(cacheCrossYuanHangTrialRankList); idx++ {
  99. if cacheCrossYuanHangTrialRankList[idx].StartIdx == startIdx {
  100. nowTime := util.GetTimeMilliseconds()
  101. if cacheCrossYuanHangTrialRankList[idx].RefreshTime+TrialRankExpired_Time <= nowTime {
  102. return nil
  103. }
  104. return cacheCrossYuanHangTrialRankList[idx].rankList
  105. }
  106. }
  107. return nil
  108. }
  109. // 全局跨服使用GCrossRouter
  110. // 服务器列表状态缓存
  111. type ServerStateCache struct {
  112. ServerType int32
  113. ServerState *serverproto.SCGCrossGetServerStateAck
  114. RefreshTime uint64
  115. }
  116. var ServerStateCacheList = map[int32]*ServerStateCache{}
  117. // force是否判断过期需要重新获取
  118. func GetServerStateListByType(serverType int32, force bool) *serverproto.SCGCrossGetServerStateAck {
  119. nowTime := util.GetTimeMilliseconds()
  120. if dataList, ok := ServerStateCacheList[serverType]; ok {
  121. if dataList.ServerState == nil || (force && dataList.RefreshTime < nowTime) {
  122. return nil
  123. }
  124. return dataList.ServerState
  125. } else {
  126. return nil
  127. }
  128. }
  129. func GetServerStateByTypeAndLine(serverType, lineNum int32) string {
  130. retSID := ""
  131. listData := GetServerStateListByType(serverType, false)
  132. if listData == nil {
  133. return retSID
  134. }
  135. for idx := 0; idx < len(listData.ServerList); idx++ {
  136. tmpNodeId := listData.ServerList[idx]
  137. beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
  138. endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
  139. if beginLineNum <= lineNum && lineNum <= endLineNum {
  140. retSID = tmpNodeId.Sid
  141. break
  142. }
  143. }
  144. return retSID
  145. }
  146. // 选择线路未满的房间(线路号从小达到)
  147. func GetServerStateByType(serverType int32) (string, int32) {
  148. retSID := ""
  149. listData := GetServerStateListByType(serverType, false)
  150. if listData == nil {
  151. return retSID, 0
  152. }
  153. var lineNum int32 = 0
  154. for idx := 0; idx < len(listData.ServerList); idx++ {
  155. tmpNodeId := listData.ServerList[idx]
  156. beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
  157. endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
  158. for lineIdx := beginLineNum; lineIdx <= endLineNum; lineIdx++ {
  159. bFull := false
  160. for k := 0; k < len(tmpNodeId.StateList); k++ {
  161. if tmpNodeId.StateList[k].Line == lineIdx {
  162. if tmpNodeId.StateList[k].CurNum >= tmpNodeId.MaxSpaceEntityNum {
  163. bFull = true
  164. }
  165. break
  166. }
  167. }
  168. if !bFull {
  169. retSID = tmpNodeId.Sid
  170. lineNum = lineIdx
  171. break
  172. }
  173. }
  174. }
  175. return retSID, lineNum
  176. }
  177. func UpdateServerStateListByType(serverType int32, serverStateData *serverproto.SSGetGServerStateAck) {
  178. if len(serverStateData.ServerList) <= 0 {
  179. return
  180. }
  181. nowTime := util.GetTimeMilliseconds()
  182. if dataList, ok := ServerStateCacheList[serverType]; ok {
  183. dataList.ServerState.ServerList = serverStateData.ServerList
  184. dataList.RefreshTime = nowTime + 5*1000
  185. } else {
  186. ServerStateCacheList[serverType] = &ServerStateCache{
  187. ServerType: serverType,
  188. RefreshTime: nowTime + 5*1000,
  189. ServerState: &serverproto.SCGCrossGetServerStateAck{
  190. ServerType: serverType,
  191. ServerList: serverStateData.ServerList,
  192. },
  193. }
  194. sort.Slice(ServerStateCacheList[serverType].ServerState.ServerList, func(i, j int) bool {
  195. return ServerStateCacheList[serverType].ServerState.ServerList[i].Id <
  196. ServerStateCacheList[serverType].ServerState.ServerList[j].Id
  197. })
  198. }
  199. //人数为0的线路初始化
  200. listData := ServerStateCacheList[serverType].ServerState
  201. for idx := 0; idx < len(listData.ServerList); idx++ {
  202. tmpNodeId := listData.ServerList[idx]
  203. if len(tmpNodeId.StateList) >= int(tmpNodeId.MaxLineNum) {
  204. continue
  205. }
  206. beginLineNum := (tmpNodeId.Id-1)*tmpNodeId.MaxLineNum + 1
  207. endLineNum := tmpNodeId.Id * tmpNodeId.MaxLineNum
  208. for lineIdx := beginLineNum; lineIdx <= endLineNum; lineIdx++ {
  209. bFind := false
  210. for k := 0; k < len(tmpNodeId.StateList); k++ {
  211. if tmpNodeId.StateList[k].Line == lineIdx {
  212. bFind = true
  213. break
  214. }
  215. }
  216. if !bFind {
  217. tmpNodeId.StateList = append(tmpNodeId.StateList, &serverproto.StateDetailDesc{Line: lineIdx})
  218. }
  219. }
  220. }
  221. }
  222. // 分发来自跨服的消息
  223. func SendMsgFromCrossRouter(msg interface{}, cliId model.ClientID) {
  224. if cliId.SessID > 0 {
  225. role := RoleMag.GetRole(cliId)
  226. if role == nil {
  227. return
  228. }
  229. util.DebugF("uid=%v receive SSGCrossMapEnterNtf ms=%v", role.GetUUid(), msg)
  230. role.ReplayGate(msg, true)
  231. } else if len(cliId.SessIdList) > 0 {
  232. var clientIdLIstMap = map[string][]uint64{}
  233. //只发送当前game相关的玩家
  234. for idx := 0; idx < len(cliId.SessIdList); idx++ {
  235. role := RoleMag.GetRoleFromUUid(cliId.SessIdList[idx])
  236. if role == nil {
  237. continue
  238. }
  239. serviceId := role.CliID().ServiceID
  240. clientIdLIstMap[serviceId] = append(clientIdLIstMap[serviceId], role.CliID().SessID)
  241. }
  242. for key, dataList := range clientIdLIstMap {
  243. ReplayGateList(msg, dataList, key, true)
  244. }
  245. }
  246. }
  247. type CrossManager struct {
  248. updateTimer util.ServerTimer //更新定时器
  249. initStartUp bool
  250. startupTimeDate, nowTimeDate time.Time
  251. curSeasonId, lastSeasonId int32
  252. seasonStartTime, seasonEndTime time.Time
  253. }
  254. func newCrossMag() *CrossManager {
  255. mag := &CrossManager{}
  256. mag.updateTimer = util.NewDurationTimer(util.GetCurrentTime(), 5000)
  257. return mag
  258. }
  259. func (this *CrossManager) init(ms uint64) {
  260. startUpTime := service.GetServiceStartupTime()
  261. if startUpTime > 0 {
  262. this.initSeason(startUpTime)
  263. }
  264. }
  265. func (this *CrossManager) initSeasonTime(serviceStartUpTime uint64) {
  266. loc := util.GetLoc()
  267. //获取当前处于第几个赛季
  268. this.nowTimeDate = util.GetCurrentTimeNow()
  269. deltaTime := model.ConvertArenaSeason.DiffDurationDay + int64((model.ConvertArenaSeason.Reset+1)*24*3600)
  270. //startTime := model.ConvertArenaSeason.StartTime
  271. //endTime := model.ConvertArenaSeason.EndTime
  272. //根据开服时间计算赛季开始时间和结束时间
  273. _, startHourTimeStr := util.GetDayAndHourByTimeStr(model.ConvertArenaSeason.StartTimeStr)
  274. serviceStartUpDayTime := util.GetDayByTimeStr2(serviceStartUpTime)
  275. tmpStartTimeStr := serviceStartUpDayTime.Format(util.DATE_FORMAT1) + " " + startHourTimeStr
  276. startTime := util.GetTimeByStr(tmpStartTimeStr)
  277. util.DebugF("tmpStartTime=%v", startTime.String())
  278. _, endHourTimeStr := util.GetDayAndHourByTimeStr(model.ConvertArenaSeason.EndTimeStr)
  279. tmpEndTime := time.Unix(serviceStartUpDayTime.Unix()+model.ConvertArenaSeason.DiffDurationDay, 0).In(loc)
  280. tmpEndTimeStr := tmpEndTime.Format(util.DATE_FORMAT1) + " " + endHourTimeStr
  281. endTime := util.GetTimeByStr(tmpEndTimeStr)
  282. util.DebugF("tmpStartTime=%v", endTime.String())
  283. model.ConvertArenaSeason.StartTime = startTime
  284. model.ConvertArenaSeason.EndTime = endTime
  285. var seasonIdx int32 = 0
  286. //循环赛季
  287. for {
  288. seasonIdx++
  289. if this.nowTimeDate.After(startTime) && this.nowTimeDate.Before(endTime) {
  290. this.curSeasonId = seasonIdx
  291. this.seasonStartTime = startTime
  292. this.seasonEndTime = endTime
  293. util.InfoF("curSeasonId=%v stime=%v etime=%v", seasonIdx, startTime.Unix(), endTime.Unix())
  294. break
  295. } else if this.nowTimeDate.Before(startTime) {
  296. break
  297. } else if this.nowTimeDate.After(endTime) {
  298. this.lastSeasonId = seasonIdx
  299. }
  300. startTime = time.Unix(startTime.Unix()+deltaTime, 0).In(loc)
  301. endTime = time.Unix(endTime.Unix()+deltaTime, 0).In(loc)
  302. }
  303. }
  304. func (this *CrossManager) getNextSeasonTime() (time.Time, time.Time) {
  305. loc := util.GetLoc()
  306. if this.lastSeasonId <= 0 {
  307. return model.ConvertArenaSeason.StartTime, model.ConvertArenaSeason.EndTime
  308. } else {
  309. tempSeasonId := this.lastSeasonId
  310. if this.curSeasonId != 0 {
  311. tempSeasonId = this.curSeasonId
  312. }
  313. resetTime := int64((model.ConvertArenaSeason.Reset + 1) * HourMs)
  314. diffDurationDay := model.ConvertArenaSeason.DiffDurationDay
  315. deltaTime := (diffDurationDay + resetTime) * int64(tempSeasonId)
  316. startTime := time.Unix(model.ConvertArenaSeason.StartTime.Unix()+deltaTime, 0).In(loc)
  317. endTime := time.Unix(model.ConvertArenaSeason.EndTime.Unix()+deltaTime, 0).In(loc)
  318. return startTime, endTime
  319. }
  320. }
  321. func (this *CrossManager) getSeasonTime(seasonId int32) (time.Time, time.Time) {
  322. resetTime := int64((model.ConvertArenaSeason.Reset + 1) * HourMs)
  323. diffDurationDay := model.ConvertArenaSeason.DiffDurationDay
  324. deltaTime := (diffDurationDay + resetTime) * int64(seasonId-1)
  325. loc := util.GetLoc()
  326. startTime := time.Unix(model.ConvertArenaSeason.StartTime.Unix()+deltaTime, 0).In(loc)
  327. endTime := time.Unix(model.ConvertArenaSeason.EndTime.Unix()+deltaTime, 0).In(loc)
  328. return startTime, endTime
  329. }
  330. func (this *CrossManager) initSeason(serviceStartUpTime uint64) {
  331. if model.ConvertArenaSeason == nil {
  332. util.ErrorF("ConvertArenaSeason zone=%v data not found", service.GetServiceConfig().Node.Zone)
  333. return
  334. }
  335. loc := util.GetLoc()
  336. //ServiceStartTime
  337. this.startupTimeDate = time.Unix(int64(serviceStartUpTime/1000), 0).In(loc)
  338. //util.InfoF("ServiceStartTime=%v", this.startupTimeDate)
  339. this.initStartUp = true
  340. //获取当前处于第几个赛季
  341. this.initSeasonTime(serviceStartUpTime)
  342. }
  343. func (this *CrossManager) Update(ms uint64) {
  344. if !this.initStartUp {
  345. this.init(ms)
  346. }
  347. if this.initStartUp && this.updateTimer.IsStart() && this.updateTimer.IsExpired(ms) {
  348. if len(ServerStateCacheList) <= 0 {
  349. ssStateMsg := &serverproto.SSGetGServerStateReq{
  350. ServerType: model.SERVICE_NODE_TYPE_GLOBALCROSSMAP,
  351. }
  352. SendSocial(ssStateMsg)
  353. }
  354. }
  355. // this.nowTimeDate = util.GetCurrentTimeNow()
  356. //
  357. // if this.curSeasonId > 0 {
  358. // //logUtil.InfoF("curSeasonId:%v endTime:%v", this.curSeasonId, this.seasonEndTime)
  359. // //赛季结算
  360. // if this.nowTimeDate.After(this.seasonEndTime) {
  361. // util.InfoF("ServiceStartTimeReward curseasonid=%v seasonendtime=%v", this.curSeasonId, this.seasonEndTime)
  362. // this.lastSeasonId = this.curSeasonId
  363. // this.DoSeasonReward(this.curSeasonId)
  364. //
  365. // // this.lastSeasonId = this.curSeasonId
  366. // this.curSeasonId = 0
  367. // }
  368. // } else {
  369. // sTime, eTime := this.getNextSeasonTime()
  370. // //开启新赛季
  371. // //logUtil.InfoF("openNewSeason id:%v s:%v e:%v", this.lastSeasonId+1, sTime, eTime)
  372. // if this.nowTimeDate.After(sTime) {
  373. // util.InfoF("ServiceStartTimeNewSeason lastseasonid=%v starttime=%v", this.lastSeasonId, sTime)
  374. // this.curSeasonId = this.lastSeasonId + 1
  375. // this.seasonStartTime = sTime
  376. // this.seasonEndTime = eTime
  377. // this.DoSeasonRefresh()
  378. // }
  379. // }
  380. //}
  381. }
  382. func (this *CrossManager) GetSeason() int32 {
  383. if this.curSeasonId <= 0 {
  384. return this.lastSeasonId
  385. }
  386. return this.curSeasonId
  387. }
  388. // 获取对应赛季奖励
  389. func (this *CrossManager) GetSeasonReward(role *Role, selfRank, rewardSeasonId int32) {
  390. if selfRank <= 0 || role == nil || model.ConvertArenaSeason == nil {
  391. return
  392. }
  393. //获取排名奖励,发送邮件
  394. for _, data := range model.ConvertCrossRankInfo.RewardInfo {
  395. if selfRank >= data.Left && selfRank <= data.Right {
  396. //发送邮件
  397. role.GetRoleMail().AddMail(model.GlobalMailIdArenaTopReward, serverproto.MailType_MailType_Arena,
  398. data.RewardList, []int32{selfRank, rewardSeasonId}, "", "")
  399. break
  400. }
  401. }
  402. //
  403. //// 赛季第一名触发称号事件
  404. //var value int32 = 1
  405. //if selfRank != 1 {
  406. // value = role.roleTask.GetTypeCnt(int32(serverproto.TaskType_Eve_Arean_First)) * -1
  407. //} else {
  408. // TaskMagCheck(role, serverproto.TaskType_Eve_Arean_First_Cnt, 1)
  409. //}
  410. //role.roleTask.AddTypeCnt(serverproto.TaskType_Eve_Arean_First, value)
  411. //TaskMagCheck(role, serverproto.TaskType_Eve_Arean_First, rewardSeasonId)
  412. }
  413. // 赛季结算
  414. func (this *CrossManager) DoSeasonReward(seasonId int32) {
  415. ssMsg := &serverproto.SSArenaRankUpdateReq{
  416. LastSeasonId: seasonId,
  417. }
  418. sendNum := 0
  419. for _, chRole := range RoleMag.channelRoleList {
  420. if chRole.GetState() != ROLE_STATE_ONLINE {
  421. continue
  422. }
  423. //段位奖励
  424. //chRole.(*Role).GetRoleArena().ScoreLevelReward()
  425. //top排行奖励
  426. //if chRole.(*Role).GetRoleArena().arenaInfo.Score >= model.MinTopRankScore {
  427. if chRole.(*Role).GetRoleArena().arenaInfo.Score > 0 {
  428. ssMsg.RewardPlayerList = append(ssMsg.RewardPlayerList, chRole.GetUUid())
  429. sendNum++
  430. if sendNum >= 50 {
  431. SendRankService(ssMsg)
  432. sendNum = 0
  433. ssMsg.RewardPlayerList = ssMsg.RewardPlayerList[:0]
  434. }
  435. }
  436. }
  437. //rank处理结算数据
  438. SendRankService(ssMsg)
  439. }
  440. // 开启新赛季
  441. func (this *CrossManager) DoSeasonRefresh() {
  442. for _, chRole := range RoleMag.channelRoleList {
  443. if chRole.GetState() == ROLE_STATE_ONLINE ||
  444. chRole.GetState() == ROLE_STATE_OFFLINE {
  445. chRole.(*Role).GetRoleArena().DoSeasonRefresh()
  446. }
  447. }
  448. }