using System.Collections.Generic; using Sog; namespace Friend { public static class FriendTickSvc { //1秒一次 private static List m_tickListFast = new List(); private static int m_tickIndexFast = 0; private static long m_lastTickTimeFast; //5秒一次 private static List m_tickListSlow = new List(); private static int m_tickIndexSlow = 0; private static long m_lastTickTimeSlow; // tick save DB private static List m_tickSaveList = new List(); private static int m_tickSaveIndex = 0; private static long m_lastTickSaveTime; // tick淘汰remote数据时间 private static long m_lastRemoteTickMs; public static void Tick(long nowMs) { // tick在线玩家 TickOnlinePlayerFast(nowMs); TickOnlinePlayerSlow(nowMs); // tick所有缓存中的数据 TickFriendInfoCacheSave(nowMs); TickRemoteFriendCache(nowMs); } private static void TickOnlinePlayerFast(long nowMs) { if (m_tickIndexFast >= m_tickListFast.Count) { if (nowMs - m_lastTickTimeFast >= 1000) { m_lastTickTimeFast = nowMs; m_tickIndexFast = 0; m_tickListFast.Clear(); var table = FriendServerUtils.GetPlayerTable().m_playerTable.Values; foreach (PlayerInfoFriend player in table) { if (player.IsOnline && player.roleBase.Uid != 0) { m_tickListFast.Add(player.UserID); } } } } for (int i = 0; i < 10; i++) { if (m_tickIndexFast >= m_tickListFast.Count) { break; } TickOnlineFriendFast(m_tickListFast[m_tickIndexFast]); m_tickIndexFast++; } } private static void TickOnlinePlayerSlow(long nowMs) { if (m_tickIndexSlow >= m_tickListSlow.Count) { if (nowMs - m_lastTickTimeSlow >= 5000) { m_lastTickTimeSlow = nowMs; m_tickIndexSlow = 0; m_tickListSlow.Clear(); var table = FriendServerUtils.GetPlayerTable().m_playerTable.Values; foreach (PlayerInfoFriend player in table) { if (player.IsOnline && player.roleBase.Uid != 0) { m_tickListSlow.Add(player.UserID); } } } } for (int i = 0; i < 1; i++) { if (m_tickIndexSlow >= m_tickListSlow.Count) { break; } TickOnlineFriendSlow(m_tickListSlow[m_tickIndexSlow]); m_tickIndexSlow++; } } public static void TickOnlineFriendFast(long uid) { FriendRankSvc.TickFriendRank(uid); TickCopyPlayerInfoToSelfData(uid, true); } public static void TickOnlineFriendSlow(long uid) { // 根据cache更新好友列表中的好友数据 FriendListDataSyncSvc.TickSync(uid, true); // 根据cache更新FriendOp列表中的好友数据 FriendOpListDataSyncSvc.TickSync(uid, true); //FriendStrangerSvc.TickDeleteStrangerIfInFriendList(uid, true); //FriendStrangerListDataSyncSvc.TickSync(uid, true); } public static void TickCopyPlayerInfoToSelfData(long uid, bool notifyClient) { PlayerInfoFriend player = FriendServerUtils.GetPlayerTableOp().GetPlayerInfo(uid); if (player == null || player.roleBase.Uid == 0) { return; } //为空是有可能的,有可能db没有加载完成 ref FriendCacheInfoStruct friendInfo = ref FriendOp.GetFriendInfoByUid(player.UserID); if (friendInfo.IsNull()) { return; } bool bChg = FriendUtils.CheckAndChangeSelfByPlayer(player, ref friendInfo.Self, ref player.roleBase); if (bChg) { TraceLog.Trace("FriendTickSvc.TickCopyPlayerInfoToSelfData self data chg uid {0}", player.UserID); friendInfo.SetNeedSave(true); if (notifyClient) { FriendNotify.NotifyPlayerFriendSelfChg(ref friendInfo); } } } //处理保存和淘汰 private static void TickFriendInfoCacheSave(long nowMs) { if (m_tickSaveIndex >= m_tickSaveList.Count) { if (nowMs - m_lastTickSaveTime >= 1000) { m_lastTickSaveTime = nowMs; m_tickSaveIndex = 0; m_tickSaveList.Clear(); foreach (var pair in FriendInfoCache.m_selfIDMap) { m_tickSaveList.Add(pair.Key); } } } int tickCount = FriendServerUtils.GetApp().IsStopping ? 100 : 20; for (int i = 0; i < tickCount; i++) { if (m_tickSaveIndex >= m_tickSaveList.Count) { break; } long uid = m_tickSaveList[m_tickSaveIndex]; CheckFriendInfoSave(uid, nowMs); if (FriendOp.CanDeleteFriendCacheInfo(uid)) { FriendOp.DeleteFriendCacheInfo(uid); } m_tickSaveIndex++; } } //定时淘汰 private static void TickRemoteFriendCache(long nowMs) { //5秒tick if (nowMs - m_lastRemoteTickMs <= 5000) { return; } m_lastRemoteTickMs = nowMs; //停服就不淘汰了 if (FriendServerUtils.GetApp().IsStopping) { return; } List removeList = new List(); foreach (var pair in FriendInfoCache.m_remoteFriendIDMap) { ref var info = ref FriendInfoCache.m_remoteFriendOneCache.GetByIndex(pair.Value); if (! info.IsNull()) { if (FriendServerUtils.GetTimeSecond() - info.LastAccessTime >= FriendConfig.GetFriendCacheTimeout()) { FriendInfoCache.m_remoteFriendOneCache.Free(pair.Value); removeList.Add(pair.Key); } } else { removeList.Add(pair.Key); } } foreach(var uid in removeList) { TraceLog.Debug("FriendTickSvc.TickRemoteFriendCache uid {0} delete cache", uid); FriendInfoCache.m_remoteFriendIDMap.Remove(uid); } } //停服的时候加快速度 private static void CheckFriendInfoSave(long Uid, long nowMs) { ref FriendCacheInfoStruct friendInfo = ref FriendOp.GetFriendInfoByUid(Uid); if (friendInfo.IsNull()) { return; } // 判断是否需要保存 if (friendInfo.GetDataSeqSave().CanDoSaveReqNow(nowMs) == false) { return; } TraceLog.Trace("FriendTickSvc.CheckFriendInfoSave uid {0} dataSeq {1} save DB now..." , friendInfo.Self.Uid, friendInfo.GetDataSeqSave().DataSeq); FriendCacheSvc.SendDBSaveFriendListReq(ref friendInfo, false); // 非停服, 保存DB的同时将自己的数据广播到其他好友服务器 if (! FriendServerUtils.GetApp().IsStopping) { FriendNotify.NotifyOtherFriendSvrFriendSelfChg(ref friendInfo.Self); } friendInfo.LastAccessTime = FriendServerUtils.GetTimeSecond(); } } }