using asap.core; using cfg; using game; using GameCore; using System; using System.Collections.Generic; using System.Linq; using UniRx; using UniRx.Triggers; using UnityEngine; public struct FaceGiftUIData { public FaceGiftUIData(UIType faceUI, int redirectID, int sort) { this.faceUI = faceUI; this.redirectID = redirectID; this.sort = sort; } public int sort; public UIType faceUI; public int redirectID; } public struct FaceCustomUIData { public FaceCustomUIData(UIType faceUI) { this.faceUI = faceUI; } public UIType faceUI; } public class FaceUICloseEvent { } public class PostFaceUICloseEvent { } public interface IFaceUIService { void AddFaceCustomUIData(UIType faceUI, bool forceAdd = false); void ShowFaceUI(string uiName = ""); void AddGiftFaceUIForce(int id, UIType faceUI); void AddGiftFaceUIOnLogin(int id, UIType faceUI, int sort); void AddGiftFaceUI(int id, UIType faceUI, int sort = 0); int GetFaceUICount(); void StopFaceUI(); void AddPostFaceUI(UIType faceUI); void ShowPostFaceUI(); int GetPostFaceUICount(); void StopPostFaceUI(); } public class FaceUIService : IFaceUIService { List FaceGiftUIDatas = new List(); Queue faceCustomUIDatas = new Queue(); List loginFaceMarks = new List(); Dictionary pendingPersistMarks = new Dictionary(); bool isFace; public int GetFaceUICount() { return FaceGiftUIDatas.Count + faceCustomUIDatas.Count; } void RemoveFace(string uiName) { if (string.IsNullOrEmpty(uiName)) { return; } if (faceCustomUIDatas.Count > 0) { var data = faceCustomUIDatas.Peek(); if (UITypes.GetUIType(data.faceUI.Name) == UITypes.GetUIType(uiName)) { ClearPendingFaceMark(data.faceUI); faceCustomUIDatas.Dequeue(); return; } } if (FaceGiftUIDatas.Count > 0) { Debug.Log("FaceUI RemoveFace :" + uiName); int result = 0;// FaceGiftUIDatas.RemoveAll(x => x.faceUI.Name == uiName); for (int i = 0; i < FaceGiftUIDatas.Count; i++) { if (UITypes.GetUIType(FaceGiftUIDatas[i].faceUI.Name) == UITypes.GetUIType(uiName)) { ClearPendingFaceMark(FaceGiftUIDatas[i].faceUI); FaceGiftUIDatas.RemoveAt(i); result = 1; break; } } if (result > 0) { return; } } } public void ShowFaceUI(string uiName = "NULL") { CurRewardQCount curRewardQCount = new CurRewardQCount(); if (uiName != "NULL") { GContext.Publish(curRewardQCount); RemoveFace(uiName); #if UNITY_EDITOR if (PlayerPrefs.GetInt($"P_CleanFace", 0) == 1) { FaceGiftUIDatas.Clear(); faceCustomUIDatas.Clear(); } #endif } //触发礼包拍脸 if (isFace) { return; } //不在配置中的拍脸 if (faceCustomUIDatas.Count > 0 && curRewardQCount.count == 0) { var data = faceCustomUIDatas.Peek(); ShowUI(data.faceUI); return; } if (FaceGiftUIDatas.Count > 0 && curRewardQCount.count == 0) { var data = FaceGiftUIDatas[0]; ShowUI(data.faceUI); return; } Dispose(); GContext.Publish(new FaceUICloseEvent()); } async void ShowUI(UIType ui_type) { isFace = true; string uiname = ui_type.Name; Debug.Log("FaceUI Show :" + uiname); GameObject go = await UIManager.Instance.ShowUIPack(ui_type); if (go == null) { isFace = false; ClearPendingFaceMark(ui_type); ShowFaceUI(uiname); loginFaceMarks.Remove(ui_type.Name); } else { PersistPendingFaceMark(ui_type); UINAMEW = uiname; Dispose(); showCompleteEvent = go.OnDestroyAsObservable().Subscribe(_ => { Debug.Log("FaceUI Close :" + uiname); isFace = false; ShowFaceUI(uiname); }); } } string UINAMEW; IDisposable showCompleteEvent; void Dispose() { if (showCompleteEvent != null) { showCompleteEvent.Dispose(); showCompleteEvent = null; } } //打断拍脸 public void StopFaceUI() { Debug.Log("StopFaceUI :" + UINAMEW); isFace = false; Dispose(); RemoveFace(UINAMEW); UINAMEW = ""; } public void AddFaceCustomUIData(UIType faceUI, bool forceAdd = false) { int day = ZZTimeHelper.UtcNow().UtcNowOffset().DayOfYear; bool idAdd = TryMarkFacePending(faceUI, day); if (idAdd || forceAdd) { FaceCustomUIData faceUIData = new FaceCustomUIData(faceUI); faceCustomUIDatas.Enqueue(faceUIData); } } /// /// 调用拍脸不受限制 /// /// /// /// public void AddGiftFaceUIForce(int id, UIType faceUI) { //forceAdd 可能多个活动用同一个界面,所以使用有时不能用界面名判断 用 id 判断 if (FaceGiftUIDatas.Where(_ => _.redirectID == id).Count() > 0) { return; } AddFaceGiftUIData(id, faceUI, 10000); } public void AddGiftFaceUI(int id, UIType faceUI, int sort = 0) { //可能多个活动用同一个界面,所以使用有时不能用界面名判断 用 id 判断 if (FaceGiftUIDatas.Where(_ => _.faceUI == faceUI).Count() > 0) { return; } PopupType popupType = PopupType.PopupDaily; bool idAdd = false; FishingEvent fishingEvent = GContext.container.Resolve().TbFishingEvent.GetOrDefault(id); if (fishingEvent != null) { popupType = fishingEvent.PopupType; sort = fishingEvent.PopupPriority; } switch (popupType) { case PopupType.PopupSpecial: idAdd = true; break; case PopupType.PopupLogin: if (!loginFaceMarks.Contains(faceUI.Name)) { loginFaceMarks.Add(faceUI.Name); idAdd = true; } break; case PopupType.PopupDaily: int day = ZZTimeHelper.UtcNow().UtcNowOffset().DayOfYear; idAdd = TryMarkFacePending(faceUI, day); break; case PopupType.PopupEvent: idAdd = TryMarkFacePending(faceUI, id); break; default: break; } if (!idAdd) { return; } AddFaceGiftUIData(id, faceUI, sort); } /// /// 每次登录拍一次脸 /// /// /// /// public void AddGiftFaceUIOnLogin(int id, UIType faceUI, int sort) { if (!loginFaceMarks.Contains(faceUI.Name) && FaceGiftUIDatas.Where(_ => _.faceUI == faceUI).Count() <= 0) { loginFaceMarks.Add(faceUI.Name); AddFaceGiftUIData(id, faceUI, sort); } } void AddFaceGiftUIData(int id, UIType faceUI, int sort) { if (string.IsNullOrEmpty(faceUI.Path)) { Debug.LogError($"[FaceUIService]AddFaceGiftUIData: UIType path is null or empty: {faceUI.Name}"); return; } FaceGiftUIData faceUIData = new FaceGiftUIData(faceUI, id, sort); FaceGiftUIDatas.Add(faceUIData); FaceGiftUIDatas.Sort((a, b) => b.sort.CompareTo(a.sort)); } string GetFacePersistKey(UIType faceUI) { string userID = GContext.container.Resolve().UserId; return $"P_{faceUI.Name}_{userID}"; } bool TryMarkFacePending(UIType faceUI, int persistValue) { string key = GetFacePersistKey(faceUI); if (PlayerPrefs.GetInt(key, 0) == persistValue) { return false; } if (pendingPersistMarks.TryGetValue(key, out int pendingValue) && pendingValue == persistValue) { return false; } pendingPersistMarks[key] = persistValue; return true; } void PersistPendingFaceMark(UIType faceUI) { string key = GetFacePersistKey(faceUI); if (!pendingPersistMarks.TryGetValue(key, out int persistValue)) { return; } PlayerPrefs.SetInt(key, persistValue); pendingPersistMarks.Remove(key); } void ClearPendingFaceMark(UIType faceUI) { pendingPersistMarks.Remove(GetFacePersistKey(faceUI)); } #region PostFace - 后置拍脸队列,在现有拍脸链和 Buff 展示全部完成后依次弹出 readonly Queue postFaceQueue = new Queue(); bool isPostFaceShowing; string postFaceCurrentUIName; IDisposable postFaceShowCompleteEvent; public void AddPostFaceUI(UIType faceUI) { if (postFaceQueue.Any(x => UITypes.GetUIType(x.Name) == UITypes.GetUIType(faceUI.Name))) { return; } postFaceQueue.Enqueue(faceUI); Debug.Log("PostFaceUI Add :" + faceUI.Name + " count:" + postFaceQueue.Count); } public int GetPostFaceUICount() { return postFaceQueue.Count; } public void ShowPostFaceUI() { if (isPostFaceShowing) { return; } if (postFaceQueue.Count > 0) { var uiType = postFaceQueue.Dequeue(); ShowPostUI(uiType); } else { GContext.Publish(new PostFaceUICloseEvent()); } } async void ShowPostUI(UIType uiType) { isPostFaceShowing = true; postFaceCurrentUIName = uiType.Name; Debug.Log("PostFaceUI Show :" + postFaceCurrentUIName); GameObject go = await UIManager.Instance.ShowUIPack(uiType); if (go == null) { isPostFaceShowing = false; ShowPostFaceUI(); } else { DisposePostFaceShowEvent(); postFaceShowCompleteEvent = go.OnDestroyAsObservable().Subscribe(_ => { Debug.Log("PostFaceUI Close :" + postFaceCurrentUIName); isPostFaceShowing = false; ShowPostFaceUI(); }); } } void DisposePostFaceShowEvent() { if (postFaceShowCompleteEvent != null) { postFaceShowCompleteEvent.Dispose(); postFaceShowCompleteEvent = null; } } public void StopPostFaceUI() { isPostFaceShowing = false; DisposePostFaceShowEvent(); postFaceCurrentUIName = ""; } #endregion }