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 _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(); _friendService = GContext.container.Resolve(); // _eventPartnerData = GContext.container.Resolve(); _scrollViewInfoList = new List(); _recommendList = new List(); _friendList = new List(); _invitationList = new List(); _userService = GContext.container.Resolve(); emptyGo.SetActive(false); loadingGo.SetActive(false); EventPartnerAct.Ctx.EventAggregator.GetEvent().Subscribe(e => _ = OnInvite(e.Info)).AddTo(this); EventPartnerAct.Ctx.EventAggregator.GetEvent().Subscribe(e => OnIgnore(e.Info.PlayfabId)).AddTo(this); InitScrollViewAsync(); GContext.container.Resolve().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().OpenFishingSocialPanel(1); } private async System.Threading.Tasks.Task OnInvite(ScrollViewItemInfo invitationInfo) { var _eventPartnerData = GContext.container.Resolve(); if (_eventPartnerData.IsFullyMatched) { Debug.Log("[EventPartner]Cannot invite. Player fully matched."); 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.AcceptUrl, request); if (response.State != EventPartnerData.EEventBuildState.Success) { Debug.Log($"[EventPartner] Fail to add {partnerId}, {response.State}: {response.ErrorMessage}"); return; } if (response.SlotId == null || response.SlotId.Value == -1) { Debug.Log($"[EventPartner]Fail to add bot {invitationInfo.PlayfabId}"); return; } slotId = response.SlotId.Value; EventPartnerBot.AddBot(invitationInfo, slotId); _eventPartnerData.ToPlayfabData().Save(); GContext.container.Resolve().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.InviteUrl, request); if (response.State != EventPartnerData.EEventBuildState.Success) { Debug.Log($"[EventPartner]{response.State}: {response.ErrorMessage}"); // 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(); _eventPartnerData.Cache.ListInvitation.Add(invitationInfo); BuildScrollViewInfoList(); _eventPartnerData.SavePlayerPreferenceData(); ReloadScrollViewData(); _eventPartnerData.AddInvitationCount(); } private void OnIgnore(string partnerId) { var _eventPartnerData = GContext.container.Resolve(); _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($"[EventPartner]Try get recommend list."); _recommendList = await GetRecommendList(); // Debug.Log($"[EventPartner]Try get friend list."); _friendList = GetFriendList(); // Debug.Log($"[EventPartner]Try get invitation list."); _invitationList = GetInvitationList(); // Debug.Log($"[EventPartner]Build data."); BuildScrollViewInfoList(); // Debug.Log($"[EventPartner]Set delegate."); scrollView.Delegate = this; // Debug.Log($"[EventPartner]Reset."); loadingGo.SetActive(false); ReloadScrollViewData(); } catch (Exception e) { Debug.LogError($"[EventPartner]{e.Message}"); throw; } } private async System.Threading.Tasks.Task> GetRecommendList() { var recommendList = new List(); var _eventPartnerData = GContext.container.Resolve(); 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().TbEventPartnerConfig.FriendRecommendListRefreshTime); c.RecommendListExpireTime = c.RecommendListExpireTime < _eventPartnerData.EndTime ? c.RecommendListExpireTime : _eventPartnerData.EndTime; c.Recommend = recommendList; return recommendList; } private async System.Threading.Tasks.Task> GetPlayerRecommendList(int count) { var recommendList = new List(); // 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(); request.MinLevel = int.Parse(GContext.container.Resolve().TbFishingEvent[_eventPartnerData.EventId].ConditionList[0].Param[0]); var excludeSet = new HashSet(); // 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(excludeSet); RecommendResponse recommendResponse; recommendResponse = await _customServerMgr.EventPartnerRequest(EventPartnerData.RecommendUrl, request); if (recommendResponse.State != (int)EventPartnerData.EEventBuildState.Success) { Debug.Log($"Recommend Request failed: {recommendResponse.State}"); return recommendList; } foreach (var info in recommendResponse.Players) GContext.container.Resolve().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 GetBotRecommendList(int count) { var botTable = GContext.container.Resolve().TbRobot; var recommendList = new HashSet(); var _eventPartnerData = GContext.container.Resolve(); 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($"Robot: No.{randomBot.ID} {randomBot.Name}"); } return recommendList; } private List GetFriendList() { var friendList = _friendService.FriendList; var _eventPartnerData = GContext.container.Resolve(); var pendingSet = _eventPartnerData.InvitePartners; var newList = new List(); // Debug.Log($"[EventPartner] DataHash from null stuff: {_eventPartnerData.GetHashCode()}"); 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 GetInvitationList() { var res = new List(); var _eventPartnerData = GContext.container.Resolve(); 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("[EventPartner] Cell view as title is null."); 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("[EventPartner] Cell view as item is null."); 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("[EventPartner]Build Title."); foreach (var info in _recommendList) { _scrollViewInfoList.Add(info); // Debug.Log($"[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}"); } } if (_friendList is not null && _friendList.Count > 0) { _scrollViewInfoList.Add(new ScrollViewItemInfo { Type = EScrollViewType.Title, Title = LocalizationMgr.GetText(FriendTitleKey) }); // Debug.Log("[EventPartner]Build Title."); foreach (var info in _friendList) { _scrollViewInfoList.Add(info); // Debug.Log($"[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}"); } } if (_invitationList is not null && _invitationList.Count > 0) { _scrollViewInfoList.Add(new ScrollViewItemInfo { Type = EScrollViewType.Title, Title = LocalizationMgr.GetText(InvitationTitleKey) }); // Debug.Log("[EventPartner]Build Title."); foreach (var info in _invitationList) { _scrollViewInfoList.Add(info); // Debug.Log($"[EventPartner]Build {info.DisplayName}: {info.LastLoginTime}"); } } } private void ReloadScrollViewData() { scrollView.ReloadData(); if (_scrollViewInfoList.Count <= 1) { emptyGo.SetActive(true); } } #endregion }