using asap.core; using asap.playfab.async; using GameCore; using PlayFab.ClientModels; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace game { public class FriendService { [Inject] public IUserService userService { get; set; } [Inject] public ICustomServerMgr customServerMgr { get; set; } [Inject] public IRTService rts { get; set; } [Inject] public cfg.Tables tables { get; set; } public const string InviteLinkRewardCountKey = "InviteLinkRewardCount"; IDisposable linkCompletedDisposable; public void GetFriendData() { //GetFriendLeaderboard(); GetFriendList(); //GetInvitedListCount(); } #region 邀请Link相关 public int InviteLinkNumber { private set; get; } int InviteLinkRewardCount = 0; void SetLinkAwardData() { List invites = tables.TbInvite.DataList; //已经领取奖励的数量 string receiveRewardCountStr = PlayFabMgr.Instance.GetLocalData(InviteLinkRewardCountKey); int.TryParse(receiveRewardCountStr, out InviteLinkRewardCount); int canRewardCount = InviteLinkRewardCount; for (int i = InviteLinkRewardCount; i < invites.Count; i++) { //领取奖励 if (invites[i].NumInvite <= InviteLinkNumber) { canRewardCount = i + 1; } else { break; } } RedPointManager.Instance.SetRedPointState(RedPointName.Home_Invite, canRewardCount > InviteLinkRewardCount); #if AGG using (var e = GEvent.GameEvent("invite_increase")) { e.AddContent("inviteprogress", InviteLinkNumber) .AddContent("rewardprogress", InviteLinkRewardCount); } #endif } public int OnReceiveLinkAward() { int canRewardCount = InviteLinkRewardCount; List invites = tables.TbInvite.DataList; List DropIDs = new List(); for (int i = InviteLinkRewardCount; i < invites.Count; i++) { //领取奖励 if (invites[i].NumInvite <= InviteLinkNumber) { canRewardCount = i + 1; DropIDs.Add(invites[i].DropID); } else { break; } } if (InviteLinkRewardCount != canRewardCount) { GContext.container.Resolve().AddItemByDropList(DropIDs, scope: 1); GContext.Publish(new ShowData()); InviteLinkRewardCount = canRewardCount; PlayFabMgr.Instance.UpdateUserDataValue(InviteLinkRewardCountKey, InviteLinkRewardCount.ToString()); RedPointManager.Instance.SetRedPointState(RedPointName.Home_Invite, false); #if AGG using (var e = GEvent.GameEvent("invite_reward")) { e.AddContent("inviteprogress", InviteLinkNumber) .AddContent("rewardprogress", InviteLinkRewardCount); } #endif } return InviteLinkRewardCount; } #endregion 邀请Link相关 #region 判断是否好友 public bool IsFriend(string playFabID) { if (m_FriendList == null || m_FriendList.Count < 1 || string.IsNullOrEmpty(playFabID)) return false; foreach (var friend in m_FriendList) { if (friend.playFabId.Equals(playFabID)) { return true; } } return false; } #endregion #region 获取好友列表 private List m_FriendList = new List(); public List FriendList { get { return m_FriendList; } } public async void GetFriendLeaderboard() { string leaderboardNaem = LeadboardData.leadboardLevelName; int maxCount = 100; GetFriendLeaderboardRequest getFriendLeaderboardRequest = new GetFriendLeaderboardRequest() { StartPosition = 0, StatisticName = leaderboardNaem, MaxResultsCount = maxCount, ProfileConstraints = new PlayerProfileViewConstraints() { ShowAvatarUrl = true, ShowDisplayName = true, ShowLastLogin = true } }; var result = await PlayFabClientAsyncAPI.GetFriendLeaderboardAsync(getFriendLeaderboardRequest); var leaderboard = result?.Leaderboard; if (leaderboard != null) { int count = leaderboard.Count; if (count > 0) { string userId = GContext.container.Resolve().UserId; List list = new List(); foreach (var item in leaderboard) { if (userId.Equals(item.PlayFabId)) { continue; } LeadboardItemData friend = new LeadboardItemData(); if (string.IsNullOrEmpty(item.Profile.DisplayName)) { item.Profile.DisplayName = userService.GetDefaultName(item.PlayFabId); } //item.StatValue = item.StatValue / LeadboardData.LV_MODELING; friend.SetData(item); list.Add(friend); userService.SetPlayInfo(item.PlayFabId, item.Profile.DisplayName, item.Profile.AvatarUrl); } m_FriendList = list; #if AGG GEvent.SetProp("friends_count", count); GEvent.SetUserProp("friends_count", count); #endif } } } public async void GetFriendList() { GetFriendsListRequest getFriendsListRequest = new GetFriendsListRequest { ProfileConstraints = new PlayerProfileViewConstraints() { ShowAvatarUrl = true, ShowDisplayName = true, ShowStatistics = true, ShowLastLogin = true, } }; var result = await PlayFabClientAsyncAPI.GetFriendsListAsync(getFriendsListRequest); var list = result?.Friends; if (list != null) { string userId = GContext.container.Resolve().UserId; List leadboardList = new List(); int count = list.Count; foreach (FriendInfo friendInfo in list) { if (friendInfo.Profile == null) continue; var listStatistic = friendInfo.Profile.Statistics; if (listStatistic == null) continue; if (userId.Equals(friendInfo.FriendPlayFabId)) { continue; } if (string.IsNullOrEmpty(friendInfo.Profile.DisplayName)) { friendInfo.Profile.DisplayName = userService.GetDefaultName(friendInfo.FriendPlayFabId); } int level = 0; foreach (var item in listStatistic) { if (item == null) continue; if (item.Name == LeadboardData.leadboardLevelName) { //level = item.Value / LeadboardData.LV_MODELING; level = item.Value; break; } } userService.SetPlayInfo(friendInfo.FriendPlayFabId, friendInfo.Profile.DisplayName, friendInfo.Profile.AvatarUrl); LeadboardItemData friendData = new LeadboardItemData(); friendData.playFabId = friendInfo.FriendPlayFabId; friendData.displayName = friendInfo.Profile.DisplayName; friendData.avatarUrl = friendInfo.Profile.AvatarUrl; friendData.LastLogin = friendInfo.Profile.LastLogin; friendData.value = level; friendData.position = 0; friendData.rank = 0; leadboardList.Add(friendData); } leadboardList.Sort((item1, item2) => { return item2.value.CompareTo(item1.value); }); count = leadboardList.Count; for (int i = 0; i < count; ++i) { LeadboardItemData itemData = leadboardList[i]; itemData.position = i; itemData.rank = i + 1; } m_FriendList = leadboardList; GContext.Publish(new SocialFriendListChangedData()); #if AGG GEvent.SetProp("friends_count", count); GEvent.SetUserProp("friends_count", count); #endif } } #endregion #region 邀请好友 public async Task AddFriend(string playfabID) { int count = m_FriendList.Count; AddFriendReq getFriendListReq = new AddFriendReq() { MySelf = new BFriendInfo { PlayFabId = userService.UserId, AvatarUrl = userService.AvatarUrl, DisplayName = userService.DisplayName, Level = GContext.container.Resolve().lv }, MyFriendCount = count, FriendPlayFabId = playfabID, }; FriendHelper.FixBFriendInfoData(getFriendListReq.MySelf); return await customServerMgr.FriendRequest("AddFriend", getFriendListReq); } #endregion #region 搜索好友 public async Task SearchFriend(string playfabID) { SearchFriendReq searchFriendReq = new SearchFriendReq() { PlayFabId = playfabID }; return await customServerMgr.FriendRequest("SearchFriend", searchFriendReq); } #endregion #region 接受好友邀请/忽略好友邀请 // status:1:同意邀请;2:忽略, playfabID 接受/忽略 friendPlayFabID 的邀请 public async Task AcceptFriend(int status, string playfabID, string friendPlayFabID) { AcceptFriendReq acceptFriendReq = new AcceptFriendReq() { Status = status, PlayFabId = playfabID, FriendPlayFabId = friendPlayFabID }; return await customServerMgr.FriendRequest("AcceptFriend", acceptFriendReq); } #endregion #region 好友主页 public async Task GetHomePage(string playfabID, int pageNo) { GetHomePageReq getHomePageReq = new GetHomePageReq() { PlayFabId = playfabID, PageNo = pageNo }; return await customServerMgr.FriendRequest("GetHomePage", getHomePageReq); } #endregion #region 好友邀请列表&推荐列表 public async Task GetRecommendedFriends(string playfabID, int pageNo) { GetRecommendedFriendsReq acceptFriendReq = new GetRecommendedFriendsReq() { PlayFabId = playfabID, PageNo = pageNo }; return await customServerMgr.FriendRequest("GetRecommendedFriends", acceptFriendReq); } #endregion #region 获取申请成为我的朋友的列表 public async Task GetInvitedList() { return await customServerMgr.FriendRequest("GetInvitedList", ""); } #endregion #region 获取邀请自己的列表数量 public async void GetInvitedListCount() { string json = await customServerMgr.FriendRequest("GetInvitedListCount", ""); if (!string.IsNullOrEmpty(json)) { GetInvitedListCountResp getRecommendedFriendsResp = Newtonsoft.Json.JsonConvert.DeserializeObject(json); if (getRecommendedFriendsResp != null) { if (getRecommendedFriendsResp.FriendInvitedCount >= 0) { await Awaiters.NextFrame; RedPointManager.Instance.SetRedPointState(RedPointName.Home_Friend_Add, getRecommendedFriendsResp.FriendInvitedCount > 0); } else { Debug.LogWarning("[FriendService::GetInvitedListCount] FriendInvitedCount Failed:"); } if (getRecommendedFriendsResp.DeepLinkInvitedCount > 0) { InviteLinkNumber = getRecommendedFriendsResp.DeepLinkInvitedCount; SetLinkAwardData(); } } } } #endregion #region 邀请码处理 const string chars = "0M4KL3FZSTG8XCY5E6VW179A2UBDHQRIJNOP"; readonly ulong baseLength = (ulong)chars.Length; public string EncryptUlongToInvitationCode(ulong number) { StringBuilder encoded = new StringBuilder(); while (number > 0) { encoded.Insert(0, chars[(int)(number % baseLength)]); number /= baseLength; } return encoded.ToString().PadLeft(14, chars[0]); // Pad with '0' if necessary } public ulong DecryptInvitationCodeToUlong(string invitationCode) { ulong number = 0; foreach (char c in invitationCode) { number *= baseLength; number += (ulong)chars.IndexOf(c); } return number; } public string GetInvitationCodeByPlayFabID(string playFabID) { ulong code = Convert.ToUInt64(playFabID, 16); string invitationCode = EncryptUlongToInvitationCode(code); return InsertFormat(invitationCode, 3, "-"); } public string InsertFormat(string input, int interval, string value) { for (int i = interval; i < input.Length; i += interval + 1) input = input.Insert(i, value); return input; } #endregion #region 获得X天内登录过的活跃好友数量 public int GetActiveFriendCount(int xDays) { return FriendList.Count(data => data.LastLogin is not null && ZZTimeHelper.UtcNow() - data.LastLogin <= TimeSpan.FromDays(xDays)); } #endregion #region 判断当前用户是否处于被邀请状态 public async Task IsFriendWaitingForAccept(string playfabID, string friendPlayfabID) { IsFriendWaitingForAcceptReq req = new IsFriendWaitingForAcceptReq() { PlayFabId = playfabID, FriendPlayFabId = friendPlayfabID }; return await customServerMgr.FriendRequest("IsFriendWaitingForAccept", req); } #endregion #region 后台操作 List m_FriendAddPanelBackendOperationList = new List(); public void StartInvite(string playfabID) { var backendOperation = new FriendAddPanelBackendOperation(); m_FriendAddPanelBackendOperationList.Add(backendOperation); backendOperation.StartInvite(playfabID, OnInviteCallback); } public void OnInviteCallback(FriendAddPanelBackendOperation backendOperation, string playfabID, int code) { if (backendOperation != null) { backendOperation.Clear(); m_FriendAddPanelBackendOperationList.Remove(backendOperation); } } #endregion public void Release() { linkCompletedDisposable?.Dispose(); linkCompletedDisposable = null; m_FriendAddPanelBackendOperationList.Clear(); } } }