/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using ProtoCSStruct; using System.Reflection.Metadata.Ecma335; namespace Game { public class RankSvc { public static void TickRoleRankData(PlayerOnGame player, long nowSec) { //60s一次 if (player.lastSynRankDataTime + 60 > nowSec) { return; } player.lastSynRankDataTime = nowSec; SynRoleRankData(player); } 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 SynRoleRankData(PlayerOnGame player) { SSSynRoleRankData synData = new SSSynRoleRankData(); SSSynRoleRankData kfSynData = new SSSynRoleRankData(); int bigRealmId = player.GetBigReamlId(); for (int i = 0; i < player.RoleData.RankData.List.Count; ++i) { ref var oneData = ref player.RoleData.RankData.List[i]; if (CheckIsKfRank(oneData.RankID)) { if (CheckNeedSendToRank(player, oneData.RankID, oneData.RankScore)) { kfSynData.List.Add(ref oneData); } } else { if (CheckNeedSendToRank(player, oneData.RankID, oneData.RankScore)) { synData.List.Add(ref oneData); } } } if (synData.List.Count > 0) { synData.Uid = player.UserID; synData.RealmId = player.RealmID; synData.Level = player.GetLevel(); synData.Gender = player.GetGender(); synData.Nick.SetString(player.GetNick()); synData.Icon.SetString(player.GetIcon()); synData.IconFrameId = player.GetIconFrame(); GameServerUtils.GetPacketSender().SendToRankServer((int)SSGameMsgID.SynRoleRankData, ref synData, player.UserID); } if (kfSynData.List.Count > 0) { kfSynData.Uid = player.UserID; kfSynData.RealmId = bigRealmId; kfSynData.Level = player.GetLevel(); kfSynData.Gender = player.GetGender(); kfSynData.Nick.SetString(player.GetNick()); kfSynData.Icon.SetString(player.GetIcon()); kfSynData.IconFrameId = player.GetIconFrame(); GameServerUtils.GetPacketSender().SendToRankServer((int)SSGameMsgID.SynRoleRankData, ref kfSynData, player.UserID); } } public static bool TryGetRankScore(PlayerOnGame player, int rankid, out long score) { score = 0; for (int i = 0; i < player.RoleData.RankData.List.Count; ++i) { ref RankOneData one = ref player.RoleData.RankData.List[i]; if (one.RankID == rankid) { score = one.RankScore; return true; } } return false; } public static int GetRankIndex(PlayerOnGame player, int rankid) { for (int i = 0; i < player.RoleData.RankData.List.Count; ++i) { ref RankOneData one = ref player.RoleData.RankData.List[i]; if (one.RankID == rankid) { return i; } } return -1; } //检查需要缓存 public static bool CheckNeedCache(int rankId) { if (rankId == 1) return true; return false; } //检查能领奖 public static bool CheckGetAward(int mainType) { //return mainType == (int)RankMainType.TimeRecord; return false; } //更新自身缓存的排行榜分数 public static void UpdateRankScore(PlayerOnGame player, int rankid, long score, int param = 0, bool cache = true) { RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankid); if (rankDesc == null) { return; } //被过滤的GM号就不上排行榜了 if (GmCmdSvc.IsGMFilter(player.UserID)) { return; } //需要缓存 if (cache && CheckNeedCache(rankDesc.rankId)) { //处理角色身上的缓存 bool sortLess = rankDesc.sortByLess == 1; int index = GetRankIndex(player, rankid); if (index >= 0) { long oldScore = player.RoleData.RankData.List[index].RankScore; long oldParam = player.RoleData.RankData.List[index].Param1; if (sortLess == true && score > oldScore) { return; } if (sortLess == false && score < oldScore) { return; } //bool sort2 = rankDesc.sortByLess1 == 1; //if (sort2 == true && param > oldParam) //{ // return; //} //if (sort2 == false && score < oldParam) //{ // return; //} player.RoleData.RankData.List[index].RankScore = score; player.RoleData.RankData.List[index].Param1 = param; player.RoleData.RankData.List[index].UpdateTime = GameServerUtils.GetTimeSecond(); //CSUpdateSelfScore notice = new CSUpdateSelfScore //{ // RankId = rankid, // SelfScore = score, //}; //player.SendToClient((int)CSGameMsgID.UpdateSelfRankscore, ref notice); if(rankid == 1) { //上报微信排行榜 var ureq = new CSUpdateWXRank { Uid = player.UserID, RankId = rankid, Score = score, UsedTime = param, Time = GameServerUtils.GetTimeMs(), }; player.SendToClient((int)CSGameMsgID.UpdateWxrank, ref ureq); } } else { if (player.RoleData.RankData.List.Count >= player.RoleData.RankData.List.GetMaxCount()) { TraceLog.Error("RankSvc.UpdateRankScore data full role:{0} rankId:{1} score:{2}", player.UserID, rankid, score); return; } RankOneData newData = new RankOneData() { RankID = rankid, RankScore = score, UpdateTime = GameServerUtils.GetTimeSecond(), }; player.RoleData.RankData.List.Add(ref newData); } } SendRankInfoToRank(rankid, score, player, param, cache); } //更新成功上榜的分数 public static void UpdateRankSuccessScore(PlayerOnGame player, int rankid, long score) { int index = GetRankIndex(player, rankid); if (index < 0) { TraceLog.Error("RankSvc.UpdateRankSuccessScore fail uid:{0} rankId:{1}", player.UserID, rankid); return; } player.RoleData.RankData.List[index].SuccessScore = score; } public static int CreateOrUpdatePlayerRankData(PlayerOnGame player, int rankId, int score) { for (int i = 0; i < player.RoleData.RankData.List.Count; ++i) { ref RankOneData one = ref player.RoleData.RankData.List[i]; if (one.RankID == rankId) { one.RankScore = score; one.UpdateTime = GameServerUtils.GetTimeSecond(); return i; } } if (player.RoleData.RankData.List.Count >= player.RoleData.RankData.List.GetMaxCount()) { TraceLog.Error("RankSvc.CreateOrUpdatePlayerRankData data full, uid {0} rankId {1} score {2}", player.UserID, rankId, score); return -1; } RankOneData newData = new RankOneData { RankID = rankId, RankScore = score, UpdateTime = GameServerUtils.GetTimeSecond(), }; player.RoleData.RankData.List.Add(ref newData); return player.RoleData.RankData.List.Count - 1; } public static int DeletePlayerRankData(PlayerOnGame player, int rankId) { for (int i = player.RoleData.RankData.List.Count - 1; i >= 0; i--) { ref RankOneData one = ref player.RoleData.RankData.List[i]; if (one.RankID == rankId) { player.RoleData.RankData.List.RemoveAt(i); return 0; } } TraceLog.Error("RankSvc.DeletePlayerRankData uid {0} rankId {1} not find", player.UserID, rankId); return -1; } public static void SendRankInfoToRank(int rankid, long score, PlayerOnGame player, int param = 0, bool cache = true) { int realmId = player.RealmID; if (CheckIsKfRank(rankid)) { realmId = player.GetBigReamlId(); } if (!cache || CheckNeedSendToRank(player, rankid, score)) { SSAddRankDataReq req = new SSAddRankDataReq { RankId = rankid, RealmId = realmId, Uid = player.UserID, Score = score, Level = player.GetLevel(), Gender = player.GetGender(), IconFrameId = player.GetIconFrame(), Param = param, Power = player.RoleBase.Power, WingskinId = player.RoleData.WingData.Wing.SkinId, WingrefitId = player.RoleData.WingData.Wing.RefitId, WingwearId = player.RoleData.WingData.Wing.WearId, }; req.Nick.SetString(player.GetNick()); req.Icon.SetString(player.GetIcon()); req.Skin = player.RoleData.Skin.NowSkin; for(int i = 0; i < player.RoleData.Knight.DbHero.WearEquip.Count; ++i) { if (player.RoleData.Knight.DbHero.WearEquip[i].Pos == (int)EquipmentPos.LeftGun) { req.Weapon1 = player.RoleData.Knight.DbHero.WearEquip[i].DescId; break; } } GameServerUtils.GetPacketSender().SendToRankServer((int)SSGameMsgID.AddRankDataReq, ref req, player.UserID); } } //判断需不需要发到排行榜服务器 public static bool CheckNeedSendToRank(PlayerOnGame player, int rankId, long score) { var rankDesc = RankConfigDescMgr.Instance.GetConfig(rankId); if (rankDesc == null) { return false; } int reamlId = player.RealmID; if (CheckIsKfRank(rankId)) { reamlId = player.GetBigReamlId(); } var rankInfo = GameServerUtils.GetGameRankInfo(reamlId); if (rankInfo == null) { TraceLog.Error("RankSvc.CheckNeedSendToRank no find rankInfo {0} {1}", reamlId, rankId); return false; } if (score == 0 || rankInfo.m_stopUpdateRank.ContainsKey(rankId)) { return false; } bool sortByLess = rankDesc.sortByLess == 1; //检查限制分数 if (rankInfo.m_rankLimitInfo.ContainsKey(rankId)) { var info = rankInfo.m_rankLimitInfo[rankId]; if (info.limitScore > 0) { //顺序排 小于 if (sortByLess == true && score >= info.limitScore) { return false; } //逆序排 大于 if (sortByLess == false && score <= info.limitScore) { return false; } } } //检查成功分数 int cacheIndex = GetRankIndex(player, rankId); if (cacheIndex >= 0) { long successScore = player.RoleData.RankData.List[cacheIndex].SuccessScore; //顺序排 小于 if (sortByLess == true && score >= successScore) { return false; } //逆序排 大于 if (sortByLess == false && score <= successScore) { return false; } } return true; } //添加停止更新的榜 public static void AddStopUpdateRank(GameRankInfo rankInfo, int rankId) { rankInfo.m_stopUpdateRank.TryAdd(rankId, true); TraceLog.Trace("RankSvc.AddStopUpdateRank rank:{0}", rankId); } //更新榜的限制分数 public static void UpdateRankLimitScore(GameRankInfo rankInfo, int rankId, long score) { if (score != 0 && rankInfo.m_rankLimitInfo.ContainsKey(rankId)) { rankInfo.m_rankLimitInfo[rankId].limitScore = score; } TraceLog.Trace("RankSvc.UpdateRankLimitScore rank:{0} limint:{1}", rankId, score); } //添加能领奖的排行榜 public static void AddCanAwardRank(GameRankInfo rankInfo, int rankID) { RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(rankID); //检查能领奖 if (rankDesc == null || CheckGetAward(rankDesc.reasonType) == false) { return; } if (rankInfo.m_canAwardRank.TryAdd(rankID, true)) { TraceLog.Trace("RankSvc.AddCanAwardRank rank:{0} ", rankID); } } public static bool TryGetRankIDByMainlandID(int mainlandID, out int rankID) { if (GameRankInfo.MainlandRankMap.TryGetValue(mainlandID, out rankID)) { return true; } return false; } //添加已经领取的排行榜奖励 public static bool TryAddHaveRankAward(PlayerOnGame player, int rankID) { if (player.RoleData.RankData.HaveAwardRankList.Contains(rankID)) { return false; } if (player.RoleData.RankData.HaveAwardRankList.Count < player.RoleData.RankData.HaveAwardRankList.GetMaxCount()) { player.RoleData.RankData.HaveAwardRankList.Add(rankID); return true; } else { TraceLog.Error("RankSvc.TryAddHaveRankAward num is full role:{0}", player.UserID); } return false; } //判断角色能不能领取排行榜奖励 public static bool CheckPlayGetRankAward(PlayerOnGame player, int rankID) { int realmId = player.RealmID; if (CheckIsKfRank(rankID)) { realmId = player.GetBigReamlId(); } var rankInfo = GameServerUtils.GetGameRankInfo(realmId); if (rankInfo == null) { TraceLog.Error("RankSvc.CheckPlayGetRankAward no find rankInfo {0}", realmId); return false; } if (rankInfo.m_canAwardRank.ContainsKey(rankID) && (!player.RoleData.RankData.HaveAwardRankList.Contains(rankID))) { return true; } return false; } public static void OnQueryRankListReq(PlayerOnGame player, StructPacket packet) { ref CSQueryRankListReq req = ref packet.GetMessage(); req.RealmId = player.RealmID; req.BigRealmId = player.GetBigReamlId(); GameServerUtils.GetPacketSender().SendToRankServer(packet, player.UserID); } public static void OnQueryRankTopReq(PlayerOnGame player, StructPacket packet) { ref CSQueryRankTopReq req = ref packet.GetMessage(); req.RealmId = player.RealmID; req.BigRealmId = player.GetBigReamlId(); GameServerUtils.GetPacketSender().SendToRankServer(packet, player.UserID); } public static void OnQueryRankSelfReq(PlayerOnGame player, StructPacket packet) { ref CSQueryRankSelfReq req = ref packet.GetMessage(); req.RealmId = player.RealmID; req.BigRealmId = player.GetBigReamlId(); GameServerUtils.GetPacketSender().SendToRankServer(packet, player.UserID); } public static void OnQueryActRankListReq(PlayerOnGame player, StructPacket packet) { ref CSQueryActRankListReq req = ref packet.GetMessage(); req.RealmId = player.RealmID; req.BigRealmId = player.GetBigReamlId(); GameServerUtils.GetPacketSender().SendToRankServer(packet, player.UserID); } public static void OnAddRankDataRes(StructPacket packet) { ref SSAddRankDataRes res = ref packet.GetMessage(); var rankInfo = GameServerUtils.GetGameRankInfo(res.RealmId); if (rankInfo == null) { TraceLog.Error("RankSvc.OnAddRankDataRes realm {0} no rankInfo", res.RealmId); return; } RankConfigDesc rankDesc = RankConfigDescMgr.Instance.GetConfig(res.RankId); if (rankDesc == null) { return; } PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(res.Uid); TraceLog.Trace("RankSvc.OnAddRankDataRes rankId {0} ret {1}", res.RankId, res.Ret); switch ((CSErrCode)res.Ret) { case CSErrCode.None: //添加成功 if (player != null && CheckNeedCache(rankDesc.rankId)) { RankSvc.UpdateRankSuccessScore(player, res.RankId, res.Score); } break; case CSErrCode.RankStopUpdate: RankSvc.AddStopUpdateRank(rankInfo, res.RankId); break; case CSErrCode.RankScoreLimit: if (res.LimintScore > 0) { RankSvc.UpdateRankLimitScore(rankInfo, res.RankId, res.LimintScore); } break; } } public static void OnNoticeRankChange(StructPacket packet) { ref CSNoticeRankChange msg = ref packet.GetMessage(); BasePacketHandler.BroadcastToGate(msg.RealmId, packet.MsgID, ref msg); TraceLog.Trace("RankSvc.OnNoticeRankChange realmId:{0} rankType:{1}", msg.RealmId, msg.RankId); } public static void OnQueryRankListRes(StructPacket packet) { PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(packet.ObjectID); if (player == null) { TraceLog.Error("RankSvc.OnQueryRankListRes no player:{0}", packet.ObjectID); return; } ref CSQueryRankListRes msg = ref packet.GetMessage(); if (RankSvc.TryGetRankScore(player, msg.RankId, out long selfScore)) { msg.SelfScore = selfScore; } player.SendToClient((int)CSGameMsgID.QueryRankListRes, ref msg); } public static void OnQueryRankSelfRes(StructPacket packet) { PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(packet.ObjectID); if (player == null) { TraceLog.Error("RankSvc.OnQueryRankSelfRes no player:{0}", packet.ObjectID); return; } ref CSQueryRankSelfRes msg = ref packet.GetMessage(); player.SendToClient((int)CSGameMsgID.QueryRankSelfRes, ref msg); } //请求排行榜第一名数据 public static void OnQueryRankTopRes(StructPacket packet) { PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(packet.ObjectID); if (player == null) { TraceLog.Error("RankSvc.OnQueryRankTopRes no player:{0}", packet.ObjectID); return; } ref CSQueryRankTopRes msg = ref packet.GetMessage(); for (int index = 0; index < msg.TopInfo.Count; ++index) { ref var oneInfo = ref msg.TopInfo[index]; if (oneInfo.Uid > 0) { int realmId = player.RealmID; if (CheckIsKfRank(oneInfo.RankId)) { realmId = player.GetBigReamlId(); } var rankInfo = GameServerUtils.GetGameRankInfo(realmId); if (rankInfo == null) { TraceLog.Error("RankSvc.OnQueryRankTopRes no find rankInfo {0}", realmId); } else { AddCanAwardRank(rankInfo, oneInfo.RankId); // 0 不可领取 1 可领取 2 领取成功 if (RankSvc.CheckPlayGetRankAward(player, oneInfo.RankId)) { oneInfo.CanGetAward = 1; } else { oneInfo.CanGetAward = 2; } } } } player.SendToClient((int)CSGameMsgID.QueryRankTopRes, ref msg); } public static void OnUpdateAwardRank(StructPacket packet) { ref SSUpdateAwardRank res = ref packet.GetMessage(); GameRankInfo rankInfo = GameServerUtils.GetGameRankInfo(res.RealmId); if (rankInfo == null) { TraceLog.Error("RankSvc.OnUpdateAwardRank no find rankInfo {0}", res.RealmId); return; } if (res.CleanCache == 1) { rankInfo.m_canAwardRank.Clear(); } for (int index = 0; index < res.RankList.Count; ++index) { int rankId = res.RankList[index]; AddCanAwardRank(rankInfo, rankId); } } public static void OnAddActRankDataRes(StructPacket packet) { TraceLog.Trace("RankSvc.OnAddActRankDataRes upgrade rank player:{0}", packet.ObjectID); } public static void OnQueryActRankListRes(StructPacket packet) { ref var res = ref packet.GetMessage(); TraceLog.Trace("RankSvc.OnQueryActRankListRes get rank player:{0}", packet.ObjectID); PlayerOnGame player = GameServerUtils.GetPlayerTableOp().GetPlayerByUid(packet.ObjectID); if (player == null) { return; } player.SendToClient((int)CSGameMsgID.QueryActRankListRes, ref res); } public static void TickUpgradeRank(PlayerOnGame player) { var nowTime = GameServerUtils.GetTimeSecond(); if (player.LastUpgradeRank > nowTime - 60) return; player.LastUpgradeRank = nowTime; TraceLog.Trace("RankSvc.TickUpgradeRank upgradeInfo player:{0}", player.UserID); } } }