using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using ProtoCSStruct; namespace Friend { public class FriendRankSortInfo { public long uid; public long score; } /// /// //好友排行相关 /// public static class FriendRankSvc { public static void TickFriendRank(long uid) { FriendCacheInfoStruct info = FriendOp.GetFriendInfoByUid(uid); if (info.IsNull()) { return; } bool bChg = TickCalcRankInfoWeek(info, RoleRankType.WeekWinRoundCount); bChg = bChg | TickCalcRankInfoWeek(info, RoleRankType.WeekWinChip); if(bChg) { //如果数据有变化,广播给我的所有在线好友 FriendSvc.OnFriendSelfChgBroadcastToOtherSvr(ref info); //通知客户端 FriendNotify.NotifyPlayerFriendSelfChg(ref info); } } public static void CheckAddAllRankInfo(FriendCacheInfoStruct friendInfo) { bool bChg = CheckAddAllRankInfo(friendInfo, RoleRankType.WeekWinRoundCount); bChg = bChg | CheckAddAllRankInfo(friendInfo, RoleRankType.WeekWinChip); if (bChg) { //如果数据有变化,广播给我的所有在线好友 FriendSvc.OnFriendSelfChgBroadcastToOtherSvr(ref friendInfo); } } private static bool CheckAddAllRankInfo(FriendCacheInfoStruct friendInfo, RoleRankType rankType) { DBRoleOneRankInfo info = GetRoleRankInfo(friendInfo, rankType); if(info.RankType==0) { info = new DBRoleOneRankInfo(); info.RankType = (int)rankType; info.RankScore = 0; info.LastRankTime = FriendServerUtils.GetTimeSecond(); TraceLog.Trace("CheckAddAllRankInfo add DBRoleOneRankInfo type {0}, uid {1}" , rankType, friendInfo.Self.Uid); friendInfo.SetNeedSave(true); return true; } return false; } public static DBRoleOneRankInfo GetRoleRankInfo(FriendCacheInfoStruct friendInfo, RoleRankType rankType) { DBRoleOneRankInfo info = new DBRoleOneRankInfo(); if (friendInfo.IsNull()) { return info; } return info; } /// /// /// /// /// /// 返回true表示数据变化了,重置了 private static bool TickCalcRankInfoWeek(FriendCacheInfoStruct friendInfo, RoleRankType rankType) { DBRoleOneRankInfo info = GetRoleRankInfo(friendInfo, rankType); if (info.RankType == 0) { //tick不打日志 //TraceLog.Trace("TickCalcRankInfoWeek, not rank type {0} uid {1}" // , rankType, friendInfo.Self.Uid); return false; } long nowSec = FriendServerUtils.GetTimeSecond(); if(AppTime.IsSameWeek127(nowSec, info.LastRankTime)) { return false; } //need calc TraceLog.Trace("TickCalcRankInfoWeek need calc rank list, rank type {0} uid {1}" , rankType, friendInfo.Self.Uid); //计算名次 info.Position = CalcRankListPositionWeek(friendInfo, rankType, nowSec); //保存名次计算时候的score,供其他玩家排名的时候使用 info.PositionScore = info.RankScore; //暂时注释 //info.PositionFriendCount = FriendUtils.GetActivityFriendCount(friendInfo); info.GetReward = 0; //reset info.LastRankTime = nowSec; info.RankScore = 0; friendInfo.SetNeedSave(true); return true; } //计算要注意时间同步问题,不同game的时间有可能不同,随便写的话结果有可能有问题 private static int CalcRankListPositionWeek(FriendCacheInfoStruct friendInfo, RoleRankType rankType, long nowSec) { DBRoleOneRankInfo info = GetRoleRankInfo(friendInfo, rankType); if (info.RankType == 0) { TraceLog.Error("CalcRankListPosition, not rank type {0} uid {1}", rankType, friendInfo.Self.Uid); return 0; } info.PositionListLastWeek.Clear(); //如果自己没有分数,不排行,排名是0,就是无效 if(info.RankScore == 0) { TraceLog.Trace("CalcRankListPosition, RankScore type {0} uid {1}, postion is 0 last week, so skip calc rank" , rankType, friendInfo.Self.Uid); return 0; } //自己隔了1个礼拜上线,意思是上礼拜我没有数据,排名无效 if(AppTime.GetOffsetWeeks(nowSec, info.LastRankTime) > 1) { TraceLog.Trace("CalcRankListPosition, RankScore type {0} uid {1}, not login last week, so skip calc rank" , rankType, friendInfo.Self.Uid); return 0; } List sortList = new List(); //添加自己 sortList.Add(new FriendRankSortInfo() { uid = friendInfo.Self.Uid, score = info.RankScore }); //添加好友 for (int i =0;i < friendInfo.FriendList.iCount;i++) { DBFriendOneStruct oneFriend = FriendOp.GetFriendOneByIndex(ref friendInfo, i); //非fb好友不参加排行 if(oneFriend.oneFriend.FriendType == 0) { continue; } bool bFindRankInList = false; long score = 0; if (bFindRankInList == false) { TraceLog.Trace("CalcRankListPosition, not rank data type {0} uid {1}, default score is 0" , rankType, friendInfo.Self.Uid); } else { FriendRankSortInfo sortInfo = new FriendRankSortInfo(); sortInfo.uid = oneFriend.oneFriend.Uid; sortInfo.score = score; sortList.Add(sortInfo); } } //降序排序 IEnumerable query = from items in sortList orderby items.score descending select items; //我的排名是第几名 int postion = 1; bool alreadyGetMyPos = false; foreach (var sortedItem in query) { if(sortedItem.uid == friendInfo.Self.Uid) { alreadyGetMyPos = true; } else { if (alreadyGetMyPos == false) { postion++; } } info.PositionListLastWeek.Add((uint)sortedItem.uid); } TraceLog.Trace("CalcRankListPositionWeek rank type {0} uid {1} position {2}" , rankType, friendInfo.Self.Uid, postion); return postion; } public static void OnFriendPlayerStatChgNotify(uint remoteAppID, StructPacket packet) { long uid = packet.ObjectID; ref SSFriendPlayerStatChgNotify notify =ref packet.GetMessage(); OnDailyStatisticsChanged(uid, notify.Statid, notify.NewValue, notify.Change); } public static void OnDailyStatisticsChanged(long uid, int statid, long newValue, long change) { PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(uid); if (player == null) { TraceLog.Error("FriendRankSvc.OnDailyStatisticsChanged can not find player uid {0}", uid); return; } FriendCacheInfoStruct friendInfo = FriendOp.GetFriendInfoByUid(player.UserID); if (friendInfo.IsNull()) { TraceLog.Debug("FriendRankSvc.OnDailyStatisticsChanged uid {0} no data in cache" , player.UserID); return; } TraceLog.Trace("FriendRankSvc.OnDailyStatisticsChanged uid {0} id {1} newvalue {2}" , friendInfo.Self.Uid, statid, newValue); } } }