413 lines
11 KiB
C#
413 lines
11 KiB
C#
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
|
||
}
|