Files
ft/Client/Assets/Scripts/Services/FriendService.cs

494 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 Core.KV.IPlayerSaveStore SaveStore { get; set; }
[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<cfg.Invite> invites = tables.TbInvite.DataList;
//已经领取奖励的数量
string receiveRewardCountStr = SaveStore.Read(InviteLinkRewardCountKey).ValueOrThrow();
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<cfg.Invite> invites = tables.TbInvite.DataList;
List<int> DropIDs = new List<int>();
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<PlayerItemData>().AddItemByDropList(DropIDs, null);
GContext.Publish(new ShowData());
InviteLinkRewardCount = canRewardCount;
SaveStore.Write(InviteLinkRewardCountKey, InviteLinkRewardCount.ToString()).RequireAccepted();
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<LeadboardItemData> m_FriendList = new List<LeadboardItemData>();
public List<LeadboardItemData> FriendList { get { return m_FriendList; } }
public bool IsFriendListRefreshing { get; private set; } = true;
public async void GetFriendList()
{
GetFriendsListRequest getFriendsListRequest = new GetFriendsListRequest
{
ProfileConstraints = new PlayerProfileViewConstraints()
{
ShowAvatarUrl = true,
ShowDisplayName = true,
ShowStatistics = true,
ShowLastLogin = true,
}
};
var result = userService is KvUserService
? await GetKVFriendsListAsync()
: await PlayFabClientAsyncAPI.GetFriendsListAsync(getFriendsListRequest);
var list = result?.Friends;
if (list != null)
{
string userId = GContext.container.Resolve<IUserService>().UserId;
List<LeadboardItemData> leadboardList = new List<LeadboardItemData>();
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;
IsFriendListRefreshing = false;
GContext.Publish<SocialFriendListChangedData>(new SocialFriendListChangedData());
#if AGG
GEvent.SetProp("friends_count", count);
GEvent.SetUserProp("friends_count", count);
#endif
}
}
private async Task<GetFriendsListResult> GetKVFriendsListAsync()
{
var json = await customServerMgr.FriendRequest("GetFriendsList", new { });
if (string.IsNullOrEmpty(json))
{
return null;
}
try
{
var response = Newtonsoft.Json.JsonConvert.DeserializeObject<GetInvitedListResp>(json);
if (response == null || response.Code != 1 || response.Friends == null)
{
return null;
}
var friends = new List<FriendInfo>();
foreach (var serialized in response.Friends)
{
if (string.IsNullOrEmpty(serialized))
{
return null;
}
var item = Newtonsoft.Json.JsonConvert.DeserializeObject<KvFriendItem>(serialized);
if (item == null)
{
return null;
}
friends.Add(new FriendInfo { FriendPlayFabId = item.PlayFabId, Profile = item.Profile });
}
return new GetFriendsListResult { Friends = friends };
}
catch (Newtonsoft.Json.JsonException ex)
{
Debug.LogError("KV friends response failed: " + ex.GetType().Name);
return null;
}
}
private sealed class KvFriendItem
{
public string PlayFabId
{
get;
set;
}
public PlayerProfileModel Profile
{
get;
set;
}
}
#endregion
#region 邀请好友
public async Task<string> 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<PlayerData>().lv
},
MyFriendCount = count,
FriendPlayFabId = playfabID,
};
FriendHelper.FixBFriendInfoData(getFriendListReq.MySelf);
return await customServerMgr.FriendRequest("AddFriend", getFriendListReq);
}
#endregion
#region 删除好友
public async Task<bool> DeleteFriend(string friendPlayfabID)
{
var req = new FriendDeleteReq()
{
FriendPlayFabId = friendPlayfabID,
};
var json = await customServerMgr.FriendRequest("DeleteFriend", req);
if (string.IsNullOrEmpty(json)) return false;
var resp = Newtonsoft.Json.JsonConvert.DeserializeObject<FriendDeleteResp>(json);
if (resp.Code == FriendHelper.Code_OK)
{
m_FriendList.RemoveAll(f => f.playFabId == friendPlayfabID);
GContext.Publish<SocialFriendListChangedData>(new SocialFriendListChangedData());
return true;
}
return false;
}
#endregion
#region 搜索好友
public async Task<string> 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<string> 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<string> GetHomePage(string playfabID, int pageNo)
{
GetHomePageReq getHomePageReq = new GetHomePageReq()
{
PlayFabId = playfabID,
PageNo = pageNo
};
return await customServerMgr.FriendRequest("GetHomePage", getHomePageReq);
}
#endregion
#region 好友邀请列表&推荐列表
public async Task<string> GetRecommendedFriends(string playfabID, int pageNo)
{
GetRecommendedFriendsReq acceptFriendReq = new GetRecommendedFriendsReq()
{
PlayFabId = playfabID,
PageNo = pageNo
};
return await customServerMgr.FriendRequest("GetRecommendedFriends", acceptFriendReq);
}
#endregion
#region 获取申请成为我的朋友的列表
public async Task<string> 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<GetInvitedListCountResp>(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<string> IsFriendWaitingForAccept(string playfabID, string friendPlayfabID)
{
IsFriendWaitingForAcceptReq req = new IsFriendWaitingForAcceptReq()
{
PlayFabId = playfabID,
FriendPlayFabId = friendPlayfabID
};
return await customServerMgr.FriendRequest("IsFriendWaitingForAccept", req);
}
#endregion
#region 后台操作
List<FriendAddPanelBackendOperation> m_FriendAddPanelBackendOperationList = new List<FriendAddPanelBackendOperation>();
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();
}
}
}