Files
MinFt/Client/Assets/Scripts/UI/FaceUIService.cs
2026-04-27 12:07:32 +08:00

413 lines
11 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 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<FaceGiftUIData> FaceGiftUIDatas = new List<FaceGiftUIData>();
Queue<FaceCustomUIData> faceCustomUIDatas = new Queue<FaceCustomUIData>();
List<string> loginFaceMarks = new List<string>();
Dictionary<string, int> pendingPersistMarks = new Dictionary<string, int>();
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);
}
}
/// <summary>
/// 调用拍脸不受限制
/// </summary>
/// <param name="id"></param>
/// <param name="faceUI"></param>
/// <param name="sort"></param>
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<Tables>().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);
}
/// <summary>
/// 每次登录拍一次脸
/// </summary>
/// <param name="id"></param>
/// <param name="faceUI"></param>
/// <param name="sort"></param>
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<IUserService>().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<UIType> postFaceQueue = new Queue<UIType>();
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
}