using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using ProtoCSStruct; using System.Security.Cryptography; using System.IO; using System.Reflection; using Sog.Log; using Org.BouncyCastle.Bcpg; namespace Rank { public static class RankSvc { private static long lastTickTime = 0; private static readonly int HideRankTimeGap = 3 * 86400; // 延迟发送排名奖励的时间 private static readonly int DelaySendRankRewardTime = 3600; public static int GMRewardRankId = 0; public static int GMRewardTime = 0; public static void OnTick(long nowSecond) { TickLoadRankFromDb(nowSecond); TickRefreshRank(nowSecond); //更新排行榜里的玩家排名,有新的玩家数据的时候 TickUpdateRank(nowSecond); // if (nowSecond >= lastTickTime + 60) // { // lastTickTime = nowSecond; // TickActivityRank(nowSecond); // } TickSaveRankData(nowSecond); TickClearActRankData(nowSecond); } public static void On10secondTick(long nowSecond) { TickSaveActRankData(nowSecond); } public static bool CheckCanStop() { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realIdItem in rankData.AllRank.Values) { if (!realIdItem.m_loadDbDataSuccess) { continue; } foreach (var rankItem in realIdItem.m_rankMap.Values) { if (rankItem.CurRecord != null) { if (rankItem.CurRecord.IsDirty() || rankItem.CurRecord.NeedUpdate) { TraceLog.Debug("RankSvc.CheckCanStop realm {0} rank {1} dirty {2}", rankItem.RealmId, rankItem.RankID, rankItem.CurRecord.NeedUpdate); return false; } } } } return true; } private static void TickRefreshRank(long nowSecond) { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realIdItem in rankData.AllRank.Values) { foreach (var rankItem in realIdItem.m_rankMap.Values) { if (rankItem.CurRecord != null) { TickRefreshCurRankRecord(nowSecond, rankItem); } } } } private static void TickRefreshCurRankRecord(long nowSecond, RankDataOne rankDataOne) { RankDataRecord record = rankDataOne.CurRecord; var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId); if (rankDesc == null || rankDesc.refreshType == 0) { return; } long newBeginTime = 0; //不刷新 switch ((RankFlushType)rankDesc.refreshType) { case RankFlushType.None: return; case RankFlushType.Seconds: //if(nowSecond - record.BeginTime < rankDesc.refreshTypeNum) //{ // return; //} //newBeginTime = nowSecond; return; case RankFlushType.Daily: if (AppTime.IsSameDay(nowSecond, record.BeginTime)) { return; } newBeginTime = AppTime.GetTodayStartTime(nowSecond); break; case RankFlushType.Weekly: if (AppTime.IsSameWeek127(nowSecond, record.BeginTime)) { return; } newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond); break; } if (record.AwardTime != 0) { TraceLog.Error("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} already award at time {2}" , record.RankId, record.BeginTime, record.AwardTime); return; } TraceLog.Debug("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}" , record.RankId, record.BeginTime, record.AwardTime); //更新当前榜单 TickUpdateRank(rankDataOne); //发放奖励 SendRankAwardMail(rankDataOne); //重置榜单 ReplaceOnRefreshRankRecord(rankDataOne, newBeginTime); } //手动清空排行榜 public static void ClearRank(int rankID, int realmID) { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realIdItem in rankData.AllRank.Values) { foreach (var rankItem in realIdItem.m_rankMap.Values) { if (rankItem.RankID == rankID && rankItem.RealmId == realmID) { RankDataRecord record = rankItem.CurRecord; var rankDesc = RankConfigDescMgr.Instance.GetConfig(record.RankId); if (rankDesc == null) { return; } long nowSecond = RankServerUtils.GetApp().GetTimeSecond(); long newBeginTime = 0; switch ((RankFlushType)rankDesc.refreshType) { case RankFlushType.Seconds: newBeginTime = nowSecond; break; case RankFlushType.Daily: newBeginTime = AppTime.GetTodayStartTime(nowSecond); break; case RankFlushType.Weekly: newBeginTime = AppTime.GetThisWeekStartTime1(nowSecond); break; } TraceLog.Debug("RankSvc.TickRefreshRankRecord rankId {0} beginTime {1} need award at time {2}" , record.RankId, record.BeginTime, record.AwardTime); //更新当前榜单 TickUpdateRank(rankItem); ReplaceOnRefreshRankRecord(rankItem, newBeginTime); } } } } //新老榜替换 public static void ReplaceOnRefreshRankRecord(RankDataOne rankDataOne, long newBeginTime) { rankDataOne.CurRecord.BeginTime = newBeginTime; if (rankDataOne.FlushType == RankFlushType.Seconds) { return; } rankDataOne.CurRecord.lastRankAwardTime = 0; rankDataOne.CurRecord.rewardGetUids.Clear(); rankDataOne.CurRecord.lastRankData.Clear(); rankDataOne.CurRecordLimitScore = 0; //填充进旧榜,并回收 foreach (var it in rankDataOne.data.m_curRecordIDMap) { ref DBRankOnePlayerStruct one = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(it.Value); if (one.data.Uid == it.Key) { rankDataOne.CurRecord.lastRankData.Add(one.data); } rankDataOne.data.m_cacheCurRecord.Free(it.Value); } if (rankDataOne.data.m_cacheCurRecord.GetUsedCount() > 1) { TraceLog.Error("RankSvc.ReplaceOnRefreshRankRecord rank {0} m_cacheCurRecord free error", rankDataOne.RankID); } //回收needRank foreach (var it in rankDataOne.data.m_needRankIDMap) { rankDataOne.data.m_cacheNeedRankData.Free(it.Value); } if (rankDataOne.data.m_cacheNeedRankData.GetUsedCount() > 1) { TraceLog.Error("RankSvc.ReplaceOnRefreshRankRecord rank {0} m_cacheNeedRankData free error", rankDataOne.RankID); } rankDataOne.data.m_curRecordIDMap.Clear(); rankDataOne.data.m_needRankIDMap.Clear(); rankDataOne.CurRecord.AwardTime = 0; rankDataOne.CurRecord.Data.Clear(); rankDataOne.CurRecord.NeedUpdate = true; rankDataOne.CurRecord.MakeDirty(); NoticeRankChange(rankDataOne); } public static void SendRankAwardMail(RankDataOne rankOne) { int rankId = rankOne.RankID; var record = rankOne.CurRecord; var rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId); if (rankDesc == null) { return; } TraceLog.Debug("RankSvc.SendRankAwardMail rankId {0}", record.RankId); int count = 0; int rank = 1; while (true) { if (rank <= record.Data.Count) { long uid = record.Data[rank - 1]; TraceLog.Debug("RankSvc.SendRankAwardMail {0} - uid {1} rank", rank, uid); SendAwardMailToRankPlayer(uid, rank, rankDesc); ++count; if(rank <= 100 && rankDesc.rankId == 2) { ref DBRankOnePlayerStruct p = ref rankOne.data.m_cacheCurRecord.GetByIndex(rankOne.data.m_curRecordIDMap[uid]); LogContinueBattleRank(uid, rank, (int)p.data.Score, 0, GetRankAward(rank, rankDesc)); }else if (rank <= 100 && rankDesc.rankId == 3) { ref DBRankOnePlayerStruct p = ref rankOne.data.m_cacheCurRecord.GetByIndex(rankOne.data.m_curRecordIDMap[uid]); LogContinueBattleRank(uid, rank, 0, (int)p.data.Score, GetRankAward(rank, rankDesc)); } } else { //排行榜上的玩家发送完奖励 break; } ++rank; } TraceLog.Debug("RankSvc.SendRankAwardMail succ, rankId {0} award count {1}", record.RankId, count); } public static void SendAwardMailToRankPlayer(long uid, int rankPos, RankConfigDesc rankDesc) { string reward = GetRankAward(rankPos, rankDesc); TraceLog.Trace("RankSvc.SendAwardMailToRankPlayer uid {0} rankId {1} pos {2}, reward={3}", uid, rankDesc.rankId, rankPos, reward); MailSender.SendNewMailToPlayer(uid, rankDesc.mail, reward, rankPos); } public static string GetRankAward(int rank, RankConfigDesc rankDesc) { List rewards = new List(); foreach (var item in RankAwardDescMgr.Instance.GetGroup(rankDesc.rankAward)) { if (rank >= item.Value.minRank && rank <= item.Value.maxRank) { return item.Value.reward; } } return ""; } private static void TickUpdateRank(long nowSecond) { WorldRankData rankData = RankServerUtils.GetRankData(); //1分钟一次,停服时5s一次 int updateRankCd = 5; if (RankServerUtils.GetApp().IsStopping) { updateRankCd = 5; } foreach (var realmIdItem in rankData.AllRank.Values) { if (realmIdItem.m_loadDbDataSuccess == false) { continue; } if (nowSecond < realmIdItem.m_lastUpdateRankTime + updateRankCd) { return; } realmIdItem.m_lastUpdateRankTime = nowSecond; foreach (var rankItem in realmIdItem.m_rankMap.Values) { if (rankItem.CurRecord != null) { TickUpdateRank(rankItem); } } } foreach (var realmIdItem in rankData.GlobalRank.Values) { if (realmIdItem.m_loadDbDataSuccess == false) { continue; } if (nowSecond < realmIdItem.m_lastUpdateRankTime + updateRankCd) { return; } realmIdItem.m_lastUpdateRankTime = nowSecond; var rankItem = realmIdItem.rankOne; { if (rankItem.CurRecord != null) { TickUpdateRank(rankItem); } } } } public static void LoadRankDataFromDb(int realmId) { SSQueryRankDbReq req = new SSQueryRankDbReq(); TraceLog.Trace("RankSvc.LoadRankDataFromDb begin realmId num:{0}", realmId); SortedList list = RankConfigDescMgr.Instance.ItemTable; uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1); req.RealmId = realmId; req.GroupId = 0; req.BeginTime = 0; //存取库Req.BeginTime全部统一用0 for (int i = 0; i < list.Values.Count; i++) { RankConfigDesc desc = list.Values[i]; if (desc.type != RankType.Single) continue;//跨服榜单独拉取 req.RankId = desc.rankId; RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.QueryRankDbReq, ref req, 0); } } public static void LoadGlobalRankFromDB(WorldRankData rankData, long nowSecond) { SSQueryRankDbReq req = new SSQueryRankDbReq(); SortedList list = RankConfigDescMgr.Instance.ItemTable; uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1); req.RealmId = 0; req.GroupId = 0; req.BeginTime = 0; //存取库Req.BeginTime全部统一用0 for (int i = 0; i < list.Values.Count; i++) { RankConfigDesc desc = list.Values[i]; if (desc.type != RankType.All) continue;//跨服榜单独拉取 if (!rankData.GlobalRank.TryGetValue(desc.rankId, out var rankone)) { rankone = new GlobalRankInfo(); rankData.GlobalRank[desc.rankId] = rankone; } if (rankone.m_loadDbDataSuccess) { continue; } if (rankone.m_serverStartTime == 0) { rankone.m_serverStartTime = nowSecond; } if (nowSecond - rankone.m_serverStartTime > 5 && nowSecond - rankone.m_lastLoadDbReqTime > 30) { rankone.m_lastLoadDbReqTime = nowSecond; req.RankId = desc.rankId; RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.QueryRankDbReq, ref req, 0); TraceLog.Trace("RankSvc.LoadGlobalRankFromDB begin {0}", req.RankId); } } } //5秒后开始加载数据库,如果失败30秒后再次尝试 public static void TickLoadRankFromDb(long nowSecond) { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realmItem in rankData.AllRank.Values) { if (realmItem.m_loadDbDataSuccess) { continue; } if (realmItem.m_serverStartTime == 0) { realmItem.m_serverStartTime = nowSecond; } if (nowSecond - realmItem.m_serverStartTime > 5 && nowSecond - realmItem.m_lastLoadDbReqTime > 30) { realmItem.m_lastLoadDbReqTime = nowSecond; LoadRankDataFromDb(realmItem.m_realmId); } } LoadGlobalRankFromDB(rankData, nowSecond); } public static void OnSaveRankDbRes(uint remoteAppID, StructPacket packet) { ref SSSaveRankDbRes res = ref packet.GetMessage(); if (res.Ret == 0) { if (res.BeginTime == 0) { bool setSaveSeq = false; WorldRankData rankData = RankServerUtils.GetRankData(); if (rankData.TryGetRankDataOne(out var rankOne, res.RealmId, res.RankId)) { if (rankOne.CurRecord != null) { setSaveSeq = true; rankOne.CurRecord.SavedSuccessSeq = res.DataSeq; TraceLog.Trace("RankSvc.OnSaveRankDbRes CurRecord rankId {0} {1} {2}", res.RankId, res.RealmId, res.DataSeq); } } if (!setSaveSeq) { TraceLog.Error("RankSvc.OnSaveRankDbRes CurRecord rankId {0} {1} not setSaveSeq", res.RankId, res.RealmId); } } else { TraceLog.Trace("RankSvc.OnSaveRankDbRes rankId {0} {1} {2} save success", res.RankId, res.RealmId, res.BeginTime); } } else { TraceLog.Error("RankSvc.OnSaveRankDbRes rankId {0} {1} {2} save fail", res.RankId, res.RealmId, res.BeginTime); } } public static void OnQueryRankDbRes(uint remoteAppID, StructPacket packet) { ref SSQueryRankDbRes res = ref packet.GetMessage(); RankDataOne oneRank = null; var rankDesc = RankConfigDescMgr.Instance.GetConfig(res.RankId); if(rankDesc.type == RankType.Single) { oneRank = RankUtils.GetCreateWorldRankDataOne(res.RealmId, res.RankId); if (oneRank == null) { TraceLog.Error("RankSvc.OnQueryRankDbRes realm {0} rankid {1} not get RankDataOne", res.RealmId, res.RankId); return; } RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(res.RealmId); if (realmRankInfo != null && realmRankInfo.m_loadDbDataSuccess) { TraceLog.Debug("RankSvc.OnQueryRankDbRes realm {0} rankId {1} already load, skip", res.RealmId, res.RankId); return; } } else { oneRank = RankUtils.GetCreateGlobalRank(res.RankId); } if (oneRank.CurRecord != null) { TraceLog.Error("RankSvc.OnQueryRankDbRes rankId {0} already load curRank from db, skip", res.RankId); return; } if (res.BeginTime != 0) { TraceLog.Error("RankSvc.OnQueryRankDbRes rankId {0} only load beginTime zero data {1}", res.RankId, res.BeginTime); return; } oneRank.CurRecord = new RankDataRecord(res.RankId); InitRankData(oneRank, ref res.Data); if (rankDesc.type == RankType.Single) { if (RankUtils.CheckLoadRankDataSuccess(res.RealmId)) { RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(res.RealmId); realmRankInfo.m_loadDbDataSuccess = true; } } else if (rankDesc.type == RankType.All) { WorldRankData rankData = RankServerUtils.GetRankData(); rankData.GlobalRank[res.RankId].m_loadDbDataSuccess = true; } TraceLog.Debug("RankSvc.OnQueryRankDbRes realmId {0} rank {1} load success", res.RealmId, res.RankId); } public static void InitRankData(RankDataOne rankData, ref DBRankData data) { rankData.closeRankTime = data.CloseRankTime; rankData.hideRankTime = data.HideRankTime; ref RankDataInfoCache cacheInfo = ref rankData.data; if (rankData.CurRecord.Data.Count != 0) { TraceLog.Error("RankSvc.InitRankData had InitCurRankData"); return; } rankData.CurRecord.BeginTime = data.BeginTime; rankData.CurRecord.AwardTime = data.AwardTime; for (int i = 0; i < data.RankList.Count; i++) { ref DBRankOnePlayerStruct one = ref cacheInfo.m_cacheCurRecord.Malloc(); if (!one.IsNull()) { int index = one.GetObjectID(); one.data.CopyFrom(ref data.RankList[i]); cacheInfo.m_curRecordIDMap.Add(data.RankList[i].Uid, index); //Uid index map rankData.CurRecord.Data.Add(data.RankList[i].Uid); } } for (int i = 0; i < data.LastRankData.LastRankList.Count; ++i) { rankData.CurRecord.lastRankData.Add(data.LastRankData.LastRankList[i]); } for (int i = 0; i < data.LastRankData.RewardGetUids.Count; ++i) { rankData.CurRecord.rewardGetUids.Add(data.LastRankData.RewardGetUids[i]); } if (rankData.SaveObjMax > 0 && rankData.SaveObjMax <= data.RankList.Count) { rankData.CurRecordLimitScore = data.RankList[rankData.SaveObjMax - 1].Score; } else { rankData.CurRecordLimitScore = 0; } //把已上榜的放到待排序队列中 AddCur2Need(ref rankData); } public static void ForceUpdateAllRank(int realmId = 0, int rankId = 0, bool skipCheck = false) { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realmIdPair in rankData.AllRank) { if (realmId == 0 || realmIdPair.Key == realmId) { foreach (var rankPair in realmIdPair.Value.m_rankMap) { if (rankId == 0 || rankPair.Key == rankId) { if (rankPair.Value.CurRecord != null) { TickUpdateRank(rankPair.Value, skipCheck); } } } } } } public static string GetRankActSaveDbFileName() { return "./RankActDb_" + RankServerUtils.GetApp().ServerID.ToString() + ".fdb"; } public static void SaveRankData() { var allplayerInfo = RankServerUtils.GetAllplayerInfo(); var file = GetRankActSaveDbFileName(); int haveSave = 0; TraceLog.Trace("RankSvc.SaveRankData save file {0} begin time {1}", file, RankServerUtils.GetTimeSecond()); try { FileStream fileStream = File.OpenWrite(file); //清空文件 fileStream.SetLength(0); BinaryWriter sw = new BinaryWriter(fileStream); foreach (var one in allplayerInfo.Values) { int size = one.CalculateSize(); byte[] dataByte = new byte[size]; CodedOutputStream ouput = new CodedOutputStream(dataByte); one.WriteTo(ouput); sw.Write(size); sw.Write(dataByte); //写入数据 sw.Flush(); ++haveSave; } sw.Dispose(); fileStream.Dispose(); } catch (Exception ex) { TraceLog.Error("RankSvc.SaveRankData write file failed! {0}", file); TraceLog.Exception(ex); return; } TraceLog.Trace("RankSvc.SaveRankData save file {0} end time {1}", file, RankServerUtils.GetTimeSecond()); } public static bool LoadRankFromFile() { var allplayerInfo = RankServerUtils.GetAllplayerInfo(); var file = GetRankActSaveDbFileName(); TraceLog.Trace("RankSvc.LoadMatchFromFile save file {0} begin time {1}", file, RankServerUtils.GetTimeSecond()); if (File.Exists(file) == false) { TraceLog.Trace("RankSvc.LoadMatchFromFile file not exist {0}", file); return true; } try { FileStream fileStream = File.OpenRead(file); BinaryReader sw = new BinaryReader(fileStream); long lenth = fileStream.Length; long pos = 0; while (pos < lenth) { int size = sw.ReadInt32(); byte[] data = sw.ReadBytes(size); //读数据 pos += sizeof(int) + size; if (pos <= lenth) { CodedInputStream input = new CodedInputStream(data); var one = new DBActRankTopPlayerInfo(); one.ReadFrom(input); allplayerInfo.TryAdd(one.Uid, one); } } sw.Dispose(); fileStream.Dispose(); } catch (Exception ex) { TraceLog.Error("RankSvc.LoadMatchFromFile parse message failed! {0}", file); TraceLog.Exception(ex); return false; } TraceLog.Trace("RankSvc.LoadMatchFromFile file {0} success time {1}", file, RankServerUtils.GetTimeSecond()); return true; } public static bool CheckGetAward(int mainType) { //return mainType == (int)RankMainType.TimeRecord; return false; } public static void DealNeedForceUpdate(RankDataOne rankOne) { //能领奖的榜有第一名就要更新,玩家需要在第一时间能领奖 if (CheckGetAward(0/*(int)rankOne.MainType*/) && rankOne.CurRecord.Data.Count < 10) { //if (rankOne.LinkRank > 0) //{ // //先更新主榜 // var mainRankdata = RankUtils.GetRankDataOne(rankOne.RealmId, rankOne.LinkRank); // if (mainRankdata != null) // { // TickUpdateRank(mainRankdata); // } //} TickUpdateRank(rankOne); AddCanAwardRank(rankOne); } } private static void TickUpdateRank(RankDataOne rankOne, bool skipCheck = false) { if (rankOne.CurRecord == null) { return; } if (rankOne.CurRecord.NeedUpdate || skipCheck) { rankOne.CurRecord.NeedUpdate = false; 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; } SortNeedRank(ref rankOne, rankDesc); if (rankDesc.refreshType != (int)RankFlushType.Seconds) {//按照秒刷新的排行榜不推送通知 NoticeRankChange(rankOne); } TraceLog.Trace("RankSvc.TickUpdateRank realmId:{0} rankId:{1}", rankOne.RealmId, rankOne.RankID); } } private static void TickSaveRankData(long nowSecond) { long nowMs = RankServerUtils.GetTimeMs(); WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realmIdItem in rankData.AllRank.Values) { if (realmIdItem.m_loadDbDataSuccess == false) { continue; } foreach (var rankItem in realmIdItem.m_rankMap.Values) { if (rankItem.CurRecord != null) { if (rankItem.CurRecord.CanDoSaveReqNow(nowMs)) { SaveRankCurRecord(rankItem); rankItem.CurRecord.OnSaveReq(nowMs); } } } } foreach (var rankItem in rankData.GlobalRank.Values) { if (rankItem.rankOne == null) continue; if (rankItem.rankOne.CurRecord != null) { if (rankItem.rankOne.CurRecord.CanDoSaveReqNow(nowMs)) { SaveRankCurRecord(rankItem.rankOne); rankItem.rankOne.CurRecord.OnSaveReq(nowMs); } } } } private static void TickSaveActRankData(long nowSecond) { long nowMs = RankServerUtils.GetTimeMs(); var rankData = RankServerUtils.GetActRankData(); uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1); foreach (var realmRank in rankData.Values) { foreach (var rankOne in realmRank.m_AcRank.Values) { if (!rankOne.IsDirty()) continue; if (!rankOne.CanDoSaveReqNow(nowMs)) continue; // save req var req = new SSSaveActRankDataReq(); req.ActRankId = rankOne.ActRankID; req.RealmId = rankOne.RealmId; req.BeginTime = rankOne.BeginTime; req.EndTime = rankOne.EndTime; req.EndClear = rankOne.endClear ? 1 : 0; req.RankData.RankId = rankOne.ActRankID; foreach (var one in rankOne.m_rankRank) { if (req.RankData.RankList.Count >= req.RankData.RankList.GetMaxCount()) break; req.RankData.RankList.Add(one.Uid); } req.DataSeq = rankOne.DataSeq; rankOne.OnSaveReq(nowMs); RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveActRankDataReq, ref req, 0); TraceLog.Trace("RankSvc.TickSaveActRankData rankId {0} rem:{1} dataSeq {2}", rankOne.ActRankID, rankOne.RealmId, rankOne.DataSeq); } } } private static void TickClearActRankData(long nowSecond) { long nowMs = RankServerUtils.GetTimeMs(); var rankData = RankServerUtils.GetActRankData(); uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1); foreach (var realmRank in rankData.Values) { foreach (var rankOne in realmRank.m_AcRank.Values) { if (rankOne.endClear) continue; if (rankOne.EndTime > nowSecond) continue; //结算 EndClearRank(rankOne); } } } public static void EndClearRank(ActRankOne rankOne) { var desc = ActivityDescMgr.Instance.GetConfig(rankOne.ActRankID); if (desc == null) { TraceLog.Error("RankSvc.EndClearRank get PandoraActivity is null! id:{0}", rankOne.ActRankID); return; } for (var i = 0; i < rankOne.m_rankRank.Count; i++) { var rank = i + 1; SendActRankAwardMailPlayer(rankOne.m_rankRank[i].Uid, rank, rankOne.ActRankID, rankOne.RealmId, desc); } TraceLog.Trace("RankSvc.EndClearRank rank actRank:{0} rem:{1}", rankOne.ActRankID, rankOne.RealmId); rankOne.endClear = true; rankOne.MakeDirty(); } public static void SendActRankAwardMailPlayer(long uid, int rankPos, int ActRankID, int rem, ActivityDesc desc) { ; var descMail=MailDescMgr.Instance.GetConfig(desc.mailId); DBMail mail = new DBMail(); mail.Uid = uid; mail.MailConfId = desc.mailId; mail.MailType = (int)MailType.ActRank; //mail.Title.SetString(descMail.title); //mail.Content.SetString(descMail.content); //mail.SenderName.SetString(descMail.name); mail.Param1 = rankPos; var rankReward = GetActRankReward(rankPos); for (int i = 0; i < rankReward.Count; i++) { mail.AddGoods.Add(rankReward[i]); } TraceLog.TraceDetail("RankSvc.SendAwardMailToRankPlayer uid {0} rankId {1} rem:{2}: mailInfo:{3}", uid, ActRankID, rem, mail); MailSender.SendNewMailToPlayer(mail.Uid, ref mail); } private static List GetActRankReward(int rank) { var list = new List(); NewSeverRankAwardDesc rankDesc = null; foreach (var desc in NewSeverRankAwardDescMgr.Instance.ItemTable.Values) { if (desc.minRank <= rank && desc.maxRank >= rank) { rankDesc = desc; break; } } if (rankDesc == null) return list; for (var i = 0; i < rankDesc.rewards.Length; i++) { if (!string.IsNullOrEmpty(rankDesc.rewards[i].id) ) continue; list.Add(new TypeIDValueString() { Type = rankDesc.rewards[i].type, Id = new FixedStructString64(rankDesc.rewards[i].id), Value = rankDesc.rewards[i].value, }); } return list; } private static void SaveRankCurRecord(RankDataOne rankOne) { RankDataRecord record = rankOne.CurRecord; TraceLog.Trace("RankSvc.SaveRankRecord rankId {0} beginTime {1} dataSeq {2}", record.RankId, record.BeginTime, record.DataSeq); SSSaveRankDbReq req = new SSSaveRankDbReq(); req.RankId = record.RankId; req.RealmId = rankOne.RealmId; req.BeginTime = 0; //存取库Req.BeginTime全部统一用0 req.GroupId = 0; req.Data.RankId = record.RankId; req.Data.AwardTime = record.AwardTime; req.Data.HideRankTime = rankOne.hideRankTime; req.Data.CloseRankTime = rankOne.closeRankTime; req.Data.BeginTime = record.BeginTime; req.DataSeq = record.DataSeq; foreach (var uid in record.Data) { long index; if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out index)) { if (req.Data.RankList.GetCount() < req.Data.RankList.GetMaxCount() && req.Data.RankList.GetCount() < rankOne.SaveObjMax) { ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index); req.Data.RankList.Add(ref one.data); } } } int dataCount = rankOne.CurRecord.lastRankData.Count; if (dataCount > req.Data.LastRankData.LastRankList.GetMaxCount()) { TraceLog.Error("RankSvc.SaveRankRecord rankId {0} LastRankList error count {1}", rankOne.RankID, dataCount); dataCount = req.Data.LastRankData.LastRankList.GetMaxCount(); } req.Data.LastRankData.AwardTime = rankOne.CurRecord.lastRankAwardTime; for (int i = 0; i < dataCount; ++i) { req.Data.LastRankData.LastRankList.Add(rankOne.CurRecord.lastRankData[i]); } dataCount = rankOne.CurRecord.rewardGetUids.Count; if (dataCount > req.Data.LastRankData.RewardGetUids.GetMaxCount()) { TraceLog.Error("RankSvc.SaveRankRecord rankId {0} RewardGetUids error count {1}", rankOne.RankID, dataCount); dataCount = req.Data.LastRankData.RewardGetUids.GetMaxCount(); } for (int i = 0; i < dataCount; ++i) { req.Data.LastRankData.RewardGetUids.Add(rankOne.CurRecord.rewardGetUids[i]); } uint dbServerID = GameDBServerIDUtils.GetGameDBServerID(1); RankServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.SaveRankDbReq, ref req, 0); } public static void AddCur2Need(ref RankDataOne rankOne) { long index; foreach (var uid in rankOne.CurRecord.Data) { if (rankOne.data.m_needRankIDMap.ContainsKey(uid) == false) { if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out index)) { ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index); if (one.data.Uid == uid) { ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.Malloc(); if (need.IsNull()) { TraceLog.Error("RankSvc.AddCur2Need !!!!!!!! cache isfull"); return; } need.data.CopyFrom(ref one.data); rankOne.data.m_needRankIDMap.Add(uid, need.GetObjectID()); } else { TraceLog.Error("RankSvc.AddCur2Need item_Value:{0} != one_data_Uid:{1}", uid, one.data.Uid); } } } } } public static void SortNeedRank(ref RankDataOne rankOne, RankConfigDesc rankDesc) { WorldRankData rankData = RankServerUtils.GetRankData(); List rankSortList = new List(); bool sortByLess = rankDesc.sortByLess == 1; bool sortByLess2 = rankDesc.sortByLess1 == 1; foreach (var item in rankOne.data.m_needRankIDMap) { if (rankData.m_forbitUidMap.ContainsKey(item.Key)) { continue; } ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.GetByIndex(item.Value); var dataOne = new RankBriefDataOne(need.data.Uid, need.data.Rank, need.data.Rank, need.data.Score,need.data.Param, need.data.Time); rankSortList.Add(dataOne); } //默认小值在前,非小值在前的话乘-1 rankSortList.Sort((a, b) => a.CompareTo(b, sortByLess, sortByLess2)); // 清空cur foreach (long uid in rankOne.CurRecord.Data) { if (rankOne.data.m_curRecordIDMap.TryGetValue(uid, out long index)) { ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.GetByIndex(index); rankOne.data.m_cacheCurRecord.Free(ref one); } } rankOne.data.m_curRecordIDMap.Clear(); rankOne.CurRecord.MakeDirty(); rankOne.CurRecordLimitScore = 0; //限制分数设为0 rankOne.CurRecord.Data.Clear(); Dictionary newNeedRankIDMap = new Dictionary(); // 填充cur for (int i = 0; i < rankSortList.Count; ++i) { var oneData = rankSortList[i]; long uid = oneData.Uid; int rank = rankOne.CurRecord.Data.Count + 1; if (rankOne.data.m_needRankIDMap.TryGetValue(uid, out long index)) { ref DBRankOnePlayerStruct need = ref rankOne.data.m_cacheNeedRankData.GetByIndex(index); ref DBRankOnePlayerStruct one = ref rankOne.data.m_cacheCurRecord.Malloc(); if (one.IsNull() || need.IsNull()) { TraceLog.Error("RankSvc.SortNeedRank can not Malloc rankOne.data.m_cacheCurRecord {0}", rankOne.RankID); return; } rankOne.data.m_curRecordIDMap.Add(uid, one.GetObjectID()); newNeedRankIDMap.Add(uid, index); //新的needRankMap need.data.Rank = rank; one.data.CopyFrom(ref need.data); rankOne.CurRecord.Data.Add(need.data.Uid); if (rank == rankOne.SaveObjMax) { rankOne.CurRecordLimitScore = oneData.Score; break; } } } rankOne.CurRecord.MakeDirty(); //将不在新排行榜上的数据从needrank中清除 foreach (var item in rankOne.data.m_needRankIDMap) { if (newNeedRankIDMap.ContainsKey(item.Key) == false) { rankOne.data.m_cacheNeedRankData.Free(item.Value); } } rankOne.data.m_needRankIDMap = newNeedRankIDMap; } public static void NoticeRankChange(RankDataOne rankOne) { CSNoticeRankChange notice = new CSNoticeRankChange(); notice.RealmId = rankOne.RealmId; notice.RankId = rankOne.RankID; //广播给所有game RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)CSGameMsgID.NoticeRankChange, ref notice, 0, 0); } //添加能领奖的榜 public static void AddCanAwardRank(RankDataOne rankDataOne) { RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankDataOne.RankID); //记录榜才能领奖 if (rankDesc == null) { return; } //有第一名 if (rankDataOne.CurRecord != null && rankDataOne.CurRecord.Data.Count > 0) { SSUpdateAwardRank notice = new SSUpdateAwardRank(); notice.RealmId = rankDataOne.RealmId; notice.RankList.Add(rankDataOne.RankID); //广播给所有game RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0); TraceLog.Trace("RankSvc.AddCanAwardRank realmId:{0} rankId:{1}", rankDataOne.RealmId, rankDataOne.RankID); } } //更新能领奖的榜单 public static void UpdateCanAwardRank() { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realmIdPair in rankData.AllRank) { SSUpdateAwardRank notice = new SSUpdateAwardRank(); notice.RealmId = realmIdPair.Key; notice.CleanCache = 1; //清楚缓存 foreach (var rankPair in realmIdPair.Value.m_rankMap) { var oneInfo = rankPair.Value; if (oneInfo.CurRecord != null && oneInfo.CurRecord.Data.Count > 0) { var rankDesc = RankConfigDescMgr.Instance.GetConfig(oneInfo.RankID); //记录榜才能领奖 if (rankDesc != null) { notice.RankList.Add(oneInfo.RankID); if (notice.RankList.Count >= notice.RankList.GetMaxCount()) { RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0); notice.RankList.Clear(); notice.CleanCache = 0; } } } } if (notice.RankList.Count > 0) { RankServerUtils.GetPacketSender().Broadcast((int)ServerType.Game, (int)SSGameMsgID.UpdateAwardRank, ref notice, 0, 0); } } } public static void OnRankRealmlistRanklistRes(uint remoteAppID, StructPacket packet) { ref SSRankRealmlistRes res = ref packet.GetMessage(); RankServerData serverData = RankServerUtils.GetRankServerData(); var addRank = false; for (int i = 0; i < res.Realms.Count; i++) { var realm = new RealmBriefInfo(ref res.Realms[i]); serverData.m_configRealm[realm.realmId] = realm; if (serverData.m_RankData.AllRank.ContainsKey(realm.realmId) == false) { serverData.m_RankData.AllRank.Add(realm.realmId, new RealmRankInfo(realm.realmId)); addRank = true; } if (realm.bigRealmId > 0 && serverData.m_RankData.AllRank.ContainsKey(realm.bigRealmId) == false) { serverData.m_RankData.AllRank.Add(realm.bigRealmId, new RealmRankInfo(realm.bigRealmId)); addRank = true; } } // ActRank.LoadActRank(); TraceLog.Trace("OnRankRealmlistRanklistRes realm count {0}", serverData.m_configRealm.Count); } //判断能不能上榜 public static bool CheckRankLimit(RankConfigDesc rankDesc, long values, long limitScore) { if (limitScore == 0) { return true; } //顺序榜小于限制值 if (rankDesc.sortByLess == 1 && values < limitScore) { return true; } //逆序榜大于限制值 else if (rankDesc.sortByLess == 0 && values > limitScore) { return true; } return false; } public static void OnSynRoleRankData(uint remoteAppID, StructPacket packet) { ref SSSynRoleRankData synData = ref packet.GetMessage(); SSAddRankDataReq addReq = new SSAddRankDataReq() { Uid = synData.Uid, RealmId = synData.RealmId, GroupId = synData.GroupId, Level = synData.Level, Gender = synData.Gender, IconFrameId = synData.IconFrameId, }; addReq.Nick.CopyFrom(ref synData.Nick); addReq.Icon.CopyFrom(ref synData.Icon); SSAddRankDataRes res = new SSAddRankDataRes() { Uid = synData.Uid, RealmId = synData.RealmId, GroupId = synData.GroupId, }; for (int i = 0; i < synData.List.Count; ++i) { ref var oneData = ref synData.List[i]; addReq.RankId = oneData.RankID; addReq.Score = oneData.RankScore; res.RankId = oneData.RankID; res.Score = oneData.RankScore; res.Ret = (int)OnAddRankData(remoteAppID, ref addReq, ref res); RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.AddRankDataRes, ref res, packet.ObjectID); } } public static void OnAddRankDataReq(uint remoteAppID, StructPacket packet) { ref SSAddRankDataReq req = ref packet.GetMessage(); SSAddRankDataRes res = new SSAddRankDataRes() { Uid = req.Uid, RankId = req.RankId, RealmId = req.RealmId, GroupId = req.GroupId, Score = req.Score, }; res.Ret = (int)OnAddRankData(remoteAppID, ref req, ref res); RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.AddRankDataRes, ref res, packet.ObjectID); } public static void OnSendRankRewardReq(uint remoteAppID, StructPacket packet) { //ref var req = ref packet.GetMessage(); ////获取榜单 //var serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); //if (!serverData.m_RankData.TryGetRankDataOne(out RankDataOne rank, req.RealmId, req.RankId)) //{ // TraceLog.Error("RankSvc.OnSendRankRewardReq realm {0} rank {1} not exist" // , req.RankId, req.RealmId); // return; //} //rank.hideRankTime = req.HideRankTime; //if (req.CloseRank == 1 && rank.closeRankTime == 0) //{ // rank.closeRankTime = (int)RankServerUtils.GetTimeSecond(); //} //if (rank.CurRecord != null && rank.CurRecord.AwardTime == 0) //{ // // todo 这里有个风险, 如果rankData存DB失败, 同时服务器core了, 那么重启后可能会重复发奖励 // rank.CurRecord.AwardTime = RankServerUtils.GetTimeSecond(); // rank.CurRecord.NeedSave = true; // SendRankAwardMail(rank.RankID, rank.CurRecord); //} } public static CSErrCode OnAddRankData(uint remoteAppID, ref SSAddRankDataReq req, ref SSAddRankDataRes res) { RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(req.RankId); //分数0,不上榜 if (rankDesc == null || req.Score == 0) { TraceLog.Error("RankSvc.OnAddRankData fail RankId:{0} score:{1}", req.RankId, req.Score); return CSErrCode.SysFailure; } //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); //排行榜黑名单 if (serverData.m_RankData.m_forbitUidMap.ContainsKey(req.Uid)) { TraceLog.Trace("RankSvc.OnAddRankData fail forbitUid:{0} RankId:{1} score:{2}", req.Uid, req.RankId, req.Score); return CSErrCode.SysFailure; } RankDataOne rankDataOne = null; if (rankDesc.type == RankType.Single) { RealmRankInfo relamInfo = RankUtils.GetRealmRankInfo(req.RealmId); if (relamInfo == null || relamInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.OnAddRankData realmid {0} not all loaded", req.RealmId); return CSErrCode.SysFailure; } if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, req.RealmId, req.RankId)) { TraceLog.Error("RankSvc.OnAddRankData get RankData fail RankId:{0} RealmId:{1}", req.RankId, req.RealmId); return CSErrCode.SysFailure; } } else { rankDataOne = RankUtils.GetGlobalRank(req.RankId); if (rankDataOne == null) { TraceLog.Error("RankSvc.OnAddRankData rankid {0} null", req.RankId); return CSErrCode.SysFailure; } } if (rankDataOne.CurRecord == null) { TraceLog.Error("RankSvc.OnAddRankData RankData currecord null RankId:{0} RealmId:{1}", req.RankId, req.RealmId); return CSErrCode.SysFailure; } // 排行榜关闭或隐藏, 不更新 if (rankDataOne.closeRankTime > 0 || (rankDataOne.hideRankTime > 0 && RankServerUtils.GetTimeSecond() >= rankDataOne.hideRankTime)) { TraceLog.Trace("RankSvc.OnAddRankData RankId:{0} RealmId:{1} close or hide", req.RankId, req.RealmId); return CSErrCode.RankStopUpdate; } //太拉跨了不能上榜 if (!CheckRankLimit(rankDesc, req.Score, rankDataOne.CurRecordLimitScore)) { res.LimintScore = rankDataOne.CurRecordLimitScore; return CSErrCode.RankScoreLimit; } long top; if (rankDataOne.data.m_curRecordIDMap.TryGetValue(req.Uid, out top)) { //可能只是切换了称号 ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(top); need.data.Param = req.Param; } long index; //有需要上榜的缓存数据 if (rankDataOne.data.m_needRankIDMap.TryGetValue(req.Uid, out index)) { ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.GetByIndex(index); //需不需要更新数据 if (CheckRankLimit(rankDesc, req.Score, need.data.Score)) { TraceLog.Trace("RankSvc.OnAddRankData rank {0} realm {1} uid {2} score {3}" , req.RankId, req.RealmId, req.Uid, req.Score); need.data.Time = RankServerUtils.GetTimeSecond(); need.data.Icon.CopyFrom(ref req.Icon); need.data.Nick.CopyFrom(ref req.Nick); need.data.Gender = req.Gender; need.data.Level = req.Level; need.data.Score = req.Score; need.data.IconFrameId = req.IconFrameId; need.data.Param = req.Param; need.data.Skin = req.Skin; need.data.Weapon1 = req.Weapon1; need.data.Power = req.Power; need.data.WingrefitId = req.WingrefitId; need.data.WingskinId = req.WingskinId; need.data.WingwearId = req.WingwearId; rankDataOne.CurRecord.NeedUpdate = true; return CSErrCode.None; } //可能是切换称号 need.data.Param = req.Param; return CSErrCode.RankScoreLimit; } if (AddNeedRankData(rankDataOne, ref req) >= 0) { return CSErrCode.None; } return CSErrCode.SysFailure; } public static int AddNeedRankData(RankDataOne rankDataOne, ref SSAddRankDataReq req) { ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.Malloc(); if (need.IsNull()) { TraceLog.Error("RankSvc.AddNeedRankData malloc cache fail RankId:{0} uid:{1} score:{2}", req.RankId, req.Uid, req.Score); return -1; } rankDataOne.data.m_needRankIDMap.Add(req.Uid, need.GetObjectID()); rankDataOne.CurRecord.NeedUpdate = true; TraceLog.Trace("RankSvc.AddNeedRankData rank {0} realm {1} uid {2} score {3}" , req.RankId, req.RealmId, req.Uid, req.Score); need.data.Clear(); need.data.Uid = req.Uid; need.data.Rank = rankDataOne.data.m_cacheCurRecord.GetTotalCount() + 1; //排序依据 同分数的话排名会低于之前就在榜上的 need.data.Time = RankServerUtils.GetTimeSecond(); need.data.Icon.CopyFrom(ref req.Icon); need.data.Nick.CopyFrom(ref req.Nick); need.data.Gender = req.Gender; need.data.Level = req.Level; need.data.Score = req.Score; need.data.IconFrameId = req.IconFrameId; need.data.Param = req.Param; need.data.Skin = req.Skin; need.data.Weapon1 = req.Weapon1; need.data.Power = req.Power; need.data.WingrefitId = req.WingrefitId; need.data.WingskinId = req.WingskinId; need.data.WingwearId = req.WingwearId; RankSvc.DealNeedForceUpdate(rankDataOne); //没空间了直接排一次 if (rankDataOne.data.m_cacheNeedRankData.GetFreeCount() <= 0) { TickUpdateRank(rankDataOne); } return 0; } public static void OnQueryRankListReq(uint remoteAppID, StructPacket packet) { ref CSQueryRankListReq req = ref packet.GetMessage(); //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); var desc = RankConfigDescMgr.Instance.GetConfig(req.RankId); RankDataOne rankDataOne = null; if (desc.type == RankType.Single) { int realmId = req.RealmId; if (CheckIsKfRank(req.RankId)) { realmId = req.BigRealmId; } RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId); if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.OnQueryRankListReq get realmRankInfo fail RealmId:{0}", realmId); return; } if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, req.RankId)) { TraceLog.Error("RankSvc.OnQueryRankListReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId); return; } } else if(desc.type == RankType.All) { rankDataOne = RankUtils.GetGlobalRank(req.RankId); } // 隐藏排行榜 if (rankDataOne.hideRankTime > 0 && RankServerUtils.GetTimeSecond() >= rankDataOne.hideRankTime) { TraceLog.Trace("RankSvc.OnQueryRankListReq realmId {0} rankId {1} hide at {2}" , req.RankId, req.RankId, rankDataOne.hideRankTime); return; } CSQueryRankListRes res = new CSQueryRankListRes { Ret = (int)CSErrCode.None, RankId = req.RankId, HideRankTime = rankDataOne.hideRankTime, //NextUpdateRankTime = (int)realmRankInfo.m_lastUpdateRankTime + 60 }; long selfUid = packet.ObjectID; for (int rank = req.StartPos; rank <= req.EndPos; ++rank) { if (rank <= rankDataOne.CurRecord.Data.Count && rank > 0) { long Uid = rankDataOne.CurRecord.Data[rank - 1]; if (rankDataOne.data.m_curRecordIDMap.TryGetValue(Uid, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); res.RankList.Add(ref data.data); if (res.RankList.Count >= res.RankList.GetMaxCount()) { break; } } } } res.GetLastReward = true; if (rankDataOne.CurRecord != null) { for (int i = 0; i < rankDataOne.CurRecord.lastRankData.Count; ++i) { if (rankDataOne.CurRecord.lastRankData[i].Uid == selfUid) { res.LastRank = rankDataOne.CurRecord.lastRankData[i].Rank; if (!rankDataOne.CurRecord.rewardGetUids.Contains(selfUid)) { res.GetLastReward = false; } break; } } } //从第一名开始请求的时候需要回自己的排名 res.SelfRank = 0; if (req.StartPos == 1) { if (rankDataOne.data.m_curRecordIDMap.TryGetValue(selfUid, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); if (data.data.Uid == selfUid) { res.SelfRank = data.data.Rank; res.SelfScore = data.data.Score; res.SelfParam = data.data.Param; } } } res.PlayerCount = res.RankList.Count; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankListRes, ref res, packet.ObjectID); } public static void OnQueryRankSelfReq(uint remoteAppID, StructPacket packet) { ref CSQueryRankSelfReq req = ref packet.GetMessage(); //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); int realmId = req.RealmId; if (CheckIsKfRank(req.RankId)) { realmId = req.BigRealmId; } RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId); if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.OnQueryRankListReq get realmRankInfo fail RealmId:{0}", realmId); return; } if (!serverData.m_RankData.TryGetRankDataOne(out RankDataOne rankDataOne, realmId, req.RankId)) { TraceLog.Error("RankSvc.OnQueryRankListReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId); return; } if (rankDataOne == null || rankDataOne.CurRecord == null) { return; } if (rankDataOne.CurRecord.rewardGetUids.Contains(packet.ObjectID)) { return; } CSQueryRankSelfRes res = new CSQueryRankSelfRes(); res.Ret = (int)CSErrCode.None; res.RankId = req.RankId; for (int rank = 0; rank < rankDataOne.CurRecord.Data.Count; ++rank) { if (rankDataOne.CurRecord.Data[rank] == packet.ObjectID && rankDataOne.data.m_curRecordIDMap.TryGetValue(packet.ObjectID, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); res.SelfInfo = data.data; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankSelfRes, ref res, packet.ObjectID); return; } } //未上榜的也需要返回一下数据 res.SelfInfo = new DBRankPlayerInfo() { Rank = 0 }; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankSelfRes, ref res, packet.ObjectID); } //根据类型获取排行榜list public static List GetRankListByType(int mainType, int subType) { List rankList = new List(); SortedList list = RankConfigDescMgr.Instance.ItemTable; for (int i = 0; i < list.Values.Count; i++) { RankConfigDesc desc = list.Values[i]; } return rankList; } public static void OnQueryRankTopReq(uint remoteAppID, StructPacket packet) { ref CSQueryRankTopReq req = ref packet.GetMessage(); //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); CSQueryRankTopRes res = new CSQueryRankTopRes { Ret = (int)CSErrCode.None, MainType = req.MainType, SubType = req.SubType, }; List rankList = GetRankListByType(req.MainType, req.SubType); if (rankList.Count == 0) { res.Ret = (int)CSErrCode.RankTypeError; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankTopRes, ref res, packet.ObjectID); TraceLog.Error("RankSvc.OnQueryRankTopReq type error {0}-{1}", req.MainType, req.SubType); return; } foreach (var rankId in rankList) { int realmId = req.RealmId; if (CheckIsKfRank(rankId)) { realmId = req.BigRealmId; } if (serverData.m_RankData.TryGetRankDataOne(out RankDataOne rankDataOne, realmId, rankId)) { RankTopPlayerInfo onePlayer = new RankTopPlayerInfo { Uid = 0, RankId = rankId, }; if (rankDataOne.CurRecord.Data.Count > 0) { long Uid = rankDataOne.CurRecord.Data[0]; if (rankDataOne.data.m_curRecordIDMap.TryGetValue(Uid, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); onePlayer.Uid = data.data.Uid; onePlayer.Gender = data.data.Gender; onePlayer.Level = data.data.Level; onePlayer.Score = data.data.Score; onePlayer.Nick.CopyFrom(ref data.data.Nick); onePlayer.Icon.CopyFrom(ref data.data.Icon); onePlayer.Time = data.data.Time; onePlayer.IconFrameId = data.data.IconFrameId; } } res.TopInfo.Add(ref onePlayer); if (res.TopInfo.Count >= res.TopInfo.GetMaxCount()) { TraceLog.Error("RankSvc.OnQueryRankTopReq top count is full {0}", res.TopInfo.Count); break; } } } RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.QueryRankTopRes, ref res, packet.ObjectID); } public static void OnPlayerShowInfoUpdate(uint remoteAppID, StructPacket packet) { ref SSPlayerShowInfoUpdate req = ref packet.GetMessage(); RealmRankInfo realmInfo = RankUtils.GetRealmRankInfo(req.RealmId); if (realmInfo == null || realmInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.OnPlayerShowInfoUpdate RealmId:{0} no load success", req.RealmId); return; } foreach (var item in realmInfo.m_rankMap) { var rankDataOne = item.Value; //在榜上 if (rankDataOne.data.m_curRecordIDMap.TryGetValue(req.Uid, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); if (data.data.Uid == req.Uid) { data.data.Level = req.Level; data.data.Gender = req.Gender; data.data.Icon.CopyFrom(ref req.Icon); data.data.Nick.CopyFrom(ref req.Nick); data.data.IconFrameId = req.IconFrameId; data.data.Power = req.Power; data.data.Skin = req.Skin; data.data.WingskinId = req.WingskinId; data.data.WingrefitId = req.WingrefitId; data.data.WingwearId = req.WingwearId; rankDataOne.CurRecord.MakeDirty(); } } //在即将上榜的缓存中 if (rankDataOne.data.m_needRankIDMap.TryGetValue(req.Uid, out index)) { ref DBRankOnePlayerStruct need = ref rankDataOne.data.m_cacheNeedRankData.GetByIndex(index); if (need.data.Uid == req.Uid) { need.data.Gender = req.Gender; need.data.Level = req.Level; need.data.Icon.CopyFrom(ref req.Icon); need.data.Nick.CopyFrom(ref req.Nick); need.data.IconFrameId = req.IconFrameId; need.data.Power = req.Power; need.data.Skin = req.Skin; need.data.WingskinId = req.WingskinId; need.data.WingrefitId = req.WingrefitId; need.data.WingwearId = req.WingwearId; rankDataOne.CurRecord.NeedUpdate = true; } } } } //添加禁止上榜名单 public static bool AddForbitRankUid(long uid) { WorldRankData rankData = RankServerUtils.GetRankData(); return rankData.m_forbitUidMap.TryAdd(uid, true); } public static bool CheckIsKfRank(int rankId) { var desc = RankConfigDescMgr.Instance.GetConfig(rankId); if (desc != null && desc.reasonType == (int)RankReasonType.ArenaStarRank) { return true; } return false; } public static void QueryRankOneReq(uint remoteAppID, StructPacket packet) { ref SSQueryRankOneReq req = ref packet.GetMessage(); var res = new SSQueryRankOneRes(); res.Uid = req.Uid; ; res.RealmId = req.RealmId; res.RankId = req.RankId; //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); var desc = RankConfigDescMgr.Instance.GetConfig(req.RankId); RankDataOne rankDataOne = null; if (desc.type == RankType.Single) { int realmId = req.RealmId; RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId); if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.QueryRankOneReq get realmRankInfo fail RealmId:{0}", realmId); return; } if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, req.RankId)) { TraceLog.Error("RankSvc.QueryRankOneReq get RankData fail RealmId:{0} RankId:{1}", realmId, req.RankId); //没有记录 res.Ret = 1; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID); return; } if(rankDataOne.data.m_curRecordIDMap.TryGetValue(req.RankId, out var cidx)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(cidx); if (data.data.Uid == req.Uid) { res.Rank.CopyFrom(ref data.data); res.Ret = 0; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID); return; } } //没有记录 res.Ret = 1; RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSGameMsgID.QueryRankOneRes, ref res, packet.ObjectID); } } public static void TALogRank(long nowSecond) { WorldRankData rankData = RankServerUtils.GetRankData(); foreach (var realIdItem in rankData.AllRank.Values) { foreach (var rankItem in realIdItem.m_rankMap.Values) { if (rankItem.CurRecord != null) { if(rankItem.RankID == 1) { for (int i = 0; i < rankItem.CurRecord.Data.Count; i++) { long uid = rankItem.CurRecord.Data[i]; if (rankItem.data.m_curRecordIDMap.TryGetValue(uid, out long index)) { ref var d = ref rankItem.data.m_cacheCurRecord.GetByIndex(index); LogChapterRank(uid, i + 1, (int)d.data.Score, d.data.Param); } } } } } } } public static void LogChapterRank(long uid, int rank, int mainland_id, int fight_time) { var ta = new TALogHelper(TALOG_TYPE.TRACE, uid + "", "", TALogEventName.RANK_FLOW); ta.Add("rank", rank); ta.Add("mainland_id", mainland_id); ta.Add("fight_time", fight_time); ta.PutLog(); } public static void LogContinueBattleRank(long uid, int rank, int stage_max, int score, string rewardid) { var ta = new TALogHelper(TALOG_TYPE.TRACE, uid + "", "", TALogEventName.continue_battle_rank); ta.Add("rank", rank); ta.Add("stage_max", stage_max); ta.Add("score", score); ta.Add("rewards_id", rewardid); ta.PutLog(); } public static void RankPlayerBylevelReq(uint remoteAppID, StructPacket packet) { ref CSRankPlayerByLevelReq req = ref packet.GetMessage(); var res = new CSRankPlayerByLevelRes(); res.Uid = req.Uid; ; res.RealmId = req.RealmId; //获取榜单 RankServerData serverData = ServerDataObjMgr.GetDataObj(RankDataObjType.RankServerData); var desc = RankConfigDescMgr.Instance.GetConfig(1); RankDataOne rankDataOne = null; if (desc.type == RankType.Single) { int realmId = req.RealmId; RealmRankInfo realmRankInfo = RankUtils.GetRealmRankInfo(realmId); if (realmRankInfo == null || realmRankInfo.m_loadDbDataSuccess == false) { TraceLog.Error("RankSvc.RankPlayerBylevelReq get realmRankInfo fail RealmId:{0}", realmId); return; } if (!serverData.m_RankData.TryGetRankDataOne(out rankDataOne, realmId, desc.rankId)) { TraceLog.Error("RankSvc.RankPlayerBylevelReq get RankData fail RealmId:{0} RankId:{1}", realmId, desc.rankId); //没有记录 return; } List idlist = new List(); for (int i = 0; i < rankDataOne.CurRecord.Data.Count; i++) { long uid = rankDataOne.CurRecord.Data[i]; if (rankDataOne.data.m_curRecordIDMap.TryGetValue(uid, out long index)) { ref var data = ref rankDataOne.data.m_cacheCurRecord.GetByIndex(index); if (data.data.Level <= req.LvMax && data.data.Level >= req.LvMin) { idlist.Add(uid); if (idlist.Count == 10) break; } } } if (idlist.Count > 0) { GenericUtils.Shuffle(RankServerUtils.GetRankServerData().m_app.Rand, idlist); res.Uids.Add(idlist[0]); } RankServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSGameMsgID.RankPlayerBylevelRes, ref res, packet.ObjectID); } } } }