using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using ProtoCSStruct; namespace World { public static class RankSvc { private static long m_serverStartTime; private static long m_lastLoadDbReqTime; private static long m_lastSaveDbTime; private static long m_lastUpdateRankTime;// 更新排行榜里的玩家数据,5秒一次 //5秒后开始加载数据库,如果失败30秒后再次尝试 private static void TickLoadFromDb(long nowSecond) { if (RankUtils.IsLoadRankDataFromDbSuccess()) { return; } if (m_serverStartTime == 0) { m_serverStartTime = nowSecond; } if (nowSecond - m_serverStartTime > 5 && nowSecond - m_lastLoadDbReqTime > 30) { m_lastLoadDbReqTime = nowSecond; } } //private static void SaveRankRecord(WorldRankDataRecord record) //{ // if (record.NeedSave() == false) // { // return; // } // TraceLog.Trace("SaveRankRecord rankId {0} beginTime {1} dataSeq {2}", record.RankId, record.BeginTime, record.DataSeq); // ref SSSaveRankDbReq req = ref CSStructPool.Instance.GetObjRef(); // req.RankId = record.RankId; // req.BeginTime = record.BeginTime; // req.Data = record.Data; // req.DataSeq = record.DataSeq; // long nowMs = WorldServerUtils.GetTimeSecond() * 1000; // record.OnSaveReq(nowMs); // uint dbServerID = DBServerIDUtils.GetGameDBServerID(0); // WorldServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveRankDbReq, ref req, 0); //} private static void TickSaveRankData(long nowSecond) { //平时300秒保存一次,停服的时候5秒 long saveIntervalSecond = 300; if (WorldServerUtils.GetApp().CurrStopStage == ServerStopStage.stopping) { saveIntervalSecond = 5; } if (nowSecond - m_lastSaveDbTime <= saveIntervalSecond) { return; } m_lastSaveDbTime = nowSecond; WorldRankData rankData = WorldServerUtils.GetWorldRankData(); foreach (var rankItem in rankData.AllRank.Values) { } } public static void OnTick(long nowSecond) { TickLoadFromDb(nowSecond); if (!RankUtils.IsLoadRankDataFromDbSuccess()) { return; } TickRefreshRank(nowSecond); //更新排行榜里的玩家排名,有新的玩家数据的时候 TickUpdateRank(nowSecond); TickSaveRankData(nowSecond); } private static void TickRefreshRank(long nowSecond) { WorldRankData rankData = WorldServerUtils.GetWorldRankData(); foreach (var rankItem in rankData.AllRank.Values) { if (rankItem.CurRecord != null) { //TickRefreshCurRankRecord(nowSecond, rankItem.CurRecord, rankItem); } } } //private static void TickRefreshCurRankRecord(long nowSecond, WorldRankDataRecord record, WorldRankDataOne rankDataOne) //{ // var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId); // if (rankDesc == null) // { // return; // } // long newBeginTime = 0; // // 周榜 // if (rankDesc.refreshType == 1) // { // if (AppTime.IsSameWeek127(nowSecond, record.BeginTime)) // { // return; // } // newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond); // } // if (rankDesc.refreshType == 2) // { // if (AppTime.IsSameDay(nowSecond, record.BeginTime)) // { // return; // } // newBeginTime = AppTime.GetTodayStartTime(nowSecond); // } // if (record.Data.AwardTime != 0) // { // TraceLog.Error("TickRefreshRankRecord rankId {0} beginTime {1} already award at time {2}" // , record.RankId, record.BeginTime, record.Data.AwardTime); // return; // } // //刷新 // record.Data.AwardTime = nowSecond; // TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}" // , record.RankId, record.BeginTime, record.Data.AwardTime); // //替换老榜 // rankDataOne.LastRecord = record; // //rankDataOne.LastRecord.RankDict.Clear(); // rankDataOne.CurRecordMinScore = 0; //设置成0 // rankDataOne.NeedRankPlayers.Clear(); // //new 新榜 // rankDataOne.CurRecord = new WorldRankDataRecord(); // rankDataOne.CurRecord.RankId = rankDesc.rankId; // rankDataOne.CurRecord.BeginTime = newBeginTime; // rankDataOne.CurRecord.Data = new DBRankData(); // rankDataOne.CurRecord.Data.RankId = rankDesc.rankId; // //不清空老榜,直接复制数据,todo 加上清理的规则 // if (rankDesc.clearWhenRefresh == 0) // { // TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} clearWhenRefresh is 0, so copy old rank list" // , record.RankId, record.BeginTime); // for (int i = 0; i < record.Data.RankList.Count; i++) // { // rankDataOne.CurRecord.Data.RankList.Add(record.Data.RankList[i]); // } // for(int i =0;i< rankDataOne.CurRecord.Data.RankList.Count;i++) // { // rankDataOne.CurRecord.RankDict.Add(rankDataOne.CurRecord.Data.RankList[i].Uid, rankDataOne.CurRecord.Data.RankList[i]); // } // } // rankDataOne.CurRecord.MakeDirty(); // //发奖 // var awardDesc = RankAwardDescMgr.Instance.GetGroup(rankDesc.rankId); // if (awardDesc == null) // { // TraceLog.Trace("TickRefreshRankRecord rankId {0} no award config", record.RankId); // return; // } // int awardPlayerCount = 0; // foreach (var oneAward in awardDesc) // { // //遍历发邮件 // for (int i = oneAward.rankPosMin; i <= oneAward.rankPosMax; i++) // { // if (record.Data.RankList.Count < i || i <= 0) // { // continue; // } // DBRankPlayerInfo playerInfo = record.Data.RankList[i - 1]; // SendAwardMailToRankPlayer(playerInfo, oneAward, i); // awardPlayerCount++; // } // } // TraceLog.Debug("TickRefreshRankRecord rankId {0} beginTime {1} send award success, award player count {2}" // , record.RankId, record.BeginTime, awardPlayerCount); //} private static void AddOneItemToMail(DBMail mail, string itemid, int count) { TypeIDValueString item = new TypeIDValueString(); item.Type = (int) GoodsType.Items; item.Id = new FixedStructString64(itemid); item.Value = count; mail.AddGoods.Add(item); } /* private static void SendAwardMailToRankPlayer(DBRankPlayerInfo playerInfo, RankAwardDesc oneAward, int rankPos) { //给玩家发邮件,就是发奖品 DBMail mail = new DBMail(); mail.MailType = (int)MailType.Rank; mail.Uid = playerInfo.Uid; //var currency = new IDValue64() { Id = (long)CurrencyType.Chip, Value = oneAward.chip }; //mail.AddCurrency.Add(ref currency); //currency = new IDValue64() { Id = (long)CurrencyType.Diamond, Value = oneAward.diamond }; //mail.AddCurrency.Add(ref currency); //if (oneAward.itemid > 0 && oneAward.itemcount > 0) // { // AddOneItemToMail(mail, (uint)oneAward.itemid, oneAward.itemcount); // } // if (oneAward.itemid2 > 0 && oneAward.itemcount2 > 0) // { // AddOneItemToMail(mail, (uint)oneAward.itemid2, oneAward.itemcount2); // } //时间提前设置上,客户端可根据时间显示内容 mail.SendTime = WorldServerUtils.GetTimeSecond(); mail.Param1 = oneAward.rankId;//排行榜id mail.Param2 = rankPos;//第几名 MailSvc.SendMail(mail); TraceLog.Debug("RankSvc.SendAwardMailToRankPlayer send award mail to uid {0} rankId {1} rankPos {2}" , playerInfo.Uid, oneAward.rankId, rankPos); }*/ private static void TickUpdateRank(long nowSecond) { //1分钟一次 if (nowSecond - m_lastUpdateRankTime < 300) { return; } m_lastUpdateRankTime = nowSecond; WorldRankData rankData = WorldServerUtils.GetWorldRankData(); foreach (var rankItem in rankData.AllRank.Values) { if (rankItem.CurRecord != null) { TickUpdateRank(rankItem); } } } private static void TickUpdateRank(WorldRankDataOne rankOne) { if (rankOne.CurRecord == null) { return; } if (rankOne.NeedRankPlayers.Count == 0) { return; } int rankId = rankOne.CurRecord.RankId; RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId); if (rankDesc == null) { TraceLog.Error("RankSvc.TickUpdateRank rankId {0} not config desc", rankId); return; } //for (int i = 0; i < rankOne.CurRecord.Data.RankList.Count; i++) //{ // if (rankOne.NeedRankPlayers.ContainsKey(rankOne.CurRecord.Data.RankList[i].Uid) == false) // { // rankOne.NeedRankPlayers.Add(rankOne.CurRecord.Data.RankList[i].Uid, rankOne.CurRecord.Data.RankList[i]); // } //} //降序排序 IEnumerable query = from items in rankOne.NeedRankPlayers.Values orderby items.Score descending select items; //清空老数据 //rankOne.CurRecord.Data.RankList.Clear(); rankOne.CurRecord.RankDict.Clear(); int iCount = 0; long minScore = 0; foreach (var player in query) { //分数为0不排 if (player.Score > 0) { //rankOne.CurRecord.Data.RankList.Add(player); rankOne.CurRecord.RankDict.Add(player.Uid, player); iCount++; minScore = player.Score; } } //清空 rankOne.NeedRankPlayers.Clear(); rankOne.CurRecordMinScore = minScore; rankOne.CurRecord.MakeDirty(); rankOne.CurRecord.RankDataVersion++; TraceLog.Debug("RankSvc.TickUpdateRank sort new rank list rankId {0} count {1} minScore {2}" , rankId, iCount, minScore); } //玩家数据保存的时候更新排行榜 public static void OnPlayerDataSaveReq(DBRoleBase roleBase, DBRoleData roleData) { /*//数据没加载成功不处理 if (RankUtils.IsLoadRankDataFromDbSuccess() == false) { return; } WorldRankData rankData = WorldServerUtils.GetWorldRankData(); foreach (var rankItem in rankData.AllRank.Values) { if (rankItem.CurRecord != null) { int rankId = rankItem.CurRecord.RankId; RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId); if (rankDesc == null) { TraceLog.Error("RankSvc.OnPlayerDataSaveReq rankId {0} not config desc", rankId); continue; } long playerScore = 0; //赢取筹码 if (rankDesc.rankScoreType == 1) { playerScore = roleData.StatData.Weekly.WinChip; } else if (rankDesc.rankScoreType == 2) { //playerScore = roleData.StatData.Weekly.MatchArch; } else if (rankDesc.rankScoreType == 3) { playerScore = roleBase.Chip; } else if (rankDesc.rankScoreType == 4) { playerScore = roleData.StatData.Weekly.ReceiveFriendGift; } //先更新已经在排行榜里的玩家信息 //财富榜强制更新,因为分数会变小 if (playerScore >= rankItem.CurRecordMinScore || rankDesc.rankScoreType == 3) { //UpdateRolebaseInRankList(rankItem.CurRecord, roleBase, playerScore); } //有可能新进排行榜的,重复了也不管,直接加 //分数大于最低或者排行榜未满的时候有分 //不管如何,都排一下序算了,金钱榜的金钱会减少,不这么做有点问题 //if (playerScore > rankItem.CurRecordMinScore // || (playerScore > 0 && rankItem.CurRecord.Data.RankList.Count < rankDesc.listCount) // || (playerScore > 0 && rankDesc.rankScoreType == 3)) { AddPlayerToNeedRank(rankItem, roleBase, roleData, playerScore); } } }*/ } private static void AddPlayerToNeedRank(WorldRankDataOne oneRank, DBRoleBase roleBase, DBRoleData roleData, long score) { TraceLog.Trace("RankSvc.AddPlayerToNeedRank uid {0} rankId {1} score {2}", roleBase.Uid, oneRank.CurRecord.RankId, score); /*DBRankPlayerInfo rankPlayer; if (oneRank.NeedRankPlayers.ContainsKey(roleBase.Uid)) { rankPlayer = oneRank.NeedRankPlayers[roleBase.Uid]; } else { rankPlayer = new DBRankPlayerInfo(); oneRank.NeedRankPlayers.Add(roleBase.Uid, rankPlayer); } //更新数据 rankPlayer.Uid = roleBase.Uid; rankPlayer.Score = score; rankPlayer.Nick = roleBase.Nick; rankPlayer.Icon = roleBase.Icon; rankPlayer.Level = roleBase.Level; rankPlayer.Chip = roleBase.Chip; rankPlayer.Diamond = (int)roleBase.Diamond; rankPlayer.VipLevel = roleBase.VipLevel; rankPlayer.Gender = roleBase.Gender; rankPlayer.GameRound = (int)RankUtils.GetRoleTotalStatData(roleData, (int)CSRoleStatisticsID.TotalRound); rankPlayer.WinRound = (int)RankUtils.GetRoleTotalStatData(roleData, (int)CSRoleStatisticsID.TotalWin);*/ } //更新昵称和头像等信息 public static void UpdateRolebaseInAllRankList(DBRoleBase roleBase) { //数据没加载成功不处理 if (RankUtils.IsLoadRankDataFromDbSuccess() == false) { return; } WorldRankData rankData = WorldServerUtils.GetWorldRankData(); foreach (var rankItem in rankData.AllRank.Values) { if (rankItem.CurRecord != null) { if (rankItem.CurRecord.RankDict.ContainsKey(roleBase.Uid)) { DBRankPlayerInfo rankPlayer = rankItem.CurRecord.RankDict[roleBase.Uid]; rankPlayer.Level = roleBase.Level; rankPlayer.Nick = roleBase.Nick; rankPlayer.Icon = roleBase.Icon; TraceLog.Trace("UpdateRolebaseInRankList uid {0}", roleBase.Uid); } } } } //更新昵称和头像等信息 public static void UpdateRolebaseInRankList(WorldRankDataRecord record, DBRoleBase roleBase, long score) { if (record != null && record.RankDict.ContainsKey(roleBase.Uid)) { DBRankPlayerInfo rankPlayer = record.RankDict[roleBase.Uid]; rankPlayer.Level = roleBase.Level; rankPlayer.Nick = roleBase.Nick; rankPlayer.Icon = roleBase.Icon; rankPlayer.Score = score; TraceLog.Trace("UpdateRolebaseInRankList uid {0}", roleBase.Uid); } } } }