Files
back_cantanBuilding/Assets/Scripts/UI/PartnerFishBowl/EventPartnerInvitationPanel.cs
2026-05-26 16:15:54 +08:00

508 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using asap.core;
using cfg;
using EnhancedUI.EnhancedScroller;
using game;
using GameCore;
using UniRx;
using UnityEngine;
using UnityEngine.UI;
using ScrollViewItemInfo = EventPartnerScrollViewItem.ScrollViewItemInfo;
using EScrollViewType = EventPartnerScrollViewItem.EScrollViewType;
using Random = UnityEngine.Random;
using RecommendResponse = EventPartnerData.EventBuildRecommendPlayerResp;
using RecommendRequest = EventPartnerData.EventBuildRecommendPlayerRequest;
public class EventPartnerInvitationPanel : MonoBehaviour, IEnhancedScrollerDelegate
{
[SerializeField] private EnhancedScroller scrollView;
[SerializeField] private Button btnClose, btnAddFriends;
[SerializeField] private EventPartnerScrollViewItem scrollViewItemPrefab;
[SerializeField] private EventPartnerScrollViewTitle scrollViewTitlePrefab;
[SerializeField] private GameObject emptyGo, loadingGo;
private const string RecommendTitleKey = "UI_EventPartnerFishbowlPanel_30",
FriendTitleKey = "UI_EventPartnerFishbowlPanel_31",
InvitationTitleKey = "UI_EventPartnerFishbowlPanel_36";
private List<ScrollViewItemInfo> _scrollViewInfoList, _recommendList, _friendList, _invitationList;
private ICustomServerMgr _customServerMgr;
private FriendService _friendService;
// private EventPartnerData _eventPartnerData;
private IUserService _userService;
private void Start()
{
btnClose.onClick.AddListener(OnClickClose);
btnAddFriends.onClick.AddListener(OnClickAddFriends);
_customServerMgr = GContext.container.Resolve<ICustomServerMgr>();
_friendService = GContext.container.Resolve<FriendService>();
// _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
_scrollViewInfoList = new List<ScrollViewItemInfo>();
_recommendList = new List<ScrollViewItemInfo>();
_friendList = new List<ScrollViewItemInfo>();
_invitationList = new List<ScrollViewItemInfo>();
_userService = GContext.container.Resolve<IUserService>();
emptyGo.SetActive(false);
loadingGo.SetActive(false);
EventPartnerAct.Ctx.EventAggregator.GetEvent<EventPartnerClickInvite>().Subscribe(e => _ = OnInvite(e.Info)).AddTo(this);
EventPartnerAct.Ctx.EventAggregator.GetEvent<EventPartnerClickIgnore>().Subscribe(e => OnIgnore(e.Info.PlayfabId)).AddTo(this);
InitScrollViewAsync();
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("EventPartnerInvitePopupPanel", curPanelName: gameObject.name);
}
private async void InitScrollViewAsync()
{
await InitScrollView();
}
private void OnClickClose()
{
UIManager.Instance.DestroyUI(UITypes.EventPartnerInvitationPanel);
}
private void OnClickAddFriends()
{
//添加好友
GContext.container.Resolve<ClubService>().OpenFishingSocialPanel(1);
}
private async System.Threading.Tasks.Task OnInvite(ScrollViewItemInfo invitationInfo)
{
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
if (_eventPartnerData.IsFullyMatched)
{
Debug.Log("<color=#c191ff>[EventPartner]Cannot invite. Player fully matched.</color>");
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_80"));
RemoveItem(invitationInfo.PlayfabId);
return;
}
var partnerId = invitationInfo.PlayfabId;
int slotId = -1;
if (partnerId.EndsWith(EventPartnerBot.RobotIdentifier))
{
var request = new EventPartnerData.EventBuildPartnerRequest { partnerId = partnerId, eventId = _eventPartnerData.EventId };
var response = await _customServerMgr.EventPartnerRequest<EventPartnerData.EventBuildOperationResp>(EventPartnerData.AcceptUrl, request);
if (response.State != EventPartnerData.EEventBuildState.Success)
{
Debug.Log($"<color=#c191ff>[EventPartner] Fail to add {partnerId}, {response.State}: {response.ErrorMessage}</color>");
return;
}
if (response.SlotId == null || response.SlotId.Value == -1)
{
Debug.Log($"<color=#c191ff>[EventPartner]Fail to add bot {invitationInfo.PlayfabId}</color>");
return;
}
slotId = response.SlotId.Value;
EventPartnerBot.AddBot(invitationInfo, slotId);
_eventPartnerData.ToPlayfabData().Save();
GContext.container.Resolve<IUserService>().SetPlayInfo(partnerId, invitationInfo.DisplayName, invitationInfo.AvatarUrl);
_eventPartnerData.Components[slotId].ScheduleBotScoreAction();
EventPartnerAct.Ctx.EventAggregator.Publish(new EventPartnerMatchSuccess
{
NamePartner = invitationInfo.DisplayName,
IconPartner = invitationInfo.AvatarUrl,
NameComponent = EventPartnerAct.Ctx.Data.Components[slotId].GetComponentName(),
SlotId = slotId,
PartnerId = invitationInfo.PlayfabId
});
}
else
{
var request = new EventPartnerData.EventBuildPartnerRequest { partnerId = partnerId, eventId = _eventPartnerData.EventId };
var response = await _customServerMgr.EventPartnerRequest<EventPartnerData.EventBuildOperationResp>(EventPartnerData.InviteUrl, request);
if (response.State != EventPartnerData.EEventBuildState.Success)
{
Debug.Log($"<color=#c191ff>[EventPartner]{response.State}: {response.ErrorMessage}</color>");
// ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_80"));
RemoveItem(partnerId);
invitationInfo.IsFull = response.State == EventPartnerData.EEventBuildState.Full;
}
}
switch (invitationInfo.Type)
{
case EScrollViewType.Friend:
{
int i = 0;
while (i < _friendList.Count)
{
if (_friendList[i].PlayfabId == partnerId)
_friendList.RemoveAt(i);
i++;
}
break;
}
case EScrollViewType.Recommendation:
{
int i = 0;
while (i < _recommendList.Count)
{
if (_recommendList[i].PlayfabId == partnerId)
_recommendList.RemoveAt(i);
i++;
}
i = 0;
while (i < _eventPartnerData.Cache.Recommend.Count)
{
if (_eventPartnerData.Cache.Recommend[i].PlayfabId == partnerId)
_eventPartnerData.Cache.Recommend.RemoveAt(i);
i++;
}
break;
}
}
if (_eventPartnerData.InvitePartners.Contains(partnerId))
return;
_eventPartnerData.InvitePartners.Add(partnerId);
invitationInfo.Type = EScrollViewType.MyInvitation;
_invitationList.Add(invitationInfo);
_eventPartnerData.Cache.ListInvitation ??= new List<ScrollViewItemInfo>();
_eventPartnerData.Cache.ListInvitation.Add(invitationInfo);
BuildScrollViewInfoList();
_eventPartnerData.SavePlayerPreferenceData();
ReloadScrollViewData();
_eventPartnerData.AddInvitationCount();
}
private void OnIgnore(string partnerId)
{
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
_eventPartnerData.RefusePartners.Add(partnerId);
for (int i = 0; i < _recommendList.Count; i++)
{
if (_recommendList[i].PlayfabId != partnerId) continue;
_recommendList.RemoveAt(i);
break;
}
for (int i = 0; i < _friendList.Count; i++)
{
if (_friendList[i].PlayfabId != partnerId) continue;
_friendList.RemoveAt(i);
break;
}
for (int i = 0; i < _eventPartnerData.Cache.Recommend.Count; i++)
{
if (_eventPartnerData.Cache.Recommend[i].PlayfabId != partnerId) continue;
_eventPartnerData.Cache.Recommend.RemoveAt(i);
break;
}
BuildScrollViewInfoList();
_eventPartnerData.SavePlayerPreferenceData();
ReloadScrollViewData();
}
#region ScrollView
[SerializeField] private float jiandaTitleHeight = 72f, jiandaItemHeight = 150f;
private async System.Threading.Tasks.Task InitScrollView()
{
try
{
loadingGo.SetActive(true);
// Debug.Log($"<color=red>[EventPartner]Try get recommend list.</color>");
_recommendList = await GetRecommendList();
// Debug.Log($"<color=red>[EventPartner]Try get friend list.</color>");
_friendList = GetFriendList();
// Debug.Log($"<color=red>[EventPartner]Try get invitation list.</color>");
_invitationList = GetInvitationList();
// Debug.Log($"<color=red>[EventPartner]Build data.</color>");
BuildScrollViewInfoList();
// Debug.Log($"<color=red>[EventPartner]Set delegate.</color>");
scrollView.Delegate = this;
// Debug.Log($"<color=red>[EventPartner]Reset.</color>");
loadingGo.SetActive(false);
ReloadScrollViewData();
}
catch (Exception e)
{
Debug.LogError($"[EventPartner]{e.Message}");
throw;
}
}
private async System.Threading.Tasks.Task<List<ScrollViewItemInfo>> GetRecommendList()
{
var recommendList = new List<ScrollViewItemInfo>();
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
var c = _eventPartnerData.Cache;
if (c.RecommendListExpireTime > ZZTimeHelper.UtcNow() && c.Recommend is not null)
{
recommendList.AddRange(c.Recommend.OrderByDescending(info => info.LastLoginTime));
return recommendList;
}
if (_eventPartnerData.DoRecommendBot)
{
recommendList.AddRange((await GetPlayerRecommendList(_eventPartnerData.RecommendCount / 2)).OrderByDescending(info => info.LastLoginTime));
var botCount = _eventPartnerData.RecommendCount - recommendList.Count;
recommendList.AddRange(GetBotRecommendList(botCount));
}
else
recommendList.AddRange((await GetPlayerRecommendList(_eventPartnerData.RecommendCount)).OrderByDescending(info => info.LastLoginTime));
// Update cache
c.RecommendListExpireTime = ZZTimeHelper.UtcNow() + TimeSpan.FromSeconds(GContext.container.Resolve<Tables>().TbEventPartnerConfig.FriendRecommendListRefreshTime);
c.RecommendListExpireTime = c.RecommendListExpireTime < _eventPartnerData.EndTime
? c.RecommendListExpireTime
: _eventPartnerData.EndTime;
c.Recommend = recommendList;
return recommendList;
}
private async System.Threading.Tasks.Task<List<ScrollViewItemInfo>> GetPlayerRecommendList(int count)
{
var recommendList = new List<ScrollViewItemInfo>();
// Either cache is expired or no previous recommend found.
var request = new RecommendRequest();
// Exclude players that do not reach level limit.
// if (EventPartnerData.DebugFlag)
// request.MinLevel = 0;
// else
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
request.MinLevel = int.Parse(GContext.container.Resolve<Tables>().TbFishingEvent[_eventPartnerData.EventId].ConditionList[0].Param[0]);
var excludeSet = new HashSet<string>();
// Exclude players that invites me.
// recommendList = oldList.Where(info => info.IsInvitationPending).ToList();
if (_eventPartnerData.RequestPartners != null)
foreach (var playfabId in _eventPartnerData.RequestPartners)
excludeSet.Add(playfabId);
// Exclude players that is matched to me.
foreach (var component in _eventPartnerData.Components.Where(component => component.PartnerId != ""))
excludeSet.Add(component.PartnerId);
// Exclude friends
foreach (var friend in _friendService.FriendList)
excludeSet.Add(friend.playFabId);
// Exclude refused ones
if (_eventPartnerData.RefusePartners is not null)
foreach (var id in _eventPartnerData.RefusePartners)
excludeSet.Add(id);
// Exclude ones that player already invited
if (_eventPartnerData.InvitePartners is not null)
foreach (var id in _eventPartnerData.InvitePartners)
excludeSet.Add(id);
request.Exclude = new List<string>(excludeSet);
RecommendResponse recommendResponse;
recommendResponse = await _customServerMgr.EventPartnerRequest<RecommendResponse>(EventPartnerData.RecommendUrl, request);
if (recommendResponse.State != (int)EventPartnerData.EEventBuildState.Success)
{
Debug.Log($"<color=red>Recommend Request failed: {recommendResponse.State}</color>");
return recommendList;
}
foreach (var info in recommendResponse.Players)
GContext.container.Resolve<IUserService>().SetPlayInfo(info.PlayFabId, info.DisplayName, info.AvatarUrl);
recommendList.AddRange(recommendResponse.Players.Select(info => new ScrollViewItemInfo
{
Type = EScrollViewType.Recommendation,
AvatarUrl = info.AvatarUrl,
DisplayName = info.DisplayName,
PlayfabId = info.PlayFabId,
Level = info.Level,
LastLoginTime = info.lastLoginTime.Value
}).Take(count));
_eventPartnerData.SavePlayerPreferenceData();
return recommendList;
}
private HashSet<ScrollViewItemInfo> GetBotRecommendList(int count)
{
var botTable = GContext.container.Resolve<Tables>().TbRobot;
var recommendList = new HashSet<ScrollViewItemInfo>();
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
var partnerIdSet = _eventPartnerData.Components.Where(c => c.IsMatched)
.Select(c => c.PartnerId).ToHashSet();
while (recommendList.Count < count)
{
var randomBot = botTable.DataList[Random.Range(0, botTable.DataList.Count)];
if (partnerIdSet.Contains(EventPartnerBot.Idx2Id(randomBot.ID)))
continue;
recommendList.Add(new ScrollViewItemInfo
{
Type = EScrollViewType.Recommendation,
AvatarUrl = randomBot.Avatar,
DisplayName = randomBot.Name,
PlayfabId = EventPartnerBot.Idx2Id(randomBot.ID),
Level = Random.Range(60, 120),
});
// Debug.Log($"<color=#ffc700>Robot: No.{randomBot.ID} {randomBot.Name}</color>");
}
return recommendList;
}
private List<ScrollViewItemInfo> GetFriendList()
{
var friendList = _friendService.FriendList;
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
var pendingSet = _eventPartnerData.InvitePartners;
var newList = new List<ScrollViewItemInfo>();
// Debug.Log($"<color=#ffc700>[EventPartner] DataHash from null stuff: {_eventPartnerData.GetHashCode()}</color>");
foreach (var info in (from friend in friendList
where friend.playFabId != _userService.UserId &&
!_eventPartnerData.RequestPartners.Contains(friend.playFabId) &&
!_eventPartnerData.RefusePartners.Contains(friend.playFabId) &&
!pendingSet.Contains(friend.playFabId) &&
_eventPartnerData.Components.All(c => c.PartnerId != friend.playFabId)
select new ScrollViewItemInfo
{
Type = EScrollViewType.Friend,
AvatarUrl = friend.avatarUrl,
DisplayName = friend.displayName,
PlayfabId = friend.playFabId,
Level = friend.value / LeadboardData.LV_MODELING,
LastLoginTime = friend.LastLogin.Value
}).OrderByDescending(info => info.LastLoginTime))
{
// if (info.IsInvitationPending)
newList.Add(info);
// else
// newList.Insert(0, info);
}
return newList;
}
private List<ScrollViewItemInfo> GetInvitationList()
{
var res = new List<ScrollViewItemInfo>();
var _eventPartnerData = GContext.container.Resolve<EventPartnerData>();
if (_eventPartnerData.Cache.ListInvitation is null)
return res;
_eventPartnerData.Cache.ListInvitation = _eventPartnerData.Cache.ListInvitation
.Where(info => _eventPartnerData.InvitePartners.Contains(info.PlayfabId))
.ToList();
foreach (var info in _eventPartnerData.Cache.ListInvitation)
{
res.Add(info);
}
// foreach (var info in _eventPartnerData.Cache.ListInvitation)
// {
// if (_eventPartnerData.InvitePartners.Contains(info.PlayfabId))
// res.Add(info);
// else
// _eventPartnerData.Cache.ListInvitation.Remove(info);
// }
return res;
}
public int GetNumberOfCells(EnhancedScroller scroller)
{
return _scrollViewInfoList.Count;
}
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
{
switch (_scrollViewInfoList[dataIndex].Type)
{
case EScrollViewType.Title:
return jiandaTitleHeight;
default:
return jiandaItemHeight;
}
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex,
int cellIndex)
{
var info = _scrollViewInfoList[dataIndex];
switch (info.Type)
{
case EScrollViewType.Title:
if (scroller.GetCellView(scrollViewTitlePrefab) is not EventPartnerScrollViewTitle cellViewTitle)
{
Debug.Log("<color=red>[EventPartner] Cell view as title is null.</color>");
return null;
}
cellViewTitle.textTitle.text = info.Title;
return cellViewTitle;
case EScrollViewType.Recommendation:
case EScrollViewType.Friend:
case EScrollViewType.MyInvitation:
if (scroller.GetCellView(scrollViewItemPrefab) is not EventPartnerScrollViewItem cellViewItem)
{
Debug.Log("<color=red>[EventPartner] Cell view as item is null.</color>");
return null;
}
cellViewItem.Init(info);
return cellViewItem;
default:
throw new ArgumentOutOfRangeException();
}
}
private void RemoveItem(string id)
{
if (_recommendList is not null)
for (int i = 0; i < _recommendList.Count; i++)
{
if (_recommendList[i].PlayfabId == id)
_recommendList.RemoveAt(i);
}
if (_friendList is not null)
for (int i = 0; i < _friendList.Count; i++)
{
if (_friendList[i].PlayfabId == id)
_friendList.RemoveAt(i);
}
BuildScrollViewInfoList();
ReloadScrollViewData();
}
private void BuildScrollViewInfoList()
{
_scrollViewInfoList.Clear();
if (_recommendList is not null && _recommendList.Count > 0)
{
_scrollViewInfoList.Add(new ScrollViewItemInfo
{
Type = EScrollViewType.Title,
Title = LocalizationMgr.GetText(RecommendTitleKey)
});
// Debug.Log("<color=#c191ff>[EventPartner]Build Title.</color>");
foreach (var info in _recommendList)
{
_scrollViewInfoList.Add(info);
// Debug.Log($"<color=#c191ff>[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}</color>");
}
}
if (_friendList is not null && _friendList.Count > 0)
{
_scrollViewInfoList.Add(new ScrollViewItemInfo
{ Type = EScrollViewType.Title, Title = LocalizationMgr.GetText(FriendTitleKey) });
// Debug.Log("<color=#c191ff>[EventPartner]Build Title.</color>");
foreach (var info in _friendList)
{
_scrollViewInfoList.Add(info);
// Debug.Log($"<color=#c191ff>[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}</color>");
}
}
if (_invitationList is not null && _invitationList.Count > 0)
{
_scrollViewInfoList.Add(new ScrollViewItemInfo
{ Type = EScrollViewType.Title, Title = LocalizationMgr.GetText(InvitationTitleKey) });
// Debug.Log("<color=#c191ff>[EventPartner]Build Title.</color>");
foreach (var info in _invitationList)
{
_scrollViewInfoList.Add(info);
// Debug.Log($"<color=#c191ff>[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}</color>");
}
}
}
private void ReloadScrollViewData()
{
scrollView.ReloadData();
if (_scrollViewInfoList.Count <= 1)
{
emptyGo.SetActive(true);
}
}
#endregion
}