rank_tower.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. package model
  2. import (
  3. "encoding/base64"
  4. "rocommon"
  5. "rocommon/service"
  6. "rocommon/util"
  7. model2 "roserver/baseserver/model"
  8. "roserver/db/model"
  9. "roserver/serverproto"
  10. "strconv"
  11. "time"
  12. )
  13. //排名前3玩家uid列表
  14. const (
  15. TOWERRANK_TOP_50 = 50 //玩家可查看排名数量
  16. TOWERRANK_TOP_1000 = 1000 //最大排名数量
  17. TOWEFIGHT_RANK = 50 //每次更新50个到DB
  18. TOWERRANK_TOP_3 = 3 //玩家可查看排名数量
  19. )
  20. const RefreshTime = 5 * 1000
  21. const MailMaxUids = 50
  22. const (
  23. Rush_Tower_Rank_Rush = 1 //冲榜阶段
  24. Rush_Tower_Rank_Reward = 2 //领奖阶段
  25. Rush_Tower_Rank_End = 3 //结束
  26. )
  27. //爬塔战力信息
  28. type TowerFightInfo struct {
  29. Uid uint64
  30. FightPower int32
  31. TowerLevel int32
  32. ImgID int32
  33. }
  34. type TowerMinFight struct {
  35. TowerLevel int32
  36. Brief *serverproto.CommonPlayerBriefInfo
  37. }
  38. type TowerRankManger struct {
  39. TowerMinFightList map[int32]*serverproto.TowerBriefInfo
  40. TickTime uint64
  41. ChangeList map[int32]int32
  42. //冲榜数据
  43. RushId int32 //冲榜序号(第几次冲榜)
  44. RushStage int32 //冲榜阶段
  45. RewardList map[uint64]int32 //自己领奖则不再邮件发送
  46. RoundData []*serverproto.RushRoundData
  47. initRushTime bool
  48. }
  49. func newTowerRankManger() *TowerRankManger {
  50. mag := &TowerRankManger{
  51. TowerMinFightList: map[int32]*serverproto.TowerBriefInfo{},
  52. }
  53. mag.TickTime = 0
  54. mag.ChangeList = make(map[int32]int32)
  55. mag.initRushTime = false
  56. return mag
  57. }
  58. //1秒刷新
  59. func (this *TowerRankManger) Update(ms uint64) {
  60. if service.GetRedis() == nil {
  61. return
  62. }
  63. if this.TickTime == 0 {
  64. err := this.getTowerFightPowerFromRedis()
  65. if err != nil && err != service.NIL {
  66. util.ErrorF("[TowerRankManger] getTowerFightPowerFromRedis err:%v", err)
  67. return
  68. }
  69. err1 := this.loadRushTowerDataFromRedis()
  70. if err1 != nil && err1 != service.NIL {
  71. util.ErrorF("[TowerRankManger] loadRushTowerDataFromRedis err:%v", err1)
  72. return
  73. }
  74. this.TickTime = ms
  75. util.InfoF("[TowerRankManger] init success")
  76. //上线加载崇拜活动数据
  77. return
  78. }
  79. if this.TickTime != 0 && this.initRushTime == false {
  80. startUpTime := service.GetServiceStartupTime()
  81. if startUpTime > 0 {
  82. this.CheckAddInitRoundData()
  83. this.initRushTime = true
  84. }
  85. }
  86. //5秒中刷新
  87. if this.TickTime != 0 && this.TickTime+RefreshTime < ms {
  88. //写数据库
  89. this.SetTowerFightPowerToRedis()
  90. this.SwitchRushActivityState()
  91. this.TickTime = ms
  92. return
  93. }
  94. }
  95. func (this *TowerRankManger) CheckAddInitRoundData() {
  96. if this.RushId == 0 {
  97. return
  98. }
  99. for _, data := range this.RoundData {
  100. if data.RushId == this.RushId {
  101. return
  102. }
  103. }
  104. //初始化一下
  105. rankData := model2.GetRushActivityByRound(model2.Rush_Type_Tower, this.RushId)
  106. if rankData == nil {
  107. util.ErrorF("[TowerRankManger] CheckAddInitRoundData config not found error:curRushId", this.RushId)
  108. return
  109. }
  110. //判定开始时间是否已经过了。
  111. startTime := model2.GetRushActivityTimeStamp(rankData.StartDay, rankData.StartTime)
  112. closeTime := model2.GetRushActivityTimeStamp(rankData.CloseDay, rankData.CloseTime)
  113. resetTime := model2.GetRushActivityTimeStamp(rankData.RestDay, rankData.RestTime)
  114. this.RoundData = append(this.RoundData, &serverproto.RushRoundData{
  115. RushId: this.RushId,
  116. StartTime: startTime,
  117. CloseTime: closeTime,
  118. ResetTime: resetTime,
  119. })
  120. util.InfoF("[TowerRankManger] init time: %v - %v - %v, this.RoundData :%v", startTime, closeTime, resetTime, this.RoundData)
  121. this.saveRushTowerDataToRedis()
  122. }
  123. func (this *TowerRankManger) getTowerFightPowerFromRedis() error {
  124. keyStr := model2.TowerFightpowerRankPrefix
  125. valueStr, err := service.GetRedis().HGetAll(keyStr).Result()
  126. if err != nil {
  127. util.InfoF("getTowerFightPowerFromRedis get keyStr=%v err=%v", keyStr, err)
  128. return err
  129. }
  130. util.InfoF("getTowerFightPowerFromRedis --------- get keyStr=%v err=%v", keyStr, err)
  131. for towerLevel, towerValue := range valueStr {
  132. val, _ := model2.Str2Num(towerLevel)
  133. msgStr, err := base64.StdEncoding.DecodeString(towerValue)
  134. if err != nil {
  135. util.InfoF("getTowerFightPowerFromRedis level=%v err=%v", towerLevel, err)
  136. continue
  137. }
  138. tower := &serverproto.TowerBriefInfo{}
  139. err = rocommon.GetCodec().Unmarshal(msgStr, tower)
  140. if err == nil {
  141. this.TowerMinFightList[int32(val)] = tower
  142. } else {
  143. return err
  144. }
  145. }
  146. //util.DebugF("getTowerFightPowerFromRedis TowerMinFightList=%v", this.TowerMinFightList)
  147. return nil
  148. }
  149. func (this *TowerRankManger) SetTowerFightPowerToRedis() {
  150. if len(this.ChangeList) <= 0 {
  151. return
  152. }
  153. var count int = 0
  154. for towerLevel, _ := range this.ChangeList {
  155. if count >= TOWEFIGHT_RANK {
  156. break
  157. }
  158. data, ok := this.TowerMinFightList[towerLevel]
  159. if !ok {
  160. continue
  161. }
  162. fieldStr := strconv.FormatUint(uint64(towerLevel), 10)
  163. keyStr := model2.TowerFightpowerRankPrefix
  164. msgData, err := rocommon.GetCodec().Marshal(data)
  165. if err != nil {
  166. util.InfoF("[SetTowerFightPowerToRedis] Marshal err:%v %v %s", err, fieldStr, msgData)
  167. continue
  168. }
  169. msgStr := base64.StdEncoding.EncodeToString(msgData.([]byte))
  170. ret, err := service.GetRedis().HSet(keyStr, fieldStr, msgStr).Result()
  171. if err != nil {
  172. util.InfoF("[SetTowerFightPowerToRedis] err:%v %v", err, ret)
  173. continue
  174. }
  175. delete(this.ChangeList, towerLevel)
  176. count++
  177. }
  178. return
  179. }
  180. func (this *TowerRankManger) AddMinFightListGM(brief *serverproto.TowerBriefInfo) bool {
  181. for i := 1; i <= int(brief.CommonInfo.TowerLevel); i++ {
  182. bDirty := false
  183. if this.TowerMinFightList == nil {
  184. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  185. bDirty = true
  186. } else {
  187. data, ok := this.TowerMinFightList[brief.CommonInfo.TowerLevel]
  188. if !ok {
  189. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  190. util.DebugF("[AddMinFightList] GM add new level fight brief:%s", brief)
  191. bDirty = true
  192. } else {
  193. //传进来的战力更小
  194. if data.CommonInfo.FightPower > brief.CommonInfo.FightPower {
  195. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  196. util.DebugF("[AddMinFightList] GM change new level fight brief:%s", brief)
  197. bDirty = true
  198. }
  199. }
  200. }
  201. if bDirty == true {
  202. this.ChangeList[brief.CommonInfo.TowerLevel] = 1
  203. }
  204. }
  205. return true
  206. }
  207. func (this *TowerRankManger) AddMinFightList(brief *serverproto.TowerBriefInfo) bool {
  208. //为零怎么可能发送过来?真是奇怪了
  209. var oldRecordId uint64 = 0
  210. bDirty := false
  211. if this.TowerMinFightList == nil {
  212. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  213. bDirty = true
  214. } else {
  215. data, ok := this.TowerMinFightList[brief.CommonInfo.TowerLevel]
  216. if !ok {
  217. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  218. util.DebugF("[AddMinFightList] add new level fight brief:%s", brief)
  219. bDirty = true
  220. } else {
  221. //传进来的战力更小
  222. if data.CommonInfo.FightPower > brief.CommonInfo.FightPower || brief.BattleVersion > data.BattleVersion {
  223. oldRecordId = data.CommonInfo.BattleRecordId
  224. this.TowerMinFightList[brief.CommonInfo.TowerLevel] = brief
  225. util.DebugF("[AddMinFightList] change new level fight brief:%s", brief)
  226. bDirty = true
  227. }
  228. }
  229. }
  230. if bDirty == true {
  231. this.ChangeList[brief.CommonInfo.TowerLevel] = 1
  232. //战报处理
  233. if oldRecordId > 0 {
  234. oldRecordIdStr := strconv.FormatUint(oldRecordId, 10)
  235. service.GetRedis().Expire(model2.BattleRecordDetailPrefix+oldRecordIdStr, time.Minute*1)
  236. }
  237. if brief.CommonInfo.BattleRecordId > 0 {
  238. service.GetRedis().SAdd(model2.BattleRecordDetailCheckPrefix, brief.CommonInfo.BattleRecordId)
  239. }
  240. return true
  241. }
  242. return false
  243. }
  244. func (this *TowerRankManger) GetMinFightList(towerLevel int32, ackMsg *serverproto.SSTowerMinFightPowerAck) {
  245. if len(this.TowerMinFightList) <= 0 {
  246. return
  247. }
  248. data, ok := this.TowerMinFightList[towerLevel]
  249. if ok {
  250. info := &serverproto.TowerMinFight{
  251. FightPower: data.CommonInfo.FightPower,
  252. Infos: data.CommonInfo,
  253. BattleTime: uint32(data.BattleTime),
  254. RecordTime: data.CommonInfo.TowerTime,
  255. BattleVersion: data.BattleVersion,
  256. }
  257. ackMsg.TowerInfo = append(ackMsg.TowerInfo, info)
  258. }
  259. }
  260. //passTime 传进来的是秒。所以32位够用。以防万一就用48位,所以还要判定下0xffffffffffff > passTime
  261. func (this *TowerRankManger) GetTowerRankScore(val uint64, passTime uint64) uint64 {
  262. //score
  263. var scoreStr = val
  264. if scoreStr >= (1 << 16) {
  265. scoreStr = (1 << 16) - 1
  266. }
  267. scoreStr <<= 48
  268. if 0xffffffffffff > passTime {
  269. scoreStr |= 0xffffffffffff - passTime //通关先到的passTime越小。取反则越大,相同关卡则排在前
  270. } else {
  271. scoreStr |= 1
  272. }
  273. return scoreStr
  274. }
  275. //全服爬塔排名逻辑
  276. func (this *TowerRankManger) AddTowerLevelRank(brief *serverproto.CommonPlayerBriefInfo) uint32 {
  277. //score
  278. scoreStr := getTowerScore(uint64(brief.TowerLevel), brief.TowerTime)
  279. //uid
  280. keyStr := strconv.FormatUint(brief.Uid, 10)
  281. _, err := service.GetRedis().ZAdd(model2.TowerLevelRankPrefix, service.BaseZ{Score: float64(scoreStr), Member: keyStr}).Result()
  282. if err != nil {
  283. util.ErrorF("[AddTowerLevelRank] err:%v uid:%v", err, brief.Uid)
  284. return 0
  285. }
  286. selfRank, err2 := service.GetRedis().ZRevRank(model2.TowerLevelRankPrefix, keyStr).Result()
  287. if err2 != nil {
  288. util.DebugF("[AddTowerLevelRank] selfRank err:%v", err2)
  289. return 0
  290. }
  291. util.DebugF("[AddTowerLevelRank] selfRank:%v", selfRank+1)
  292. //超过1000人的情况
  293. rankListCount, err1 := service.GetRedis().ZCard(model2.TowerLevelRankPrefix).Result()
  294. if err1 != nil {
  295. util.DebugF("[getTowerRankList] totalRanks err:%v", err1)
  296. return uint32(selfRank)
  297. }
  298. if rankListCount > TOWERRANK_TOP_1000 {
  299. count := rankListCount - TOWERRANK_TOP_1000
  300. for i := 0; i < int(count); i++ {
  301. _, err := service.GetRedis().ZRemRangeByRank(model2.TowerLevelRankPrefix, 0, 0).Result()
  302. if err != nil {
  303. util.ErrorF("[AddTowerScoreRank] remove top rank err:%v uid:%v", err)
  304. break
  305. }
  306. }
  307. }
  308. return uint32(selfRank + 1)
  309. }
  310. func (this *TowerRankManger) GetTopTowerRank(uid uint64, ackMsg *serverproto.SSPassTowerLevelRankAck) int32 {
  311. if ackMsg == nil {
  312. return 0
  313. }
  314. topListWithScore, err3 := service.GetRedis().ZRevRangeWithScores(model2.TowerLevelRankPrefix, 0, TOWERRANK_TOP_50-1).Result()
  315. if err3 == nil {
  316. for index, _ := range topListWithScore {
  317. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  318. // _, _, TowerLevel := getValByRankScore(topListWithScore[index].Score)
  319. info := &serverproto.TowerLevelInfo{
  320. Rank: int32(index + 1),
  321. Uid: rankUid,
  322. }
  323. ackMsg.TowerInfo = append(ackMsg.TowerInfo, info)
  324. }
  325. //获取自己的排名
  326. keyStr := strconv.FormatUint(uid, 10)
  327. selfRank, err4 := service.GetRedis().ZRevRank(model2.TowerLevelRankPrefix, keyStr).Result()
  328. if err4 != nil {
  329. util.DebugF("[GetTopTowerRank] selfRank err:%v", err4)
  330. return 0
  331. }
  332. ackMsg.SelfRank = int32(selfRank + 1)
  333. return int32(selfRank)
  334. }
  335. return 0
  336. }
  337. //================================================= 爬塔冲榜 =================================================
  338. //加载赛季数据
  339. func (this *TowerRankManger) loadRushTowerDataFromRedis() error {
  340. keyStr := model2.RushTowerPrefix
  341. ret, err := service.GetRedis().Get(keyStr).Result()
  342. if err != nil {
  343. util.InfoF("LoadTowerData get guildId key=%v err=%v\n", keyStr, err)
  344. return err
  345. }
  346. if ret == "" {
  347. util.InfoF("key(%v)->val empty", keyStr)
  348. return err
  349. }
  350. str, err := base64.StdEncoding.DecodeString(ret)
  351. if err != nil {
  352. util.InfoF("key(%v)->val DecodeString error", keyStr)
  353. return err
  354. }
  355. rushData := &serverproto.RushData{}
  356. err = rocommon.GetCodec().Unmarshal(str, rushData)
  357. if err == nil {
  358. this.RushId = rushData.RushId
  359. this.RushStage = rushData.RushStage
  360. this.RewardList = make(map[uint64]int32)
  361. this.RoundData = rushData.RoundData
  362. if len(rushData.RewardList) > 0 {
  363. for _, data := range rushData.RewardList {
  364. this.RewardList[data] = 1
  365. }
  366. }
  367. util.InfoF("LoadTowerData success:%v", rushData)
  368. return nil
  369. }
  370. util.InfoF("LoadTowerData failed")
  371. return err
  372. }
  373. func (this *TowerRankManger) saveRushTowerDataToRedis() {
  374. keyStr := model2.RushTowerPrefix
  375. rushData := &serverproto.RushData{
  376. RushId: this.RushId,
  377. RushStage: this.RushStage,
  378. RoundData: this.RoundData,
  379. }
  380. for key, _ := range this.RewardList {
  381. rushData.RewardList = append(rushData.RewardList, key)
  382. }
  383. msgData, err := rocommon.GetCodec().Marshal(rushData)
  384. if err != nil {
  385. return
  386. }
  387. msgStr := base64.StdEncoding.EncodeToString(msgData.([]byte))
  388. ret, err := service.GetRedis().Set(keyStr, msgStr, 0).Result()
  389. if err != nil {
  390. util.InfoF("SaveTowerData err=%v ret=%v", keyStr, ret)
  391. return
  392. }
  393. util.InfoF("SaveTowerData save rushData sucess : %v", rushData)
  394. }
  395. //当前是否有冲榜活动
  396. func (this *TowerRankManger) CheckInRushActivity() bool {
  397. if this.RushId == 0 || (this.RushId != 0 && this.RushStage == int32(Rush_Tower_Rank_End)) {
  398. return false
  399. }
  400. return true
  401. }
  402. //是否有新的冲榜开启
  403. func (this *TowerRankManger) CheckNewRushActivity() {
  404. //如果在活动内,不做处理
  405. if this.RushId != 0 && this.RushStage != int32(Rush_Tower_Rank_End) {
  406. return
  407. }
  408. //配置有问题
  409. rankData := model2.GetRushActivityByRound(model2.Rush_Type_Tower, this.RushId+1)
  410. if rankData == nil {
  411. return
  412. }
  413. curTime := util.GetCurrentTime()
  414. bFind := false
  415. for _, data := range this.RoundData {
  416. if data.RushId == this.RushId+1 {
  417. bFind = true
  418. if data.StartTime <= curTime {
  419. this.RushId = this.RushId + 1
  420. this.RushStage = Rush_Tower_Rank_Rush
  421. this.RewardList = make(map[uint64]int32)
  422. this.saveRushTowerDataToRedis()
  423. util.InfoF("start new rushTower this.RoundData:%v, ", data)
  424. }
  425. return
  426. }
  427. }
  428. if bFind == false {
  429. //判定开始时间是否已经过了。
  430. startTime := model2.GetRushActivityTimeStamp(rankData.StartDay, rankData.StartTime)
  431. closeTime := model2.GetRushActivityTimeStamp(rankData.CloseDay, rankData.CloseTime)
  432. resetTime := model2.GetRushActivityTimeStamp(rankData.RestDay, rankData.RestTime)
  433. //如果当前时间 >= startTime 则,设定开启时间 return
  434. newStartTime := startTime
  435. newCloseTime := closeTime
  436. newResetTime := resetTime
  437. //计算今天的开启时间//超过今天的开启时间,则开启时间定为第二天的开启时间
  438. loc := util.GetLoc()
  439. todayStartHour := util.GetLatest5Hour() - 24*3600*1000
  440. startServer := time.Unix(int64(todayStartHour/1000), 0).In(loc).Format(util.DATE_FORMAT1)
  441. startUpDayStr := util.GetDayByTimeStr1(startServer)
  442. todayRushBegin := util.GetTimeByStr(startUpDayStr.Format(util.DATE_FORMAT1) + " " + rankData.StartTime)
  443. todayRushStart := time.Unix(todayRushBegin.Unix(), 0).In(loc)
  444. todayRushTime := uint64(todayRushStart.UnixNano() / 1e6)
  445. //已经过了开服时间,才需要顺延。正常不需要顺延
  446. if startTime < curTime {
  447. if curTime <= todayRushTime {
  448. newStartTime = todayRushTime
  449. } else {
  450. newStartTime = todayRushTime + 24*3600*1000
  451. }
  452. newCloseTime = newStartTime + (closeTime - startTime)
  453. newResetTime = newStartTime + (resetTime - startTime)
  454. }
  455. //重置数据
  456. this.RoundData = append(this.RoundData, &serverproto.RushRoundData{
  457. RushId: this.RushId + 1,
  458. StartTime: newStartTime,
  459. CloseTime: newCloseTime,
  460. ResetTime: newResetTime,
  461. })
  462. util.InfoF("init next rushTower newStartTime:%v, newCloseTime:%v, newResetTime:%v, serverStart:%s", newStartTime, newCloseTime, newResetTime, startUpDayStr)
  463. this.saveRushTowerDataToRedis()
  464. }
  465. }
  466. func (this *TowerRankManger) GetRoundTime(rushId int32) (uint64, uint64, uint64) {
  467. for _, data := range this.RoundData {
  468. if data.RushId == rushId {
  469. return data.StartTime, data.CloseTime, data.ResetTime
  470. }
  471. }
  472. return 0, 0, 0
  473. }
  474. //是否冲榜状态更新
  475. func (this *TowerRankManger) SwitchRushActivityState() {
  476. if this.CheckInRushActivity() == false {
  477. this.CheckNewRushActivity()
  478. return
  479. }
  480. //活动结束。且又没有新的赛季直接返回
  481. if this.RushId == 0 || this.RushStage == int32(Rush_Tower_Rank_End) {
  482. return
  483. }
  484. //切换状态
  485. curTime := util.GetCurrentTime()
  486. _, closeTime, resetTime := this.GetRoundTime(this.RushId)
  487. if closeTime == 0 || resetTime == 0 {
  488. util.ErrorF("TimeError : closeTime:%v, resetTime:%v, curTime:%v, this.RushId:%v", closeTime, resetTime, curTime, this.RushId)
  489. return
  490. }
  491. //找到活动,说明还在活动内
  492. if closeTime < curTime && curTime <= resetTime {
  493. if this.RushStage < Rush_Tower_Rank_Reward {
  494. //进入领奖阶段,备份排行榜单
  495. this.backUpTowerRankData()
  496. this.RushStage = Rush_Tower_Rank_Reward
  497. this.saveRushTowerDataToRedis()
  498. }
  499. } else if curTime > resetTime {
  500. //未找到,备份数据。直接结束活动
  501. if this.RushStage == Rush_Tower_Rank_Rush || this.RushStage == Rush_Tower_Rank_Reward {
  502. //活动结束了,则备份榜单。函数本身已经判定Key是否存在
  503. this.backUpTowerRankData()
  504. //发送未领取的排行版邮件
  505. this.SendRushTowerReward()
  506. this.RushStage = Rush_Tower_Rank_End
  507. this.saveRushTowerDataToRedis()
  508. }
  509. }
  510. }
  511. //备份爬塔数据
  512. func (this *TowerRankManger) backUpTowerRankData() {
  513. roundStr := strconv.Itoa(int(this.RushId))
  514. prefixStr := model2.RushTowerRankPrefix + roundStr
  515. if !model2.ExistKey(prefixStr) {
  516. _, err := service.GetRedis().ZUnionStore(prefixStr, service.BaseStore{}, model2.TowerLevelRankPrefix).Result()
  517. if err != nil {
  518. util.ErrorF("backUpTowerRankData store rank record err=%v prefixStr=%v", err, prefixStr)
  519. return
  520. }
  521. }
  522. }
  523. func (this *TowerRankManger) GetSelfRushRank(uid uint64, rushId int32) (int32, int32) {
  524. //从爬塔榜单上取数据
  525. if this.RushStage == Rush_Tower_Rank_Rush {
  526. keyStr := strconv.FormatUint(uid, 10)
  527. selfRank, rankErr := service.GetRedis().ZRevRank(model2.TowerLevelRankPrefix, keyStr).Result()
  528. if rankErr == nil && rankErr != service.NIL {
  529. topListWithScore, err3 := service.GetRedis().ZRevRangeWithScores(model2.TowerLevelRankPrefix, selfRank, selfRank).Result()
  530. if err3 == nil {
  531. for index, _ := range topListWithScore {
  532. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  533. if rankUid == uid {
  534. _, _, towerLevel := getValByTowerScore(topListWithScore[index].Score)
  535. return int32(selfRank + 1), int32(towerLevel)
  536. }
  537. }
  538. } else {
  539. util.DebugF("[GetTopTowerRank] selfRank err:%v", err3)
  540. }
  541. }
  542. } else {
  543. rushRound := this.RushId
  544. if rushId != 0 {
  545. rushRound = rushId
  546. }
  547. roundStr := strconv.Itoa(int(rushRound))
  548. prefixStr := model2.RushTowerRankPrefix + roundStr
  549. keyStr := strconv.FormatUint(uid, 10)
  550. selfRank, rankErr := service.GetRedis().ZRevRank(prefixStr, keyStr).Result()
  551. if rankErr == nil && rankErr != service.NIL {
  552. topListWithScore, err3 := service.GetRedis().ZRevRangeWithScores(prefixStr, selfRank, selfRank).Result()
  553. if err3 == nil {
  554. for index, _ := range topListWithScore {
  555. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  556. if rankUid == uid {
  557. _, _, towerLevel := getValByTowerScore(topListWithScore[index].Score)
  558. return int32(selfRank + 1), int32(towerLevel)
  559. }
  560. }
  561. } else {
  562. util.DebugF("[GetTopTowerRank] selfRank err:%v", err3)
  563. }
  564. }
  565. }
  566. return 0, 0
  567. }
  568. func (this *TowerRankManger) GetCurrentRushActivity() *model2.RankList {
  569. curRushId := int32(0)
  570. if Rush_Tower_Rank_Rush <= this.RushStage && this.RushStage < Rush_Tower_Rank_End {
  571. curRushId = this.RushId
  572. if curRushId == 0 {
  573. return nil
  574. }
  575. }
  576. return model2.GetRushActivityByRound(model2.Rush_Type_Tower, curRushId)
  577. }
  578. func (this *TowerRankManger) GetRewardLevel(rank int32) *model2.RewardRank {
  579. rankData := this.GetCurrentRushActivity()
  580. if rankData == nil {
  581. return nil
  582. }
  583. for _, data := range rankData.Reward {
  584. if data.RankBegin <= rank && rank <= data.RankEnd {
  585. return data
  586. }
  587. }
  588. return nil
  589. }
  590. func (this *TowerRankManger) SendRushTowerReward() {
  591. rankData := model2.GetRushActivityByRound(model2.Rush_Type_Tower, this.RushId)
  592. if rankData == nil {
  593. return
  594. }
  595. //发送邮件奖励
  596. roundStr := strconv.Itoa(int(this.RushId))
  597. prefixStr := model2.RushTowerRankPrefix + roundStr
  598. topListWithScore, err3 := service.GetRedis().ZRevRangeWithScores(prefixStr, 0, TOWERRANK_TOP_1000-1).Result()
  599. if err3 == nil {
  600. ntfMsg := &serverproto.SSRushActivityRankRewardNtf{
  601. MailCfgId: model2.GlobalMailIdRushTower,
  602. MailType: int32(serverproto.MailType_MailType_RushTower),
  603. RushRound: this.RushId,
  604. }
  605. for index, _ := range topListWithScore {
  606. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  607. realRank := int32(index + 1)
  608. Uid := rankUid
  609. mailData := &serverproto.RushMailData{
  610. Uid: Uid,
  611. }
  612. bFind := false
  613. for _, data := range rankData.Reward {
  614. if data.RankBegin <= realRank && realRank <= data.RankEnd {
  615. mailData.MailParamList = append(mailData.MailParamList, realRank)
  616. mailData.MailParamList = append(mailData.MailParamList, data.RankLevel)
  617. mailData.RewardList = data.RewardList
  618. bFind = true
  619. break
  620. }
  621. }
  622. if !bFind { //没有排名奖励
  623. continue
  624. }
  625. ntfMsg.MailData = append(ntfMsg.MailData, mailData)
  626. if len(ntfMsg.MailData) >= MailMaxUids {
  627. SendToAllGame(ntfMsg)
  628. ntfMsg.MailData = ntfMsg.MailData[0:0]
  629. }
  630. }
  631. if len(ntfMsg.MailData) >= 1 {
  632. SendToAllGame(ntfMsg)
  633. }
  634. }
  635. }
  636. //打包冲榜信息给客户端
  637. func (this *TowerRankManger) GetCurRushInfo(rushTowerData *serverproto.RushActivityData) {
  638. if rushTowerData == nil {
  639. return
  640. }
  641. if this.CheckInRushActivity() == false {
  642. rushTowerData.InRush = false
  643. bFind := false
  644. for _, data := range this.RoundData {
  645. if data.RushId == this.RushId+1 {
  646. rushTowerData.NextRush = data.StartTime
  647. bFind = true
  648. break
  649. }
  650. }
  651. if bFind == false {
  652. rushTowerData.NextRush = 0
  653. }
  654. return
  655. }
  656. rankData := this.GetCurrentRushActivity()
  657. if rankData == nil {
  658. util.ErrorF("tower config not found %v", this.RushId)
  659. return
  660. }
  661. rushTowerData.InRush = true
  662. rushTowerData.Stage = this.RushStage
  663. rushTowerData.RushCount = rankData.RankRound
  664. _, closeTime, resetTime := this.GetRoundTime(this.RushId)
  665. if this.RushStage == Rush_Tower_Rank_Rush {
  666. rushTowerData.StageEnd = closeTime //model2.GetRushActivityTimeStamp(rankData.CloseDay, rankData.CloseTime)
  667. } else {
  668. rushTowerData.StageEnd = resetTime //model2.GetRushActivityTimeStamp(rankData.RestDay, rankData.RestTime)
  669. }
  670. }
  671. func (this *TowerRankManger) GetTop3RushTowerData(rankData *model2.RankList, ackMsg *serverproto.SSGetRushDataAck) int32 {
  672. //从爬塔榜单上取数据
  673. for _, data := range rankData.Reward {
  674. if this.RushStage == Rush_Tower_Rank_Rush {
  675. topListWithScore, err := service.GetRedis().ZRevRangeWithScores(model2.TowerLevelRankPrefix, int64(data.RankEnd-1), int64(data.RankEnd-1)).Result()
  676. if err == nil {
  677. for index, _ := range topListWithScore {
  678. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  679. _, _, level := getValByTowerScore(topListWithScore[index].Score)
  680. brief := &serverproto.CommonPlayerBriefInfo{}
  681. err2 := model.GetSystemDataFromRedis(model.RolePlayerBriefPrefix, rankUid, brief)
  682. if err2 != nil {
  683. continue
  684. }
  685. top3 := &serverproto.RushRankTop3{
  686. Name: brief.NickName,
  687. Rank: int32(data.RankEnd),
  688. Data: int32(level),
  689. }
  690. ackMsg.TopData = append(ackMsg.TopData, top3)
  691. }
  692. }
  693. } else if this.RushStage == Rush_Tower_Rank_Reward {
  694. roundStr := strconv.Itoa(int(this.RushId))
  695. prefixStr := model2.RushTowerRankPrefix + roundStr
  696. topListWithScore, err3 := service.GetRedis().ZRevRangeWithScores(prefixStr, int64(data.RankEnd-1), int64(data.RankEnd-1)).Result()
  697. if err3 == nil {
  698. for index, _ := range topListWithScore {
  699. rankUid, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64)
  700. _, _, level := getValByTowerScore(topListWithScore[index].Score)
  701. brief := &serverproto.CommonPlayerBriefInfo{}
  702. err2 := model.GetSystemDataFromRedis(model.RolePlayerBriefPrefix, rankUid, brief)
  703. if err2 != nil {
  704. continue
  705. }
  706. top3 := &serverproto.RushRankTop3{
  707. Name: brief.NickName,
  708. Rank: int32(data.RankEnd),
  709. Data: int32(level),
  710. }
  711. ackMsg.TopData = append(ackMsg.TopData, top3)
  712. }
  713. }
  714. }
  715. }
  716. return 0
  717. }
  718. func (this *TowerRankManger) GetSelfRushData(ackMsg *serverproto.SSGetRushDataAck) {
  719. if ackMsg == nil {
  720. return
  721. }
  722. rankData := this.GetCurrentRushActivity()
  723. if rankData == nil {
  724. util.ErrorF("tower config not found %v", this.RushId)
  725. return
  726. }
  727. ackMsg.CurRushRound = this.RushId
  728. ackMsg.SelfRank, ackMsg.SelfLevel = this.GetSelfRushRank(ackMsg.Uid, 0)
  729. _, closeTime, resetTime := this.GetRoundTime(this.RushId)
  730. if this.RushStage == Rush_Tower_Rank_Rush {
  731. ackMsg.EndTime = closeTime //model2.GetRushActivityTimeStamp(rankData.CloseDay, rankData.CloseTime)
  732. } else {
  733. ackMsg.EndTime = resetTime //model2.GetRushActivityTimeStamp(rankData.RestDay, rankData.RestTime)
  734. }
  735. this.GetTop3RushTowerData(rankData, ackMsg)
  736. }
  737. func (this *TowerRankManger) CheckRushTowerAddScore(ackMsg *serverproto.SSRushDataChangeAck) {
  738. if ackMsg == nil {
  739. return
  740. }
  741. if this.RushStage == Rush_Tower_Rank_Rush {
  742. ackMsg.RushRound = this.RushId
  743. return
  744. }
  745. ackMsg.RushRound = 0
  746. }
  747. func (this *TowerRankManger) GetRushTowerReward(ackMsg *serverproto.SSGetRushRewardAck, rewardType int32) {
  748. if rewardType == model2.Rush_Reward_Type_FightCount {
  749. this.GetRushTowerBaseReward(ackMsg)
  750. } else if rewardType == model2.Rush_Reward_Type_Rank {
  751. this.GetRushTowerRankReward(ackMsg)
  752. }
  753. }
  754. func (this *TowerRankManger) GetRushTowerBaseReward(ackMsg *serverproto.SSGetRushRewardAck) {
  755. if ackMsg == nil {
  756. return
  757. }
  758. rankData := this.GetCurrentRushActivity()
  759. if rankData == nil {
  760. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_RUSH_ACTIVITY_REWARD_FINISH)
  761. return
  762. }
  763. if this.RushStage != Rush_Tower_Rank_Reward && this.RushStage != Rush_Tower_Rank_Rush {
  764. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_FAIL)
  765. return
  766. }
  767. ackMsg.RushRound = this.RushId
  768. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_OK)
  769. }
  770. func (this *TowerRankManger) GetRushTowerRankReward(ackMsg *serverproto.SSGetRushRewardAck) {
  771. if ackMsg == nil {
  772. return
  773. }
  774. rankData := this.GetCurrentRushActivity()
  775. if rankData == nil {
  776. ackMsg.Error = int32(serverproto.ErrorCode_ERROR_RUSH_ACTIVITY_REWARD_FINISH)
  777. return
  778. }
  779. if this.RushStage != Rush_Tower_Rank_Reward {
  780. return
  781. }
  782. rank, _ := this.GetSelfRushRank(ackMsg.Uid, 0)
  783. if rank == 0 {
  784. return
  785. }
  786. ackMsg.RushRound = this.RushId
  787. for _, data := range rankData.Reward {
  788. if data.RankBegin <= rank && rank <= data.RankEnd {
  789. for _, item := range data.RewardList {
  790. ackMsg.ItemList = append(ackMsg.ItemList, &serverproto.KeyValueType{
  791. Key: item.Key,
  792. Value: item.Value,
  793. })
  794. }
  795. break
  796. }
  797. }
  798. }
  799. func (this *TowerRankManger) GetRushInfo() (int32, int32) {
  800. if this.RushId == 0 || this.RushStage == Rush_Tower_Rank_End {
  801. return Rush_Tower_Rank_End, 0
  802. }
  803. return this.RushStage, this.RushId
  804. }
  805. func (this *TowerRankManger) GetRushBaseReward(uid uint64, rushRound int32, ackMsg *serverproto.SSGetRushBaseRewardAck) {
  806. ackMsg.Reward = false
  807. if this.RushId > rushRound {
  808. ackMsg.Reward = true
  809. ackMsg.RewardRound = rushRound
  810. return
  811. }
  812. //整个活动已经结束了
  813. if this.RushId > rushRound || (this.RushId == rushRound && this.RushStage == Rush_Tower_Rank_End) {
  814. ackMsg.Reward = true
  815. ackMsg.RewardRound = rushRound
  816. }
  817. }
  818. func (this *TowerRankManger) GetRushReward(uid uint64, rankRound int32, ackMsg *serverproto.RankRewardList) {
  819. finishRound := this.RushId
  820. if this.RushStage < Rush_Tower_Rank_End {
  821. finishRound = this.RushId - 1
  822. }
  823. if finishRound <= 0 || finishRound <= rankRound {
  824. return
  825. }
  826. ackMsg.FinishRound = finishRound
  827. for round := rankRound + 1; round <= finishRound; round++ {
  828. selfRank, _ := this.GetSelfRushRank(uid, round)
  829. if selfRank == 0 {
  830. return
  831. }
  832. rankData := model2.GetRushActivityByRound(model2.Rush_Type_Tower, round)
  833. if rankData == nil {
  834. return
  835. }
  836. rankRewardData := &serverproto.RankRewardData{
  837. RushRound: round,
  838. }
  839. rankRewardData.MailParamList = append(rankRewardData.MailParamList, selfRank)
  840. for _, data := range rankData.Reward {
  841. if data.RankBegin <= selfRank && selfRank <= data.RankEnd {
  842. for _, item := range data.RewardList {
  843. rankRewardData.RewardList = append(rankRewardData.RewardList, &serverproto.KeyValueType{
  844. Key: item.Key,
  845. Value: item.Value,
  846. })
  847. }
  848. rankRewardData.MailParamList = append(rankRewardData.MailParamList, data.RankLevel)
  849. break
  850. }
  851. }
  852. ackMsg.RankReward = append(ackMsg.RankReward, rankRewardData)
  853. }
  854. }