少年修仙传客户端代码仓库
lcy
2024-11-12 85ac5362c890305472542cc4ecbb63a3d4387b46
10271 将幻境阁相关代码放到vnxbqy.UI命名空间下
17个文件已修改
5123 ■■■■■ 已修改文件
System/FairyEmblem/EmblemCell.cs 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/EmblemHelper.cs 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/FairyEmblemCell.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/FairyEmblemItem.cs 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/FairyEmblemModel.cs 538 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/FairyEmblemWin.cs 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionAttrCell.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionAvatarFrameHandler.cs 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionAvatarHandler.cs 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionChatBubbleHandler.cs 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionChatExpressionHandler.cs 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionItem.cs 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionItemCell.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionModel.cs 1989 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionTabCell.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/PhantasmPavilion/PhantasmPavilionWin.cs 640 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyEmblem/EmblemCell.cs
@@ -1,148 +1,151 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EmblemCell : MonoBehaviour
namespace vnxbqy.UI
{
    public float scale = 1.0f;
    Image m_EmblemImage;
    public Image emblemImage
    public class EmblemCell : MonoBehaviour
    {
        get
        public float scale = 1.0f;
        Image m_EmblemImage;
        public Image emblemImage
        {
            if (m_EmblemImage == null)
            get
            {
                LoadPrefab();
                m_EmblemImage = this.GetComponent<Image>("EmblemCell/Img_Emblem");
            }
            return m_EmblemImage;
        }
    }
    Button m_button;
    public Button button
    {
        get
        {
            if (m_button == null)
            {
                LoadPrefab();
                m_button = this.GetComponent<Button>("EmblemCell/Img_Emblem");
            }
            return m_button;
        }
    }
    UIFrame m_EmblemUIFrame;
    public UIFrame emblemUIFrame
    {
        get
        {
            if (m_EmblemUIFrame == null)
            {
                LoadPrefab();
                m_EmblemUIFrame = this.GetComponent<UIFrame>("EmblemCell/Img_Emblem");
            }
            return m_EmblemUIFrame;
        }
    }
    UIEffect m_EmblemUIEffect;
    public UIEffect emblemUIEffect
    {
        get
        {
            if (m_EmblemUIEffect == null)
            {
                LoadPrefab();
                m_EmblemUIEffect = this.GetComponent<UIEffect>("EmblemCell/Img_Emblem");
            }
            return m_EmblemUIEffect;
        }
    }
    GameObject prefab;
    protected void LoadPrefab()
    {
        var tmp = transform.Find("EmblemCell");
        if (tmp != null)
        {
            prefab = tmp.gameObject;
            return;
        }
        if (prefab == null)
        {
            prefab = UIUtility.CreateWidget("EmblemCell", "EmblemCell");
            if (prefab != null)
            {
                prefab.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
                prefab.transform.SetAsFirstSibling();
                RectTransform prefabRect = prefab.GetComponent<RectTransform>();
                RectTransform parentRect = GetComponent<RectTransform>();
                if (prefabRect != null && parentRect != null)
                if (m_EmblemImage == null)
                {
                    prefabRect.anchorMin = new Vector2(0.5f, 0.5f);
                    prefabRect.anchorMax = new Vector2(0.5f, 0.5f);
                    prefabRect.sizeDelta = new Vector2(parentRect.rect.width, parentRect.rect.height);
                    prefabRect.localScale = new Vector3(scale, scale, scale);
                    LoadPrefab();
                    m_EmblemImage = this.GetComponent<Image>("EmblemCell/Img_Emblem");
                }
                return m_EmblemImage;
            }
        }
        Button m_button;
        public Button button
        {
            get
            {
                if (m_button == null)
                {
                    LoadPrefab();
                    m_button = this.GetComponent<Button>("EmblemCell/Img_Emblem");
                }
                return m_button;
            }
        }
        UIFrame m_EmblemUIFrame;
        public UIFrame emblemUIFrame
        {
            get
            {
                if (m_EmblemUIFrame == null)
                {
                    LoadPrefab();
                    m_EmblemUIFrame = this.GetComponent<UIFrame>("EmblemCell/Img_Emblem");
                }
                return m_EmblemUIFrame;
            }
        }
        UIEffect m_EmblemUIEffect;
        public UIEffect emblemUIEffect
        {
            get
            {
                if (m_EmblemUIEffect == null)
                {
                    LoadPrefab();
                    m_EmblemUIEffect = this.GetComponent<UIEffect>("EmblemCell/Img_Emblem");
                }
                return m_EmblemUIEffect;
            }
        }
        GameObject prefab;
        protected void LoadPrefab()
        {
            var tmp = transform.Find("EmblemCell");
            if (tmp != null)
            {
                prefab = tmp.gameObject;
                return;
            }
            if (prefab == null)
            {
                prefab = UIUtility.CreateWidget("EmblemCell", "EmblemCell");
                if (prefab != null)
                {
                    prefab.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
                    prefab.transform.SetAsFirstSibling();
                    RectTransform prefabRect = prefab.GetComponent<RectTransform>();
                    RectTransform parentRect = GetComponent<RectTransform>();
                    if (prefabRect != null && parentRect != null)
                    {
                        prefabRect.anchorMin = new Vector2(0.5f, 0.5f);
                        prefabRect.anchorMax = new Vector2(0.5f, 0.5f);
                        prefabRect.sizeDelta = new Vector2(parentRect.rect.width, parentRect.rect.height);
                        prefabRect.localScale = new Vector3(scale, scale, scale);
                    }
                }
            }
        }
    }
    public void InitUI(EmblemModel model)
    {
        if (model == null)
            return;
        InitUI(model.emblemID, model.emblemUIEffectID);
    }
    private void InitUI(int emblemID, int emblemUIEffectID)
    {
        emblemUIEffect.Stop();
        if (!FamilyEmblemConfig.Has(emblemID))
            return;
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
        string imgStr = config.Image;
        if (UIFrameMgr.Inst.ContainsDynamicImage(imgStr))
        public void InitUI(EmblemModel model)
        {
            emblemUIFrame.ResetFrame(imgStr);
            List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(imgStr);
            if (!spriteList.IsNullOrEmpty())
            if (model == null)
                return;
            InitUI(model.emblemID, model.emblemUIEffectID);
        }
        private void InitUI(int emblemID, int emblemUIEffectID)
        {
            emblemUIEffect.Stop();
            if (!FamilyEmblemConfig.Has(emblemID))
                return;
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
            string imgStr = config.Image;
            if (UIFrameMgr.Inst.ContainsDynamicImage(imgStr))
            {
                emblemImage.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
                emblemUIFrame.ResetFrame(imgStr);
                List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(imgStr);
                if (!spriteList.IsNullOrEmpty())
                {
                    emblemImage.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
                }
                emblemUIFrame.enabled = true;
            }
            emblemUIFrame.enabled = true;
            else
            {
                emblemImage.SetSprite(imgStr);
                emblemImage.SetNativeSize();
                emblemUIFrame.enabled = false;
            }
            if (!EffectConfig.Has(emblemUIEffectID))
                return;
            emblemUIEffect.effect = emblemUIEffectID;
            emblemUIEffect.loop = true;
            emblemUIEffect.Play();
        }
        else
        {
            emblemImage.SetSprite(imgStr);
            emblemImage.SetNativeSize();
            emblemUIFrame.enabled = false;
        }
    }
        if (!EffectConfig.Has(emblemUIEffectID))
            return;
        emblemUIEffect.effect = emblemUIEffectID;
        emblemUIEffect.loop = true;
        emblemUIEffect.Play();
    }
}
public class EmblemModel
{
    public int emblemID { get; private set; }
    public int emblemUIEffectID { get; private set; }
    public EmblemModel(int emblemID, int emblemUIEffectID)
    public class EmblemModel
    {
        this.emblemID = emblemID;
        this.emblemUIEffectID = emblemUIEffectID;
        public int emblemID { get; private set; }
        public int emblemUIEffectID { get; private set; }
        public EmblemModel(int emblemID, int emblemUIEffectID)
        {
            this.emblemID = emblemID;
            this.emblemUIEffectID = emblemUIEffectID;
        }
    }
}
System/FairyEmblem/EmblemHelper.cs
@@ -1,62 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public static class EmblemHelper
namespace vnxbqy.UI
{
    static FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
    public static EmblemModel GetEmblemModel(int familyID, int id)
    public static class EmblemHelper
    {
        bool isMyself = familyID == PlayerDatas.Instance.fairyData.fairy.FamilyID;
        return isMyself ? GetMyEmblemModel() : GetOtherEmblemModel(id);
        static FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
        public static EmblemModel GetEmblemModel(int familyID, int id)
        {
            bool isMyself = familyID == PlayerDatas.Instance.fairyData.fairy.FamilyID;
            return isMyself ? GetMyEmblemModel() : GetOtherEmblemModel(id);
        }
        public static EmblemModel GetOtherEmblemModel(int id)
        {
            int emblemID = GetOtherEmblemID(id);
            int effectID = GetEmblemEffectID(emblemID);
            return new EmblemModel(emblemID, effectID);
        }
        public static EmblemModel GetMyEmblemModel()
        {
            int emblemID = GetMyEmblemID();
            int effectID = GetEmblemEffectID(emblemID);
            return new EmblemModel(emblemID, effectID);
        }
        public static int GetEmblemID(int familyID, int id)
        {
            bool isMyself = familyID == PlayerDatas.Instance.fairyData.fairy.FamilyID;
            return isMyself ? GetMyEmblemID() : GetOtherEmblemID(id);
        }
        public static int GetOtherEmblemID(int id)
        {
            if (FamilyEmblemConfig.Has(id))
                return id;
            return !FamilyEmblemConfig.Has(model.defaultFamilyEmblemId) ? 0 : model.defaultFamilyEmblemId;
        }
        public static int GetMyEmblemID()
        {
            int emblemID = (int)PlayerDatas.Instance.fairyData.fairy.Extra6;
            if (model.IsUnLock(emblemID) && FamilyEmblemConfig.Has(emblemID))
                return emblemID;
            return !FamilyEmblemConfig.Has(model.defaultFamilyEmblemId) ? 0 : model.defaultFamilyEmblemId;
        }
        public static int GetEmblemEffectID(int id)
        {
            model.TryGetEffectID(id, out int effectID);
            return effectID;
        }
        public static int GetDefaultFamilyEmblemId()
        {
            return model.defaultFamilyEmblemId;
        }
    }
    public static EmblemModel GetOtherEmblemModel(int id)
    {
        int emblemID = GetOtherEmblemID(id);
        int effectID = GetEmblemEffectID(emblemID);
        return new EmblemModel(emblemID, effectID);
    }
    public static EmblemModel GetMyEmblemModel()
    {
        int emblemID = GetMyEmblemID();
        int effectID = GetEmblemEffectID(emblemID);
        return new EmblemModel(emblemID, effectID);
    }
    public static int GetEmblemID(int familyID, int id)
    {
        bool isMyself = familyID == PlayerDatas.Instance.fairyData.fairy.FamilyID;
        return isMyself ? GetMyEmblemID() : GetOtherEmblemID(id);
    }
    public static int GetOtherEmblemID(int id)
    {
        if (FamilyEmblemConfig.Has(id))
            return id;
        return !FamilyEmblemConfig.Has(model.defaultFamilyEmblemId) ? 0 : model.defaultFamilyEmblemId;
    }
    public static int GetMyEmblemID()
    {
        int emblemID = (int)PlayerDatas.Instance.fairyData.fairy.Extra6;
        if (model.IsUnLock(emblemID) && FamilyEmblemConfig.Has(emblemID))
            return emblemID;
        return !FamilyEmblemConfig.Has(model.defaultFamilyEmblemId) ? 0 : model.defaultFamilyEmblemId;
    }
    public static int GetEmblemEffectID(int id)
    {
        model.TryGetEffectID(id, out int effectID);
        return effectID;
    }
    public static int GetDefaultFamilyEmblemId()
    {
        return model.defaultFamilyEmblemId;
    }
}
}
System/FairyEmblem/FairyEmblemCell.cs
@@ -1,29 +1,31 @@
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public class FairyEmblemCell : CellView
namespace vnxbqy.UI
{
    [SerializeField] List<FairyEmblemItem> fairyEmblemItemList = new List<FairyEmblemItem>();
    FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
    public void Display(int rowIndex)
    {
        List<int> showList = model.GetShowList();
        for (int i = 0; i < fairyEmblemItemList.Count; i++)
        {
            //索引 = 行数 * 一行展示x个徽章 + i < 徽章总数
            int index = rowIndex * model.MaxItemRowCount + i;
            if (index < showList.Count)
    public class FairyEmblemCell : CellView
    {
        [SerializeField] List<FairyEmblemItem> fairyEmblemItemList = new List<FairyEmblemItem>();
        FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
        public void Display(int rowIndex)
        {
            List<int> showList = model.GetShowList();
            for (int i = 0; i < fairyEmblemItemList.Count; i++)
            {
                int emblemId = showList[index];
                fairyEmblemItemList[i].SetActive(true);
                fairyEmblemItemList[i].Display(emblemId);
                //索引 = 行数 * 一行展示x个徽章 + i < 徽章总数
                int index = rowIndex * model.MaxItemRowCount + i;
                if (index < showList.Count)
                {
                    int emblemId = showList[index];
                    fairyEmblemItemList[i].SetActive(true);
                    fairyEmblemItemList[i].Display(emblemId);
                }
                else
                {
                    fairyEmblemItemList[i].SetActive(false);
                }
            }
            else
            {
                fairyEmblemItemList[i].SetActive(false);
            }
        }
    }
        }
    }
}
System/FairyEmblem/FairyEmblemItem.cs
@@ -1,91 +1,93 @@
using UnityEngine;
using vnxbqy.UI;
public class FairyEmblemItem : MonoBehaviour
namespace vnxbqy.UI
{
    [SerializeField] ImageEx imgEmblem;
    [SerializeField] ImageEx imgState;
    [SerializeField] ImageEx imgChoose;
    [SerializeField] TextEx txtTime;
    [SerializeField] TextEx txtState;
    [SerializeField] TextEx txtUnlockConditions;
    [SerializeField] ButtonEx btnUse;
    [SerializeField] ButtonEx btnChoose;
    [SerializeField] UIEffect uiEffect;
    int emblemId;
    FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
    public void Display(int emblemId)
    public class FairyEmblemItem : MonoBehaviour
    {
        this.emblemId = emblemId;
        if (!FamilyEmblemConfig.Has(emblemId))
            return;
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
        [SerializeField] ImageEx imgEmblem;
        [SerializeField] ImageEx imgState;
        [SerializeField] ImageEx imgChoose;
        [SerializeField] TextEx txtTime;
        [SerializeField] TextEx txtState;
        [SerializeField] TextEx txtUnlockConditions;
        [SerializeField] ButtonEx btnUse;
        [SerializeField] ButtonEx btnChoose;
        [SerializeField] UIEffect uiEffect;
        int emblemId;
        FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
        bool isUnLock = model.IsUnLock(emblemId);
        bool isUsing = model.IsUsing(emblemId);
        bool isLimitTime = model.IsLimitTime(emblemId, out var familyAction);
        txtTime.SetActive(isUnLock && isLimitTime);
        btnUse.SetActive(isUnLock && !isUsing && model.IsCaptain());
        imgChoose.SetActive(emblemId == model.nowChooseEmblemId);
        txtUnlockConditions.SetActive(!isUnLock);
        imgState.SetActive(!isUnLock || isUsing);
        uiEffect.Stop();
        if (model.TryGetEffectID(emblemId, out int effectID))
        public void Display(int emblemId)
        {
            uiEffect.effect = effectID;
            uiEffect.Play();
            this.emblemId = emblemId;
            if (!FamilyEmblemConfig.Has(emblemId))
                return;
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
            bool isUnLock = model.IsUnLock(emblemId);
            bool isUsing = model.IsUsing(emblemId);
            bool isLimitTime = model.IsLimitTime(emblemId, out var familyAction);
            txtTime.SetActive(isUnLock && isLimitTime);
            btnUse.SetActive(isUnLock && !isUsing && model.IsCaptain());
            imgChoose.SetActive(emblemId == model.nowChooseEmblemId);
            txtUnlockConditions.SetActive(!isUnLock);
            imgState.SetActive(!isUnLock || isUsing);
            uiEffect.Stop();
            if (model.TryGetEffectID(emblemId, out int effectID))
            {
                uiEffect.effect = effectID;
                uiEffect.Play();
            }
            txtUnlockConditions.text = model.GetUnlockConditionString(emblemId);
            txtState.text = isUsing ? Language.Get("TreasureSkillWin__20") : Language.Get("KnapS144");
            txtState.colorType = isUsing ? TextColType.Green : TextColType.Red;
            txtTime.text = GetEndTimeString(emblemId);
            model.ShowEmblem(emblemId, imgEmblem);
            btnChoose.SetListener(OnChooseClick);
            btnUse.SetListener(OnUseClick);
        }
        txtUnlockConditions.text = model.GetUnlockConditionString(emblemId);
        txtState.text = isUsing ? Language.Get("TreasureSkillWin__20") : Language.Get("KnapS144");
        txtState.colorType = isUsing ? TextColType.Green : TextColType.Red;
        txtTime.text = GetEndTimeString(emblemId);
        model.ShowEmblem(emblemId, imgEmblem);
        btnChoose.SetListener(OnChooseClick);
        btnUse.SetListener(OnUseClick);
    }
    private void OnUseClick()
    {
        if (!model.IsCaptain())
        private void OnUseClick()
        {
            SysNotifyMgr.Instance.ShowTip("FairyEmblem01");
            return;
            if (!model.IsCaptain())
            {
                SysNotifyMgr.Instance.ShowTip("FairyEmblem01");
                return;
            }
            model.SendCA413ChangeFamilyEmblemPack(emblemId);
        }
        model.SendCA413ChangeFamilyEmblemPack(emblemId);
    }
    private void OnChooseClick()
    {
        model.nowChooseEmblemId = emblemId;
    }
    public string GetEndTimeString(int emblemID)
    {
        FairyEmblemUnlockMethodType type = model.GetFairyEmblemUnlockType(emblemId);
        switch (type)
        private void OnChooseClick()
        {
            case FairyEmblemUnlockMethodType.LV:
                return Language.Get("FairyEmblem04", Language.Get("PhantasmPavilion03"));
            model.nowChooseEmblemId = emblemId;
        }
            case FairyEmblemUnlockMethodType.Custom:
            case FairyEmblemUnlockMethodType.Active:
                bool isLimitTime = model.IsLimitTime(emblemID, out var familyAction);
                if (!isLimitTime)
                {
        public string GetEndTimeString(int emblemID)
        {
            FairyEmblemUnlockMethodType type = model.GetFairyEmblemUnlockType(emblemId);
            switch (type)
            {
                case FairyEmblemUnlockMethodType.LV:
                    return Language.Get("FairyEmblem04", Language.Get("PhantasmPavilion03"));
                }
                else
                {
                    uint endTimeS = familyAction.Value2;
                    int subTime = (int)(familyAction.Value2 - TimeUtility.AllSeconds);
                    return Language.Get("FairyEmblem04", TimeUtility.SecondsToDHMSCHS(subTime));
                }
            default:
                return string.Empty;
                case FairyEmblemUnlockMethodType.Custom:
                case FairyEmblemUnlockMethodType.Active:
                    bool isLimitTime = model.IsLimitTime(emblemID, out var familyAction);
                    if (!isLimitTime)
                    {
                        return Language.Get("FairyEmblem04", Language.Get("PhantasmPavilion03"));
                    }
                    else
                    {
                        uint endTimeS = familyAction.Value2;
                        int subTime = (int)(familyAction.Value2 - TimeUtility.AllSeconds);
                        return Language.Get("FairyEmblem04", TimeUtility.SecondsToDHMSCHS(subTime));
                    }
                default:
                    return string.Empty;
            }
        }
    }
}
System/FairyEmblem/FairyEmblemModel.cs
@@ -1,298 +1,300 @@
using System;
using System.Collections.Generic;
using vnxbqy.UI;
//仙盟徽章 解锁途径类型
public enum FairyEmblemUnlockMethodType
namespace vnxbqy.UI
{
    Custom,     // 0 - 定制
    LV,         // 1 - 等级自动解锁
    Active,     // 2 - 活动获得
}
public class FairyEmblemModel : Model
{
    public readonly int MaxItemRowCount = 6;    // 一行展示x个徽章
    public readonly int FamilyActionsType = 15;     // 家族行为类型15
    public readonly int FuncId = 237;
    public int defaultFamilyEmblemId;           // 默认徽章ID
    public bool isSendA408Pack = false;
    private int m_NowChooseEmblemId;
    public int nowChooseEmblemId
    //仙盟徽章 解锁途径类型
    public enum FairyEmblemUnlockMethodType
    {
        get { return m_NowChooseEmblemId; }
        set
        Custom,     // 0 - 定制
        LV,         // 1 - 等级自动解锁
        Active,     // 2 - 活动获得
    }
    public class FairyEmblemModel : Model
    {
        public readonly int MaxItemRowCount = 6;    // 一行展示x个徽章
        public readonly int FamilyActionsType = 15;     // 家族行为类型15
        public readonly int FuncId = 237;
        public int defaultFamilyEmblemId;           // 默认徽章ID
        public bool isSendA408Pack = false;
        private int m_NowChooseEmblemId;
        public int nowChooseEmblemId
        {
            m_NowChooseEmblemId = value;
            ChooseEmblemIdChangeEvent?.Invoke();
        }
    }
    //<FamilyID,<ActionType,<EmblemId,FamilyAction>>>
    public Dictionary<int, Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>> familyActions = new Dictionary<int, Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>>();
    public event Action ChooseEmblemIdChangeEvent;      //切换标签页
    public event Action<int, int> UpdateFamilyActionEvent;
    public override void Init()
    {
        defaultFamilyEmblemId = int.Parse(FuncConfigConfig.Get("FairyEmblem").Numerical1);
    }
    public override void UnInit()
    {
    }
    public bool TryGetNowEmblemID(out int nowID)
    {
        nowID = 0;
        int emblemID = (int)PlayerDatas.Instance.fairyData.fairy.Extra6;
        if (!FamilyEmblemConfig.Has(defaultFamilyEmblemId))
            return false;
        nowID = IsUnLock(emblemID) ? (int)emblemID : defaultFamilyEmblemId;
        return true;
    }
    // 展示指定徽章 表中找不到徽章就显示默认的
    public void ShowEmblem(int emblemID, ImageEx imgTitle)
    {
        int nowEmblemID = emblemID;
        if (!FamilyEmblemConfig.Has(nowEmblemID))
        {
            nowEmblemID = defaultFamilyEmblemId;
        }
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(nowEmblemID);
        UIFrame frame = imgTitle.GetComponent<UIFrame>();
        if (UIFrameMgr.Inst.ContainsDynamicImage(config.Image))
        {
            if (frame == null)
                frame = imgTitle.gameObject.AddComponent<UIFrame>();
            imgTitle.raycastTarget = false;
            frame.ResetFrame(config.Image);
            frame.enabled = true;
        }
        else
        {
            if (frame != null)
                frame.enabled = false;
            imgTitle.SetSprite(config.Image);
        }
    }
    //发包 查询玩家当前仙盟徽章
    public void TrySendA408EmblemInfoPack()
    {
        //已经发过包了
        if (isSendA408Pack)
            return;
        isSendA408Pack = true;
        var pack = new CA408_tagCGQueryFamilyAction();
        pack.ActionType = 15;
        pack.FamilyID = PlayerDatas.Instance.baseData.FamilyId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    //发包 更改仙盟徽章
    public void SendCA413ChangeFamilyEmblemPack(int emblemId)
    {
        var pack = new CA413_tagCGChangeFamilyEmblem();
        pack.EmblemID = (byte)emblemId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public List<int> GetShowList()
    {
        List<int> showList = new List<int>();
        List<string> keys = FamilyEmblemConfig.GetKeys();
        for (int i = 0; i < keys.Count; i++)
        {
            showList.Add(int.Parse(keys[i]));
        }
        showList.Sort(Cmp);
        return showList;
    }
    // 已激活>未激活
    private int Cmp(int a, int b)
    {
        bool isUnlock1 = IsUnLock(a);
        bool isUnlock2 = IsUnLock(b);
        if (isUnlock1 != isUnlock2)
        {
            return isUnlock2.CompareTo(isUnlock1);
            get { return m_NowChooseEmblemId; }
            set
            {
                m_NowChooseEmblemId = value;
                ChooseEmblemIdChangeEvent?.Invoke();
            }
        }
        // 如果激活状态相同,比较是否为限时:限时 (true) > 永久 (false)
        bool isLimitA = IsLimitTime(a, out var familyAction1);
        bool isLimitB = IsLimitTime(b, out var familyAction2);
        //<FamilyID,<ActionType,<EmblemId,FamilyAction>>>
        public Dictionary<int, Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>> familyActions = new Dictionary<int, Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>>();
        if (isLimitA != isLimitB)
        public event Action ChooseEmblemIdChangeEvent;      //切换标签页
        public event Action<int, int> UpdateFamilyActionEvent;
        public override void Init()
        {
            return isLimitB.CompareTo(isLimitA);
            defaultFamilyEmblemId = int.Parse(FuncConfigConfig.Get("FairyEmblem").Numerical1);
        }
        // 限时状态相同,比较 SortNum
        int sortNumA = GetSortNum(a);
        int sortNumB = GetSortNum(b);
        if (sortNumA != sortNumB)
        public override void UnInit()
        {
            return sortNumA.CompareTo(sortNumB);
        }
        return a.CompareTo(b);
    }
    public int GetSortNum(int emblemID)
    {
        if (!FamilyEmblemConfig.Has(emblemID))
            return 0;
        return FamilyEmblemConfig.Get(emblemID).SortNum;
    }
    // 获得徽章来源类型
    public FairyEmblemUnlockMethodType GetFairyEmblemUnlockType(int emblemID)
    {
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
        if (config.CustomFamilyID > 0)
            return FairyEmblemUnlockMethodType.Custom;
        return config.UnlockFamilyLV > 0 ? FairyEmblemUnlockMethodType.LV : FairyEmblemUnlockMethodType.Active;
    }
    // 指定的徽章解锁了吗
    public bool IsUnLock(int emblemId)
    {
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
        FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemId);
        HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction;
        switch (type)
        public bool TryGetNowEmblemID(out int nowID)
        {
            case FairyEmblemUnlockMethodType.Custom:
                //所在仙盟不是指定的定制仙盟 未解锁
                if (PlayerDatas.Instance.baseData.FamilyId != config.CustomFamilyID)
                    return false;
                //封包中没有就算未解锁
                if (!TryGetfamilyAction(emblemId, out familyAction))
                    return false;
                if (familyAction.Value2 > 0 && familyAction.Value2 < TimeUtility.AllSeconds)
                    return false;
                return true;
            case FairyEmblemUnlockMethodType.LV:
                //所在仙盟等级小于徽章要求等级 未解锁
                if (PlayerDatas.Instance.fairyData.fairy.FamilyLV < config.UnlockFamilyLV)
                    return false;
                return true;
            case FairyEmblemUnlockMethodType.Active:
                //封包中没有就算未解锁
                if (!TryGetfamilyAction(emblemId, out familyAction))
                    return false;
                if (familyAction.Value2 > 0 && familyAction.Value2 < TimeUtility.AllSeconds)
                    return false;
                return true;
            default:
                return false;
        }
    }
    public bool IsUsing(int emblemId)
    {
        if (!TryGetNowEmblemID(out int Id))
        {
            return false;
        }
        return emblemId == Id;
    }
    public bool IsLimitTime(int emblemId, out HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction)
    {
        familyAction = new HA403_tagGCFamilyActionInfo.tagGCFamilyAction();
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
        FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemId);
        switch (type)
        {
            case FairyEmblemUnlockMethodType.LV:
            nowID = 0;
            int emblemID = (int)PlayerDatas.Instance.fairyData.fairy.Extra6;
            if (!FamilyEmblemConfig.Has(defaultFamilyEmblemId))
                return false;
            case FairyEmblemUnlockMethodType.Custom:
            case FairyEmblemUnlockMethodType.Active:
                if (config.ExpireMinutes <= 0)
                    return false;
                if (!TryGetfamilyAction(emblemId, out familyAction))
                    return false;
                return true;
            nowID = IsUnLock(emblemID) ? (int)emblemID : defaultFamilyEmblemId;
            return true;
        }
            default:
        // 展示指定徽章 表中找不到徽章就显示默认的
        public void ShowEmblem(int emblemID, ImageEx imgTitle)
        {
            int nowEmblemID = emblemID;
            if (!FamilyEmblemConfig.Has(nowEmblemID))
            {
                nowEmblemID = defaultFamilyEmblemId;
            }
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(nowEmblemID);
            UIFrame frame = imgTitle.GetComponent<UIFrame>();
            if (UIFrameMgr.Inst.ContainsDynamicImage(config.Image))
            {
                if (frame == null)
                    frame = imgTitle.gameObject.AddComponent<UIFrame>();
                imgTitle.raycastTarget = false;
                frame.ResetFrame(config.Image);
                frame.enabled = true;
            }
            else
            {
                if (frame != null)
                    frame.enabled = false;
                imgTitle.SetSprite(config.Image);
            }
        }
        //发包 查询玩家当前仙盟徽章
        public void TrySendA408EmblemInfoPack()
        {
            //已经发过包了
            if (isSendA408Pack)
                return;
            isSendA408Pack = true;
            var pack = new CA408_tagCGQueryFamilyAction();
            pack.ActionType = 15;
            pack.FamilyID = PlayerDatas.Instance.baseData.FamilyId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        //发包 更改仙盟徽章
        public void SendCA413ChangeFamilyEmblemPack(int emblemId)
        {
            var pack = new CA413_tagCGChangeFamilyEmblem();
            pack.EmblemID = (byte)emblemId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public List<int> GetShowList()
        {
            List<int> showList = new List<int>();
            List<string> keys = FamilyEmblemConfig.GetKeys();
            for (int i = 0; i < keys.Count; i++)
            {
                showList.Add(int.Parse(keys[i]));
            }
            showList.Sort(Cmp);
            return showList;
        }
        // 已激活>未激活
        private int Cmp(int a, int b)
        {
            bool isUnlock1 = IsUnLock(a);
            bool isUnlock2 = IsUnLock(b);
            if (isUnlock1 != isUnlock2)
            {
                return isUnlock2.CompareTo(isUnlock1);
            }
            // 如果激活状态相同,比较是否为限时:限时 (true) > 永久 (false)
            bool isLimitA = IsLimitTime(a, out var familyAction1);
            bool isLimitB = IsLimitTime(b, out var familyAction2);
            if (isLimitA != isLimitB)
            {
                return isLimitB.CompareTo(isLimitA);
            }
            // 限时状态相同,比较 SortNum
            int sortNumA = GetSortNum(a);
            int sortNumB = GetSortNum(b);
            if (sortNumA != sortNumB)
            {
                return sortNumA.CompareTo(sortNumB);
            }
            return a.CompareTo(b);
        }
        public int GetSortNum(int emblemID)
        {
            if (!FamilyEmblemConfig.Has(emblemID))
                return 0;
            return FamilyEmblemConfig.Get(emblemID).SortNum;
        }
        // 获得徽章来源类型
        public FairyEmblemUnlockMethodType GetFairyEmblemUnlockType(int emblemID)
        {
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
            if (config.CustomFamilyID > 0)
                return FairyEmblemUnlockMethodType.Custom;
            return config.UnlockFamilyLV > 0 ? FairyEmblemUnlockMethodType.LV : FairyEmblemUnlockMethodType.Active;
        }
        // 指定的徽章解锁了吗
        public bool IsUnLock(int emblemId)
        {
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
            FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemId);
            HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction;
            switch (type)
            {
                case FairyEmblemUnlockMethodType.Custom:
                    //所在仙盟不是指定的定制仙盟 未解锁
                    if (PlayerDatas.Instance.baseData.FamilyId != config.CustomFamilyID)
                        return false;
                    //封包中没有就算未解锁
                    if (!TryGetfamilyAction(emblemId, out familyAction))
                        return false;
                    if (familyAction.Value2 > 0 && familyAction.Value2 < TimeUtility.AllSeconds)
                        return false;
                    return true;
                case FairyEmblemUnlockMethodType.LV:
                    //所在仙盟等级小于徽章要求等级 未解锁
                    if (PlayerDatas.Instance.fairyData.fairy.FamilyLV < config.UnlockFamilyLV)
                        return false;
                    return true;
                case FairyEmblemUnlockMethodType.Active:
                    //封包中没有就算未解锁
                    if (!TryGetfamilyAction(emblemId, out familyAction))
                        return false;
                    if (familyAction.Value2 > 0 && familyAction.Value2 < TimeUtility.AllSeconds)
                        return false;
                    return true;
                default:
                    return false;
            }
        }
        public bool IsUsing(int emblemId)
        {
            if (!TryGetNowEmblemID(out int Id))
            {
                return false;
            }
            return emblemId == Id;
        }
    }
    public bool IsCaptain()
    {
        return (int)PlayerDatas.Instance.fairyData.mine.FamilyLV == 3;
    }
    // 尝试从封包中得到指定的徽章时效信息(活动途径获取的徽章,定制徽章)
    private bool TryGetfamilyAction(int emblemId, out HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction)
    {
        familyAction = new HA403_tagGCFamilyActionInfo.tagGCFamilyAction();
        int familyId = (int)PlayerDatas.Instance.baseData.FamilyId;
        if (!familyActions.TryGetValue((int)PlayerDatas.Instance.baseData.FamilyId, out var familyActionDict) || familyActionDict == null)
            return false;
        if (!familyActionDict.TryGetValue(FamilyActionsType, out var infoDict) || infoDict == null)
            return false;
        if (!infoDict.TryGetValue(emblemId, out var info) || info == null)
            return false;
        familyAction = info;
        return true;
    }
    // 得到徽章获取途径字符串
    public string GetUnlockConditionString(int emblemID)
    {
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
        FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemID);
        if (type == FairyEmblemUnlockMethodType.Custom)
            return Language.Get(StringUtility.Contact("FairyEmblemUnlockByCustom", config.CustomFamilyID));
        if (type == FairyEmblemUnlockMethodType.LV)
            return Language.Get("FairyEmblemUnlockByLv", config.UnlockFamilyLV);
        if (type == FairyEmblemUnlockMethodType.Active)
            return Language.Get(StringUtility.Contact("FairyEmblemUnlockByActive", emblemID));
        return string.Empty;
    }
    public bool TryGetEffectID(int emblemId, out int effectID)
    {
        effectID = 0;
        if (!FamilyEmblemConfig.Has(emblemId))
            return false;
        FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
        if (!EffectConfig.Has(config.EffectID))
            return false;
        effectID = config.EffectID;
        return true;
    }
    internal void UpdateFamilyAction(HA403_tagGCFamilyActionInfo vNetData)
    {
        if (!familyActions.ContainsKey((int)vNetData.FamilyID))
        public bool IsLimitTime(int emblemId, out HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction)
        {
            familyActions[(int)vNetData.FamilyID] = new Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>();
            familyAction = new HA403_tagGCFamilyActionInfo.tagGCFamilyAction();
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
            FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemId);
            switch (type)
            {
                case FairyEmblemUnlockMethodType.LV:
                    return false;
                case FairyEmblemUnlockMethodType.Custom:
                case FairyEmblemUnlockMethodType.Active:
                    if (config.ExpireMinutes <= 0)
                        return false;
                    if (!TryGetfamilyAction(emblemId, out familyAction))
                        return false;
                    return true;
                default:
                    return false;
            }
        }
        if (!familyActions[(int)vNetData.FamilyID].ContainsKey(vNetData.ActionType))
        public bool IsCaptain()
        {
            familyActions[(int)vNetData.FamilyID][vNetData.ActionType] = new Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>();
            return (int)PlayerDatas.Instance.fairyData.mine.FamilyLV == 3;
        }
        for (int i = 0; i < vNetData.FamilyActionList.Length; i++)
        // 尝试从封包中得到指定的徽章时效信息(活动途径获取的徽章,定制徽章)
        private bool TryGetfamilyAction(int emblemId, out HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction)
        {
            HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction = vNetData.FamilyActionList[i];
            familyActions[(int)vNetData.FamilyID][vNetData.ActionType][(int)familyAction.Value1] = familyAction;
            familyAction = new HA403_tagGCFamilyActionInfo.tagGCFamilyAction();
            int familyId = (int)PlayerDatas.Instance.baseData.FamilyId;
            if (!familyActions.TryGetValue((int)PlayerDatas.Instance.baseData.FamilyId, out var familyActionDict) || familyActionDict == null)
                return false;
            if (!familyActionDict.TryGetValue(FamilyActionsType, out var infoDict) || infoDict == null)
                return false;
            if (!infoDict.TryGetValue(emblemId, out var info) || info == null)
                return false;
            familyAction = info;
            return true;
        }
        UpdateFamilyActionEvent?.Invoke((int)vNetData.FamilyID, vNetData.ActionType);
        // 得到徽章获取途径字符串
        public string GetUnlockConditionString(int emblemID)
        {
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemID);
            FairyEmblemUnlockMethodType type = GetFairyEmblemUnlockType(emblemID);
            if (type == FairyEmblemUnlockMethodType.Custom)
                return Language.Get(StringUtility.Contact("FairyEmblemUnlockByCustom", config.CustomFamilyID));
            if (type == FairyEmblemUnlockMethodType.LV)
                return Language.Get("FairyEmblemUnlockByLv", config.UnlockFamilyLV);
            if (type == FairyEmblemUnlockMethodType.Active)
                return Language.Get(StringUtility.Contact("FairyEmblemUnlockByActive", emblemID));
            return string.Empty;
        }
        public bool TryGetEffectID(int emblemId, out int effectID)
        {
            effectID = 0;
            if (!FamilyEmblemConfig.Has(emblemId))
                return false;
            FamilyEmblemConfig config = FamilyEmblemConfig.Get(emblemId);
            if (!EffectConfig.Has(config.EffectID))
                return false;
            effectID = config.EffectID;
            return true;
        }
        internal void UpdateFamilyAction(HA403_tagGCFamilyActionInfo vNetData)
        {
            if (!familyActions.ContainsKey((int)vNetData.FamilyID))
            {
                familyActions[(int)vNetData.FamilyID] = new Dictionary<int, Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>>();
            }
            if (!familyActions[(int)vNetData.FamilyID].ContainsKey(vNetData.ActionType))
            {
                familyActions[(int)vNetData.FamilyID][vNetData.ActionType] = new Dictionary<int, HA403_tagGCFamilyActionInfo.tagGCFamilyAction>();
            }
            for (int i = 0; i < vNetData.FamilyActionList.Length; i++)
            {
                HA403_tagGCFamilyActionInfo.tagGCFamilyAction familyAction = vNetData.FamilyActionList[i];
                familyActions[(int)vNetData.FamilyID][vNetData.ActionType][(int)familyAction.Value1] = familyAction;
            }
            UpdateFamilyActionEvent?.Invoke((int)vNetData.FamilyID, vNetData.ActionType);
        }
    }
}
System/FairyEmblem/FairyEmblemWin.cs
@@ -1,113 +1,115 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public class FairyEmblemWin : Window
namespace vnxbqy.UI
{
    [SerializeField] ImageEx imgEmblemNow;
    [SerializeField] UIEffect uiEffect;
    [SerializeField] ScrollerController scroller;
    FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
    protected override void AddListeners()
    public class FairyEmblemWin : Window
    {
    }
        [SerializeField] ImageEx imgEmblemNow;
        [SerializeField] UIEffect uiEffect;
        [SerializeField] ScrollerController scroller;
        FairyEmblemModel model { get { return ModelCenter.Instance.GetModel<FairyEmblemModel>(); } }
    protected override void BindController()
    {
    }
    protected override void OnPreOpen()
    {
        scroller.OnRefreshCell += OnRefreshCell;
        model.ChooseEmblemIdChangeEvent += OnChooseEmblemIdChangeEvent;
        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += OnRefreshFairyInfo;
        model.UpdateFamilyActionEvent += OnUpdateFamilyActionEvent;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        List<int> showList = model.GetShowList();
        if (showList.Count > 0)
        protected override void AddListeners()
        {
            model.nowChooseEmblemId = showList[0];
            Display();
        }
    }
    protected override void OnPreClose()
    {
        scroller.OnRefreshCell -= OnRefreshCell;
        model.ChooseEmblemIdChangeEvent -= OnChooseEmblemIdChangeEvent;
        PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= OnRefreshFairyInfo;
        model.UpdateFamilyActionEvent -= OnUpdateFamilyActionEvent;
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
    }
        protected override void BindController()
        {
        }
    private void OnSecondEvent()
    {
        scroller.m_Scorller.RefreshActiveCellViews();
    }
        protected override void OnPreOpen()
        {
            scroller.OnRefreshCell += OnRefreshCell;
            model.ChooseEmblemIdChangeEvent += OnChooseEmblemIdChangeEvent;
            PlayerDatas.Instance.fairyData.OnRefreshFairyInfo += OnRefreshFairyInfo;
            model.UpdateFamilyActionEvent += OnUpdateFamilyActionEvent;
            GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
            List<int> showList = model.GetShowList();
            if (showList.Count > 0)
            {
                model.nowChooseEmblemId = showList[0];
                Display();
            }
        }
    private void OnUpdateFamilyActionEvent(int arg1, int arg2)
    {
        if (arg2 == model.FamilyActionsType)
        protected override void OnPreClose()
        {
            scroller.OnRefreshCell -= OnRefreshCell;
            model.ChooseEmblemIdChangeEvent -= OnChooseEmblemIdChangeEvent;
            PlayerDatas.Instance.fairyData.OnRefreshFairyInfo -= OnRefreshFairyInfo;
            model.UpdateFamilyActionEvent -= OnUpdateFamilyActionEvent;
            GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
        }
        private void OnSecondEvent()
        {
            scroller.m_Scorller.RefreshActiveCellViews();
        }
        private void OnUpdateFamilyActionEvent(int arg1, int arg2)
        {
            if (arg2 == model.FamilyActionsType)
            {
                Refresh();
            }
        }
        protected override void OnAfterOpen()
        {
            CreateScroller();
        }
        protected override void OnAfterClose()
        {
        }
        private void OnRefreshCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as FairyEmblemCell;
            _cell.Display(_cell.index);
        }
        private void OnChooseEmblemIdChangeEvent()
        {
            Refresh();
        }
    }
    protected override void OnAfterOpen()
    {
        CreateScroller();
    }
    protected override void OnAfterClose()
    {
    }
    private void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as FairyEmblemCell;
        _cell.Display(_cell.index);
    }
    private void OnChooseEmblemIdChangeEvent()
    {
        Refresh();
    }
    private void OnRefreshFairyInfo()
    {
        Refresh();
    }
    private void Refresh()
    {
        scroller.m_Scorller.RefreshActiveCellViews();
        Display();
    }
    private void CreateScroller()
    {
        scroller.Refresh();
        List<int> showList = model.GetShowList();
        int rowCount = (int)Math.Ceiling((double)showList.Count / model.MaxItemRowCount);
        for (int i = 0; i < rowCount; i++)
        private void OnRefreshFairyInfo()
        {
            scroller.AddCell(ScrollerDataType.Header, i);
            Refresh();
        }
        scroller.Restart();
    }
    private void Display()
    {
        model.ShowEmblem(model.nowChooseEmblemId, imgEmblemNow);
        imgEmblemNow.SetNativeSize();
        uiEffect.Stop();
        if (model.TryGetEffectID(model.nowChooseEmblemId, out int effectID))
        private void Refresh()
        {
            uiEffect.effect = effectID;
            uiEffect.Play();
            scroller.m_Scorller.RefreshActiveCellViews();
            Display();
        }
        private void CreateScroller()
        {
            scroller.Refresh();
            List<int> showList = model.GetShowList();
            int rowCount = (int)Math.Ceiling((double)showList.Count / model.MaxItemRowCount);
            for (int i = 0; i < rowCount; i++)
            {
                scroller.AddCell(ScrollerDataType.Header, i);
            }
            scroller.Restart();
        }
        private void Display()
        {
            model.ShowEmblem(model.nowChooseEmblemId, imgEmblemNow);
            imgEmblemNow.SetNativeSize();
            uiEffect.Stop();
            if (model.TryGetEffectID(model.nowChooseEmblemId, out int effectID))
            {
                uiEffect.effect = effectID;
                uiEffect.Play();
            }
        }
    }
}
System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs
@@ -1,34 +1,37 @@
using System.Collections.Generic;
public interface IPhantasmPavilionTabHandler
namespace vnxbqy.UI
{
    int GetSortNum(int id);
    public interface IPhantasmPavilionTabHandler
    {
        int GetSortNum(int id);
    int GetExpireMinutes(int id);
        int GetExpireMinutes(int id);
    string GetImage(int id);
        string GetImage(int id);
    string GetName(int id);
        string GetName(int id);
    List<int> GetTableKeys();
        List<int> GetTableKeys();
    int GetUnlockDefault(int id);
        int GetUnlockDefault(int id);
    bool Has(int id);
        bool Has(int id);
    void SendStarUPPack(int id);
        void SendStarUPPack(int id);
    void SendUsePack(int id);
        void SendUsePack(int id);
    bool TryGetAddStarAttr(int faceId, int faceStar, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr);
        bool TryGetAddStarAttr(int faceId, int faceStar, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr);
    bool TryGetEffectID(int id, out int effectID);
        bool TryGetEffectID(int id, out int effectID);
    bool TryGetMaxStarLV(int faceID, out int starCount);
        bool TryGetMaxStarLV(int faceID, out int starCount);
    bool TryGetStarUpNeedItem(int faceId, int faceStar, out int itemId, out int count);
        bool TryGetStarUpNeedItem(int faceId, int faceStar, out int itemId, out int count);
    bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
    bool TryGetUnLockNeedItem(int id, out int itemId, out int count);
        bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
        bool TryGetUnLockNeedItem(int id, out int itemId, out int count);
    }
}
System/PhantasmPavilion/PhantasmPavilionAttrCell.cs
@@ -1,59 +1,61 @@
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public class PhantasmPavilionAttrCell : CellView
namespace vnxbqy.UI
{
    [SerializeField] TextEx txtValue1;
    [SerializeField] TextEx txtValue2;
    [SerializeField] ImageEx imgArrow;
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public void Display(int index)
    public class PhantasmPavilionAttrCell : CellView
    {
        int id = model.selectItemId;
        PhantasmPavilionTab tab = model.selectTab;
        int attrType;
        int attrValue1;
        int attrValue2;
        imgArrow.SetActive(false);
        if (!model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr))
            return;
        int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
        [SerializeField] TextEx txtValue1;
        [SerializeField] TextEx txtValue2;
        [SerializeField] ImageEx imgArrow;
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        if (unLockState == 2)
        public void Display(int index)
        {
            if (!model.TryGetInfo(tab, id, out var info))
            int id = model.selectItemId;
            PhantasmPavilionTab tab = model.selectTab;
            int attrType;
            int attrValue1;
            int attrValue2;
            imgArrow.SetActive(false);
            if (!model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr))
                return;
            if (!model.TryGetAttrProp(tab, id, info.Star, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList))
                return;
            if (!model.TryGetAttrShowType(tab, id, out int showType))
                return;
            attrType = attrTypeList[index];
            attrValue1 = oldAttrValueList[index];
            attrValue2 = newAttrValueList[index];
            if (showType == 0)
            int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
            if (unLockState == 2)
            {
                txtValue1.text = PlayerPropertyConfig.Get(attrType).Name;
                txtValue2.text = StringUtility.Contact("+", PlayerPropertyConfig.GetValueDescription(attrType, attrValue2));
            }
            else if (showType == 1)
            {
                imgArrow.SetActive(true);
                txtValue1.text = StringUtility.Contact(PlayerPropertyConfig.Get(attrType).Name, ": ", PlayerPropertyConfig.GetValueDescription(attrType, attrValue1));
                txtValue2.text = PlayerPropertyConfig.GetValueDescription(attrType, attrValue2);
                if (!model.TryGetInfo(tab, id, out var info))
                    return;
                if (!model.TryGetAttrProp(tab, id, info.Star, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList))
                    return;
                if (!model.TryGetAttrShowType(tab, id, out int showType))
                    return;
                attrType = attrTypeList[index];
                attrValue1 = oldAttrValueList[index];
                attrValue2 = newAttrValueList[index];
                if (showType == 0)
                {
                    txtValue1.text = PlayerPropertyConfig.Get(attrType).Name;
                    txtValue2.text = StringUtility.Contact("+", PlayerPropertyConfig.GetValueDescription(attrType, attrValue2));
                }
                else if (showType == 1)
                {
                    imgArrow.SetActive(true);
                    txtValue1.text = StringUtility.Contact(PlayerPropertyConfig.Get(attrType).Name, ": ", PlayerPropertyConfig.GetValueDescription(attrType, attrValue1));
                    txtValue2.text = PlayerPropertyConfig.GetValueDescription(attrType, attrValue2);
                }
                else
                {
                    return;
                }
            }
            else
            {
                return;
                attrType = lightAttrTypeArr[index];
                attrValue1 = lightAttrValueArr[index];
                txtValue1.text = PlayerPropertyConfig.Get(attrType).Name;
                txtValue2.text = StringUtility.Contact("+", PlayerPropertyConfig.GetValueDescription(attrType, attrValue1));
            }
        }
        else
        {
            attrType = lightAttrTypeArr[index];
            attrValue1 = lightAttrValueArr[index];
            txtValue1.text = PlayerPropertyConfig.Get(attrType).Name;
            txtValue2.text = StringUtility.Contact("+", PlayerPropertyConfig.GetValueDescription(attrType, attrValue1));
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionAvatarFrameHandler.cs
@@ -1,126 +1,128 @@
using System.Collections.Generic;
using vnxbqy.UI;
public class PhantasmPavilionAvatarFrameHandler : IPhantasmPavilionTabHandler
{
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public int GetExpireMinutes(int id)
namespace vnxbqy.UI
{
    public class PhantasmPavilionAvatarFrameHandler : IPhantasmPavilionTabHandler
    {
        return PlayerFacePicConfig.Get(id).ExpireMinutes;
    }
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public string GetImage(int id)
    {
        return PlayerFacePicConfig.Get(id).Image;
    }
        public int GetExpireMinutes(int id)
        {
            return PlayerFacePicConfig.Get(id).ExpireMinutes;
        }
    public string GetName(int id)
    {
        return PlayerFacePicConfig.Get(id).Name;
    }
        public string GetImage(int id)
        {
            return PlayerFacePicConfig.Get(id).Image;
        }
    public int GetSortNum(int id)
    {
        return PlayerFacePicConfig.Get(id).SortNum;
    }
        public string GetName(int id)
        {
            return PlayerFacePicConfig.Get(id).Name;
        }
    public List<int> GetTableKeys()
    {
        return model.StringListToIntList(PlayerFacePicConfig.GetKeys());
    }
        public int GetSortNum(int id)
        {
            return PlayerFacePicConfig.Get(id).SortNum;
        }
    public int GetUnlockDefault(int id)
    {
        return PlayerFacePicConfig.Get(id).UnlockDefault;
    }
        public List<int> GetTableKeys()
        {
            return model.StringListToIntList(PlayerFacePicConfig.GetKeys());
        }
    public bool Has(int id)
    {
        return PlayerFacePicConfig.Has(id);
    }
        public int GetUnlockDefault(int id)
        {
            return PlayerFacePicConfig.Get(id).UnlockDefault;
        }
    public void SendStarUPPack(int id)
    {
        model.SendCB229FacePicStarUP(id);
    }
        public bool Has(int id)
        {
            return PlayerFacePicConfig.Has(id);
        }
    public void SendUsePack(int id)
    {
        model.SendCB228FacePicChange(id);
    }
        public void SendStarUPPack(int id)
        {
            model.SendCB229FacePicStarUP(id);
        }
    public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
    {
        addStarAttrTypeArr = new int[0];
        addStarAttrValueArr = new int[0];
        if (!PlayerFacePicStarConfig.TryGetIndex(id, star, out int index) || !PlayerFacePicStarConfig.Has(index))
            return false;
        PlayerFacePicStarConfig config = PlayerFacePicStarConfig.Get(index);
        if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
            return false;
        addStarAttrTypeArr = config.StarAttrType;
        addStarAttrValueArr = config.StarAttrValue;
        return true;
    }
        public void SendUsePack(int id)
        {
            model.SendCB228FacePicChange(id);
        }
    public bool TryGetEffectID(int id, out int effectID)
    {
        effectID = 0;
        if (!PlayerFacePicConfig.Has(id))
            return false;
        PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
        if (!EffectConfig.Has(config.EffectID))
            return false;
        effectID = config.EffectID;
        return true;
    }
        public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
        {
            addStarAttrTypeArr = new int[0];
            addStarAttrValueArr = new int[0];
            if (!PlayerFacePicStarConfig.TryGetIndex(id, star, out int index) || !PlayerFacePicStarConfig.Has(index))
                return false;
            PlayerFacePicStarConfig config = PlayerFacePicStarConfig.Get(index);
            if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
                return false;
            addStarAttrTypeArr = config.StarAttrType;
            addStarAttrValueArr = config.StarAttrValue;
            return true;
        }
    public bool TryGetMaxStarLV(int id, out int maxStarLV)
    {
        return PlayerFacePicStarConfig.TryGetMaxStarLV(id, out maxStarLV);
    }
        public bool TryGetEffectID(int id, out int effectID)
        {
            effectID = 0;
            if (!PlayerFacePicConfig.Has(id))
                return false;
            PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
            if (!EffectConfig.Has(config.EffectID))
                return false;
            effectID = config.EffectID;
            return true;
        }
    public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!PlayerFacePicStarConfig.TryGetIndex(id, star, out int index) || !PlayerFacePicStarConfig.Has(index))
            return false;
        PlayerFacePicStarConfig config = PlayerFacePicStarConfig.Get(index);
        if (config.StarUpNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.StarUpNeedItemList[0][0];
        count = config.StarUpNeedItemList[0][1];
        return true;
    }
        public bool TryGetMaxStarLV(int id, out int maxStarLV)
        {
            return PlayerFacePicStarConfig.TryGetMaxStarLV(id, out maxStarLV);
        }
    public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
    {
        lightAttrTypeArr = new int[0];
        lightAttrValueArr = new int[0];
        if (!PlayerFacePicConfig.Has(id))
            return false;
        PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
        if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
            return false;
        lightAttrTypeArr = config.LightAttrType;
        lightAttrValueArr = config.LightAttrValue;
        return true;
    }
        public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!PlayerFacePicStarConfig.TryGetIndex(id, star, out int index) || !PlayerFacePicStarConfig.Has(index))
                return false;
            PlayerFacePicStarConfig config = PlayerFacePicStarConfig.Get(index);
            if (config.StarUpNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.StarUpNeedItemList[0][0];
            count = config.StarUpNeedItemList[0][1];
            return true;
        }
    public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!PlayerFacePicConfig.Has(id))
            return false;
        PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
        public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
        {
            lightAttrTypeArr = new int[0];
            lightAttrValueArr = new int[0];
            if (!PlayerFacePicConfig.Has(id))
                return false;
            PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
            if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
                return false;
            lightAttrTypeArr = config.LightAttrType;
            lightAttrValueArr = config.LightAttrValue;
            return true;
        }
        if (config.UnlockNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.UnlockNeedItemList[0][0];
        count = config.UnlockNeedItemList[0][1];
        return true;
        public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!PlayerFacePicConfig.Has(id))
                return false;
            PlayerFacePicConfig config = PlayerFacePicConfig.Get(id);
            if (config.UnlockNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.UnlockNeedItemList[0][0];
            count = config.UnlockNeedItemList[0][1];
            return true;
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionAvatarHandler.cs
@@ -1,127 +1,128 @@
using System.Collections.Generic;
using vnxbqy.UI;
public class PhantasmPavilionAvatarHandler : IPhantasmPavilionTabHandler
{
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public int GetExpireMinutes(int id)
namespace vnxbqy.UI
{
    public class PhantasmPavilionAvatarHandler : IPhantasmPavilionTabHandler
    {
        return PlayerFaceConfig.Get(id).ExpireMinutes;
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        public int GetExpireMinutes(int id)
        {
            return PlayerFaceConfig.Get(id).ExpireMinutes;
        }
        public string GetImage(int id)
        {
            return PlayerFaceConfig.Get(id).Image;
        }
        public string GetName(int id)
        {
            return PlayerFaceConfig.Get(id).Name;
        }
        public int GetSortNum(int id)
        {
            return PlayerFaceConfig.Get(id).BgColor;
        }
        public List<int> GetTableKeys()
        {
            return model.StringListToIntList(PlayerFaceConfig.GetKeys());
        }
        public int GetUnlockDefault(int id)
        {
            return PlayerFaceConfig.Get(id).UnlockDefault;
        }
        public bool Has(int id)
        {
            return PlayerFaceConfig.Has(id);
        }
        public void SendStarUPPack(int id)
        {
            model.SendCB227FaceStarUP(id);
        }
        public void SendUsePack(int id)
        {
            model.SendCB226FaceChange(id);
        }
        public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
        {
            addStarAttrTypeArr = new int[0];
            addStarAttrValueArr = new int[0];
            if (!PlayerFaceStarConfig.TryGetIndex(id, star, out int index) || !PlayerFaceStarConfig.Has(index))
                return false;
            PlayerFaceStarConfig config = PlayerFaceStarConfig.Get(index);
            if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
                return false;
            addStarAttrTypeArr = config.StarAttrType;
            addStarAttrValueArr = config.StarAttrValue;
            return true;
        }
        public bool TryGetEffectID(int id, out int effectID)
        {
            effectID = 0;
            if (!PlayerFaceConfig.Has(id))
                return false;
            PlayerFaceConfig config = PlayerFaceConfig.Get(id);
            if (!EffectConfig.Has(config.EffectID))
                return false;
            effectID = config.EffectID;
            return true;
        }
        public bool TryGetMaxStarLV(int id, out int maxStarLV)
        {
            return PlayerFaceStarConfig.TryGetMaxStarLV(id, out maxStarLV);
        }
        public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!PlayerFaceStarConfig.TryGetIndex(id, star, out int index) || !PlayerFaceStarConfig.Has(index))
                return false;
            PlayerFaceStarConfig config = PlayerFaceStarConfig.Get(index);
            if (config.StarUpNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.StarUpNeedItemList[0][0];
            count = config.StarUpNeedItemList[0][1];
            return true;
        }
        public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
        {
            lightAttrTypeArr = new int[0];
            lightAttrValueArr = new int[0];
            if (!PlayerFaceConfig.Has(id))
                return false;
            PlayerFaceConfig config = PlayerFaceConfig.Get(id);
            if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
                return false;
            lightAttrTypeArr = config.LightAttrType;
            lightAttrValueArr = config.LightAttrValue;
            return true;
        }
        public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!PlayerFaceConfig.Has(id))
                return false;
            PlayerFaceConfig config = PlayerFaceConfig.Get(id);
            if (config.UnlockNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.UnlockNeedItemList[0][0];
            count = config.UnlockNeedItemList[0][1];
            return true;
        }
    }
    public string GetImage(int id)
    {
        return PlayerFaceConfig.Get(id).Image;
    }
    public string GetName(int id)
    {
        return PlayerFaceConfig.Get(id).Name;
    }
    public int GetSortNum(int id)
    {
        return PlayerFaceConfig.Get(id).BgColor;
    }
    public List<int> GetTableKeys()
    {
        return model.StringListToIntList(PlayerFaceConfig.GetKeys());
    }
    public int GetUnlockDefault(int id)
    {
        return PlayerFaceConfig.Get(id).UnlockDefault;
    }
    public bool Has(int id)
    {
        return PlayerFaceConfig.Has(id);
    }
    public void SendStarUPPack(int id)
    {
        model.SendCB227FaceStarUP(id);
    }
    public void SendUsePack(int id)
    {
        model.SendCB226FaceChange(id);
    }
    public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
    {
        addStarAttrTypeArr = new int[0];
        addStarAttrValueArr = new int[0];
        if (!PlayerFaceStarConfig.TryGetIndex(id, star, out int index) || !PlayerFaceStarConfig.Has(index))
            return false;
        PlayerFaceStarConfig config = PlayerFaceStarConfig.Get(index);
        if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
            return false;
        addStarAttrTypeArr = config.StarAttrType;
        addStarAttrValueArr = config.StarAttrValue;
        return true;
    }
    public bool TryGetEffectID(int id, out int effectID)
    {
        effectID = 0;
        if (!PlayerFaceConfig.Has(id))
            return false;
        PlayerFaceConfig config = PlayerFaceConfig.Get(id);
        if (!EffectConfig.Has(config.EffectID))
            return false;
        effectID = config.EffectID;
        return true;
    }
    public bool TryGetMaxStarLV(int id, out int maxStarLV)
    {
        return PlayerFaceStarConfig.TryGetMaxStarLV(id, out maxStarLV);
    }
    public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!PlayerFaceStarConfig.TryGetIndex(id, star, out int index) || !PlayerFaceStarConfig.Has(index))
            return false;
        PlayerFaceStarConfig config = PlayerFaceStarConfig.Get(index);
        if (config.StarUpNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.StarUpNeedItemList[0][0];
        count = config.StarUpNeedItemList[0][1];
        return true;
    }
    public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
    {
        lightAttrTypeArr = new int[0];
        lightAttrValueArr = new int[0];
        if (!PlayerFaceConfig.Has(id))
            return false;
        PlayerFaceConfig config = PlayerFaceConfig.Get(id);
        if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
            return false;
        lightAttrTypeArr = config.LightAttrType;
        lightAttrValueArr = config.LightAttrValue;
        return true;
    }
    public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!PlayerFaceConfig.Has(id))
            return false;
        PlayerFaceConfig config = PlayerFaceConfig.Get(id);
        if (config.UnlockNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.UnlockNeedItemList[0][0];
        count = config.UnlockNeedItemList[0][1];
        return true;
    }
}
System/PhantasmPavilion/PhantasmPavilionChatBubbleHandler.cs
@@ -1,120 +1,122 @@
using System.Collections.Generic;
using vnxbqy.UI;
public class PhantasmPavilionChatBubbleHandler : IPhantasmPavilionTabHandler
{
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public int GetExpireMinutes(int id)
namespace vnxbqy.UI
{
    public class PhantasmPavilionChatBubbleHandler : IPhantasmPavilionTabHandler
    {
        return ChatBubbleBoxConfig.Get(id).ExpireMinutes;
    }
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public string GetImage(int id)
    {
        return ChatBubbleBoxConfig.Get(id).Icon;
    }
        public int GetExpireMinutes(int id)
        {
            return ChatBubbleBoxConfig.Get(id).ExpireMinutes;
        }
    public string GetName(int id)
    {
        return ChatBubbleBoxConfig.Get(id).Name;
    }
        public string GetImage(int id)
        {
            return ChatBubbleBoxConfig.Get(id).Icon;
        }
    public int GetSortNum(int id)
    {
        return ChatBubbleBoxConfig.Get(id).SortNum;
    }
        public string GetName(int id)
        {
            return ChatBubbleBoxConfig.Get(id).Name;
        }
    public List<int> GetTableKeys()
    {
        return model.StringListToIntList(ChatBubbleBoxConfig.GetKeys());
    }
        public int GetSortNum(int id)
        {
            return ChatBubbleBoxConfig.Get(id).SortNum;
        }
    public int GetUnlockDefault(int id)
    {
        return ChatBubbleBoxConfig.Get(id).UnlockDefault;
    }
        public List<int> GetTableKeys()
        {
            return model.StringListToIntList(ChatBubbleBoxConfig.GetKeys());
        }
    public bool Has(int id)
    {
        return ChatBubbleBoxConfig.Has(id);
    }
        public int GetUnlockDefault(int id)
        {
            return ChatBubbleBoxConfig.Get(id).UnlockDefault;
        }
    public void SendStarUPPack(int id)
    {
        model.SendCA236ChatBubbleBoxStarUP(id);
    }
        public bool Has(int id)
        {
            return ChatBubbleBoxConfig.Has(id);
        }
    public void SendUsePack(int id)
    {
        model.SendCA230SetChatBubbleBox(id);
    }
        public void SendStarUPPack(int id)
        {
            model.SendCA236ChatBubbleBoxStarUP(id);
        }
    public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
    {
        addStarAttrTypeArr = new int[0];
        addStarAttrValueArr = new int[0];
        if (!ChatBubbleBoxStarConfig.TryGetIndex(id, star, out int index) || !ChatBubbleBoxStarConfig.Has(index))
        public void SendUsePack(int id)
        {
            model.SendCA230SetChatBubbleBox(id);
        }
        public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
        {
            addStarAttrTypeArr = new int[0];
            addStarAttrValueArr = new int[0];
            if (!ChatBubbleBoxStarConfig.TryGetIndex(id, star, out int index) || !ChatBubbleBoxStarConfig.Has(index))
                return false;
            ChatBubbleBoxStarConfig config = ChatBubbleBoxStarConfig.Get(index);
            if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
                return false;
            addStarAttrTypeArr = config.StarAttrType;
            addStarAttrValueArr = config.StarAttrValue;
            return true;
        }
        public bool TryGetEffectID(int id, out int effectID)
        {
            effectID = 0;
            return false;
        ChatBubbleBoxStarConfig config = ChatBubbleBoxStarConfig.Get(index);
        if (config.StarAttrType.IsNullOrEmpty() || config.StarAttrValue.IsNullOrEmpty() || config.StarAttrType.Length != config.StarAttrValue.Length)
            return false;
        addStarAttrTypeArr = config.StarAttrType;
        addStarAttrValueArr = config.StarAttrValue;
        return true;
    }
        }
    public bool TryGetEffectID(int id, out int effectID)
    {
        effectID = 0;
        return false;
    }
        public bool TryGetMaxStarLV(int id, out int maxStarLV)
        {
            return ChatBubbleBoxStarConfig.TryGetMaxStarLV(id, out maxStarLV);
        }
    public bool TryGetMaxStarLV(int id, out int maxStarLV)
    {
        return ChatBubbleBoxStarConfig.TryGetMaxStarLV(id, out maxStarLV);
    }
        public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!ChatBubbleBoxStarConfig.TryGetIndex(id, star, out int index) || !ChatBubbleBoxStarConfig.Has(index))
                return false;
            ChatBubbleBoxStarConfig config = ChatBubbleBoxStarConfig.Get(index);
            if (config.StarUpNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.StarUpNeedItemList[0][0];
            count = config.StarUpNeedItemList[0][1];
            return true;
        }
    public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!ChatBubbleBoxStarConfig.TryGetIndex(id, star, out int index) || !ChatBubbleBoxStarConfig.Has(index))
            return false;
        ChatBubbleBoxStarConfig config = ChatBubbleBoxStarConfig.Get(index);
        if (config.StarUpNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.StarUpNeedItemList[0][0];
        count = config.StarUpNeedItemList[0][1];
        return true;
    }
        public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
        {
            lightAttrTypeArr = new int[0];
            lightAttrValueArr = new int[0];
            if (!ChatBubbleBoxConfig.Has(id))
                return false;
            ChatBubbleBoxConfig config = ChatBubbleBoxConfig.Get(id);
            if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
                return false;
            lightAttrTypeArr = config.LightAttrType;
            lightAttrValueArr = config.LightAttrValue;
            return true;
        }
    public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
    {
        lightAttrTypeArr = new int[0];
        lightAttrValueArr = new int[0];
        if (!ChatBubbleBoxConfig.Has(id))
            return false;
        ChatBubbleBoxConfig config = ChatBubbleBoxConfig.Get(id);
        if (config.LightAttrType.IsNullOrEmpty() || config.LightAttrValue.IsNullOrEmpty() || config.LightAttrType.Length != config.LightAttrValue.Length)
            return false;
        lightAttrTypeArr = config.LightAttrType;
        lightAttrValueArr = config.LightAttrValue;
        return true;
    }
        public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!ChatBubbleBoxConfig.Has(id))
                return false;
            ChatBubbleBoxConfig config = ChatBubbleBoxConfig.Get(id);
    public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!ChatBubbleBoxConfig.Has(id))
            return false;
        ChatBubbleBoxConfig config = ChatBubbleBoxConfig.Get(id);
        if (config.UnlockNeedItemList.IsNullOrEmpty())
            return false;
        itemId = config.UnlockNeedItemList[0][0];
        count = config.UnlockNeedItemList[0][1];
        return true;
            if (config.UnlockNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.UnlockNeedItemList[0][0];
            count = config.UnlockNeedItemList[0][1];
            return true;
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionChatExpressionHandler.cs
@@ -1,105 +1,107 @@
using System.Collections.Generic;
using vnxbqy.UI;
public class PhantasmPavilionChatExpressionHandler : IPhantasmPavilionTabHandler
{
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public int GetExpireMinutes(int id)
namespace vnxbqy.UI
{
    public class PhantasmPavilionChatExpressionHandler : IPhantasmPavilionTabHandler
    {
        return EmojiPackConfig.Get(id).ExpireMinutes;
    }
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public string GetImage(int id)
    {
        return EmojiPackConfig.Get(id).Image;
    }
        public int GetExpireMinutes(int id)
        {
            return EmojiPackConfig.Get(id).ExpireMinutes;
        }
    public string GetName(int id)
    {
        return EmojiPackConfig.Get(id).Name;
    }
        public string GetImage(int id)
        {
            return EmojiPackConfig.Get(id).Image;
        }
    public int GetSortNum(int id)
    {
        return EmojiPackConfig.Get(id).SortNum;
    }
        public string GetName(int id)
        {
            return EmojiPackConfig.Get(id).Name;
        }
    public List<int> GetTableKeys()
    {
        return model.StringListToIntList(EmojiPackConfig.GetKeys());
    }
        public int GetSortNum(int id)
        {
            return EmojiPackConfig.Get(id).SortNum;
        }
    public int GetUnlockDefault(int id)
    {
        return EmojiPackConfig.Get(id).UnlockDefault;
    }
        public List<int> GetTableKeys()
        {
            return model.StringListToIntList(EmojiPackConfig.GetKeys());
        }
    public bool Has(int id)
    {
        return EmojiPackConfig.Has(id);
    }
        public int GetUnlockDefault(int id)
        {
            return EmojiPackConfig.Get(id).UnlockDefault;
        }
    public void SendStarUPPack(int id)
    {
    }
        public bool Has(int id)
        {
            return EmojiPackConfig.Has(id);
        }
    public void SendUsePack(int id)
    {
        model.SendCA230SetChatBubbleBox(id);
    }
        public void SendStarUPPack(int id)
        {
        }
    public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
    {
        addStarAttrTypeArr = new int[0];
        addStarAttrValueArr = new int[0];
        return false;
    }
        public void SendUsePack(int id)
        {
            model.SendCA230SetChatBubbleBox(id);
        }
    public bool TryGetEffectID(int id, out int effectID)
    {
        effectID = 0;
        if (!EmojiPackConfig.Has(id))
        public bool TryGetAddStarAttr(int id, int star, out int[] addStarAttrTypeArr, out int[] addStarAttrValueArr)
        {
            addStarAttrTypeArr = new int[0];
            addStarAttrValueArr = new int[0];
            return false;
        EmojiPackConfig config = EmojiPackConfig.Get(id);
        if (!EffectConfig.Has(config.EffectID))
        }
        public bool TryGetEffectID(int id, out int effectID)
        {
            effectID = 0;
            if (!EmojiPackConfig.Has(id))
                return false;
            EmojiPackConfig config = EmojiPackConfig.Get(id);
            if (!EffectConfig.Has(config.EffectID))
                return false;
            effectID = config.EffectID;
            return true;
        }
        public bool TryGetMaxStarLV(int id, out int maxStarLV)
        {
            maxStarLV = 0;
            return false;
        effectID = config.EffectID;
        return true;
    }
        }
    public bool TryGetMaxStarLV(int id, out int maxStarLV)
    {
        maxStarLV = 0;
        return false;
    }
    public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        return false;
    }
    public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
    {
        lightAttrTypeArr = new int[0];
        lightAttrValueArr = new int[0];
        return false;
    }
    public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!EmojiPackConfig.Has(id))
        public bool TryGetStarUpNeedItem(int id, int star, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            return false;
        EmojiPackConfig config = EmojiPackConfig.Get(id);
        }
        if (config.UnlockNeedItemList.IsNullOrEmpty())
        public bool TryGetUnLockAttr(int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
        {
            lightAttrTypeArr = new int[0];
            lightAttrValueArr = new int[0];
            return false;
        itemId = config.UnlockNeedItemList[0][0];
        count = config.UnlockNeedItemList[0][1];
        return true;
        }
        public bool TryGetUnLockNeedItem(int id, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!EmojiPackConfig.Has(id))
                return false;
            EmojiPackConfig config = EmojiPackConfig.Get(id);
            if (config.UnlockNeedItemList.IsNullOrEmpty())
                return false;
            itemId = config.UnlockNeedItemList[0][0];
            count = config.UnlockNeedItemList[0][1];
            return true;
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionItem.cs
@@ -1,78 +1,80 @@
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public class PhantasmPavilionItem : MonoBehaviour
namespace vnxbqy.UI
{
    [SerializeField] TextEx txtFaceName;
    [SerializeField] ButtonEx btnChoose;
    [SerializeField] ImageEx imgChoose;
    [SerializeField] ImageEx imgState;
    [SerializeField] ImageEx imgFace;
    [SerializeField] TextEx txtState;
    [SerializeField] TextEx txtTime;
    [SerializeField] UIEffect uiEffect;
    [SerializeField] RedpointBehaviour redpointBehaviour;
    [SerializeField] GameObject StarGroup;
    [SerializeField] List<ImageEx> starList = new List<ImageEx>();  //星星显示隐藏 starList和starShowList数量一致
    [SerializeField] List<ImageEx> starShowList = new List<ImageEx>();  //星星是亮是暗
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    private int id;
    public void Display(int id)
    public class PhantasmPavilionItem : MonoBehaviour
    {
        this.id = id;
        PhantasmPavilionTab tab = model.selectTab;
        redpointBehaviour.redpointId = (MainRedDot.PhantasmPavilionRepoint * 10 + (int)model.selectTab + 1) * 1000 + id;
        int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
        bool isLimitTime = model.IsLimitTime(tab, id);
        bool isUsing = model.IsUsing(tab, id);
        bool isInfo = model.TryGetInfo(tab, id, out var info);
        bool isUnlockDefault = model.GetUnlockDefault(tab, id) == 1;
        bool isMaxStarLV = model.TryGetMaxStarLV(tab, id, out int maxStar);
        imgChoose.SetActive(model.selectItemId == id);
        imgState.SetActive(unLockState == 0 || unLockState == 1 || isUsing);
        txtTime.SetActive(isInfo && unLockState == 2 || isUnlockDefault);
        StarGroup.SetActive(isInfo && isMaxStarLV && unLockState == 2);
        [SerializeField] TextEx txtFaceName;
        [SerializeField] ButtonEx btnChoose;
        [SerializeField] ImageEx imgChoose;
        [SerializeField] ImageEx imgState;
        [SerializeField] ImageEx imgFace;
        [SerializeField] TextEx txtState;
        [SerializeField] TextEx txtTime;
        [SerializeField] UIEffect uiEffect;
        [SerializeField] RedpointBehaviour redpointBehaviour;
        txtState.text = isUsing ? Language.Get("TreasureSkillWin__20") : Language.Get("KnapS144");
        txtState.colorType = isUsing ? TextColType.Green : TextColType.Red;
        txtFaceName.text = model.GetName(tab, id);
        [SerializeField] GameObject StarGroup;
        [SerializeField] List<ImageEx> starList = new List<ImageEx>();  //星星显示隐藏 starList和starShowList数量一致
        [SerializeField] List<ImageEx> starShowList = new List<ImageEx>();  //星星是亮是暗
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        private int id;
        model.ShowImage(tab, id, imgFace);
        uiEffect.Stop();
        if (model.TryGetEffectID(tab, id, out int effectID))
        public void Display(int id)
        {
            uiEffect.effect = effectID;
            uiEffect.Play();
            this.id = id;
            PhantasmPavilionTab tab = model.selectTab;
            redpointBehaviour.redpointId = (MainRedDot.PhantasmPavilionRepoint * 10 + (int)model.selectTab + 1) * 1000 + id;
            int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
            bool isLimitTime = model.IsLimitTime(tab, id);
            bool isUsing = model.IsUsing(tab, id);
            bool isInfo = model.TryGetInfo(tab, id, out var info);
            bool isUnlockDefault = model.GetUnlockDefault(tab, id) == 1;
            bool isMaxStarLV = model.TryGetMaxStarLV(tab, id, out int maxStar);
            imgChoose.SetActive(model.selectItemId == id);
            imgState.SetActive(unLockState == 0 || unLockState == 1 || isUsing);
            txtTime.SetActive(isInfo && unLockState == 2 || isUnlockDefault);
            StarGroup.SetActive(isInfo && isMaxStarLV && unLockState == 2);
            txtState.text = isUsing ? Language.Get("TreasureSkillWin__20") : Language.Get("KnapS144");
            txtState.colorType = isUsing ? TextColType.Green : TextColType.Red;
            txtFaceName.text = model.GetName(tab, id);
            model.ShowImage(tab, id, imgFace);
            uiEffect.Stop();
            if (model.TryGetEffectID(tab, id, out int effectID))
            {
                uiEffect.effect = effectID;
                uiEffect.Play();
            }
            int subTime = 0;
            if (info != null)
            {
                subTime = (int)(info.EndTime - TimeUtility.AllSeconds);
            }
            txtTime.text = Language.Get("FairyEmblem03", !isLimitTime ? Language.Get("PhantasmPavilion03") : TimeUtility.SecondsToDHMSCHS(subTime));
            int star = 0;
            if (info != null)
                star = info.Star;
            for (int i = 0; i < starList.Count; i++)
            {
                starList[i].SetActive(i < maxStar && i < starList.Count);
                starShowList[i].SetActive(i < star && i < starList.Count);
            }
            model.SetStarColor(star, starShowList);
            btnChoose.SetListener(OnClickChoose);
        }
        int subTime = 0;
        if (info != null)
        private void OnClickChoose()
        {
            subTime = (int)(info.EndTime - TimeUtility.AllSeconds);
            if (model.selectItemId == id)
                return;
            model.selectItemId = id;
        }
        txtTime.text = Language.Get("FairyEmblem03", !isLimitTime ? Language.Get("PhantasmPavilion03") : TimeUtility.SecondsToDHMSCHS(subTime));
        int star = 0;
        if (info != null)
            star = info.Star;
        for (int i = 0; i < starList.Count; i++)
        {
            starList[i].SetActive(i < maxStar && i< starList.Count);
            starShowList[i].SetActive(i < star && i < starList.Count);
        }
        model.SetStarColor(star, starShowList);
        btnChoose.SetListener(OnClickChoose);
    }
    private void OnClickChoose()
    {
        if (model.selectItemId == id)
            return;
        model.selectItemId = id;
    }
}
System/PhantasmPavilion/PhantasmPavilionItemCell.cs
@@ -1,32 +1,34 @@
using System.Collections.Generic;
using UnityEngine;
using vnxbqy.UI;
public class PhantasmPavilionItemCell : CellView
namespace vnxbqy.UI
{
    [SerializeField] List<PhantasmPavilionItem> phantasmPavilionItemList = new List<PhantasmPavilionItem>();
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public void Display(int rowIndex)
    {
        for (int i = 0; i < phantasmPavilionItemList.Count; i++)
        {
            //索引 = 行数 * 一行展示x个 + i < 总数
            int index = rowIndex * model.MaxItemRowCount + i;
            List<int> showItemList = model.ShowItemList(model.selectTab, out int fristIndex);
            if (!showItemList.IsNullOrEmpty())
    public class PhantasmPavilionItemCell : CellView
    {
        [SerializeField] List<PhantasmPavilionItem> phantasmPavilionItemList = new List<PhantasmPavilionItem>();
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        public void Display(int rowIndex)
        {
            for (int i = 0; i < phantasmPavilionItemList.Count; i++)
            {
                if (index < showItemList.Count)
                //索引 = 行数 * 一行展示x个 + i < 总数
                int index = rowIndex * model.MaxItemRowCount + i;
                List<int> showItemList = model.ShowItemList(model.selectTab, out int fristIndex);
                if (!showItemList.IsNullOrEmpty())
                {
                    int faceId = showItemList[index];
                    phantasmPavilionItemList[i].SetActive(true);
                    phantasmPavilionItemList[i].Display(faceId);
                    if (index < showItemList.Count)
                    {
                        int faceId = showItemList[index];
                        phantasmPavilionItemList[i].SetActive(true);
                        phantasmPavilionItemList[i].Display(faceId);
                    }
                    else
                    {
                        phantasmPavilionItemList[i].SetActive(false);
                    }
                }
                else
                {
                    phantasmPavilionItemList[i].SetActive(false);
                }
            }
        }
            }
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionModel.cs
@@ -3,1100 +3,1099 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using vnxbqy.UI;
public enum PhantasmPavilionTab
namespace vnxbqy.UI
{
    Avatar,                 // 0 - 头像
    AvatarFrame,            // 1 - 头像框
    ChatExpression,         // 2 - 聊天表情
    ChatBubble              // 3 - 聊天气泡
}
public class PhantasmPavilionModel : Model, IPlayerLoginOk
{
    public readonly int MaxItemRowCount = 2;    // 一行展示x个物品
    public readonly int MaxEmojiCount = 10;
    public readonly int FuncId = 236;
    private PhantasmPavilionTab m_SelectTab;
    //当前选中的标签页
    public PhantasmPavilionTab selectTab
    public enum PhantasmPavilionTab
    {
        get { return m_SelectTab; }
        set
        Avatar,                 // 0 - 头像
        AvatarFrame,            // 1 - 头像框
        ChatExpression,         // 2 - 聊天表情
        ChatBubble              // 3 - 聊天气泡
    }
    public class PhantasmPavilionModel : Model, IPlayerLoginOk
    {
        public readonly int MaxItemRowCount = 2;    // 一行展示x个物品
        public readonly int MaxEmojiCount = 10;
        public readonly int FuncId = 236;
        private PhantasmPavilionTab m_SelectTab;
        //当前选中的标签页
        public PhantasmPavilionTab selectTab
        {
            m_SelectTab = value;
            TabChangeEvent?.Invoke();
        }
    }
    private int m_selectItemId;
    public int selectItemId
    {
        get { return m_selectItemId; }
        set
        {
            m_selectItemId = value;
            ItemIdChangeEvent?.Invoke();
        }
    }
    //当前选中的表情包组
    private int m_SelectEmojiPackID;
    public int selectEmojiPackID
    {
        get { return m_SelectEmojiPackID; }
        set
        {
            m_SelectEmojiPackID = value;
            EmojiPackIDChangeEvent?.Invoke();
        }
    }
    private Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler> handlers = new Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler>();
    public Dictionary<PhantasmPavilionTab, Dictionary<int, PhantasmPavilionInfo>> infoDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, PhantasmPavilionInfo>>();
    public Dictionary<PhantasmPavilionTab, Dictionary<int, int>> defaultIDDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, int>>();
    public Dictionary<PhantasmPavilionTab, int> nowIDDict = new Dictionary<PhantasmPavilionTab, int>();
    // 幻境阁入口红点 459
    Redpoint mainRedPoint = new Redpoint(10101, MainRedDot.PhantasmPavilionRepoint);
    //标签页红点 4591 - 4594
    public Dictionary<PhantasmPavilionTab, Redpoint> tabRedPointDict = new Dictionary<PhantasmPavilionTab, Redpoint>();
    public Dictionary<PhantasmPavilionTab, Dictionary<int, Redpoint>> itemRedPointDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, Redpoint>>();
    public event Action TabChangeEvent;         //切换标签页
    public event Action ItemIdChangeEvent;      //切换选中项
    public event Action EmojiPackIDChangeEvent;      //切换选中项
    public event Action UpdateFaceInfoEvent;
    public event Action UpdateFacePicInfoEvent;
    public event Action UpdateEmojiPackInfoEvent;
    public event Action UpdateChatBubbleBoxInfoEvent;
    public Action<string> SendChatAction;
    PackModel packModel { get { return ModelCenter.Instance.GetModel<PackModel>(); } }
    public override void Init()
    {
        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent;
        packModel.refreshItemCountEvent += OnRefreshItemCountEvent;
        InitHandler();
        InitTable();
        InitRedPoint();
    }
    public override void UnInit()
    {
        PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent;
        packModel.refreshItemCountEvent -= OnRefreshItemCountEvent;
    }
    private void OnRefreshItemCountEvent(PackType type, int arg2, int arg3)
    {
        UpdateRedPoint();
    }
    public void OnPlayerLoginOk()
    {
        selectTab = PhantasmPavilionTab.Avatar;
        var list = ShowItemList(selectTab, out int fristIndex);
        if (!list.IsNullOrEmpty())
            selectItemId = fristIndex;
        nowIDDict[PhantasmPavilionTab.Avatar] = PlayerDatas.Instance.baseData.face;
        nowIDDict[PhantasmPavilionTab.AvatarFrame] = PlayerDatas.Instance.baseData.facePic;
        nowIDDict[PhantasmPavilionTab.ChatBubble] = (int)PlayerDatas.Instance.baseData.bubbleId;
    }
    private void OnPlayerDataRefreshEvent(PlayerDataType type)
    {
        if (type == PlayerDataType.Face)
        {
            nowIDDict[PhantasmPavilionTab.Avatar] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.Face);
        }
        else if (type == PlayerDataType.HairColor)
        {
            nowIDDict[PhantasmPavilionTab.AvatarFrame] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.HairColor);
        }
        else if (type == PlayerDataType.ExAttr10)
        {
            nowIDDict[PhantasmPavilionTab.ChatBubble] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr10);
        }
    }
    private void InitHandler()
    {
        handlers = new Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler>();
        handlers[PhantasmPavilionTab.Avatar] = new PhantasmPavilionAvatarHandler();
        handlers[PhantasmPavilionTab.AvatarFrame] = new PhantasmPavilionAvatarFrameHandler();
        handlers[PhantasmPavilionTab.ChatExpression] = new PhantasmPavilionChatExpressionHandler();
        handlers[PhantasmPavilionTab.ChatBubble] = new PhantasmPavilionChatBubbleHandler();
    }
    private void InitTable()
    {
        InitDefault();
    }
    private void InitRedPoint()
    {
        InitTabRedPoint();
        InitItemRedPoint(PhantasmPavilionTab.Avatar, PlayerFaceConfig.GetKeys());
        InitItemRedPoint(PhantasmPavilionTab.AvatarFrame, PlayerFacePicConfig.GetKeys());
        InitItemRedPoint(PhantasmPavilionTab.ChatExpression, EmojiPackConfig.GetKeys());
        InitItemRedPoint(PhantasmPavilionTab.ChatBubble, ChatBubbleBoxConfig.GetKeys());
    }
    private void InitDefault()
    {
        var tabValues = Enum.GetValues(typeof(PhantasmPavilionTab));
        for (int i = 0; i < tabValues.Length; i++)
        {
            PhantasmPavilionTab tab = (PhantasmPavilionTab)tabValues.GetValue(i);
            if (!defaultIDDict.ContainsKey(tab))
            get { return m_SelectTab; }
            set
            {
                defaultIDDict[tab] = new Dictionary<int, int>();
                m_SelectTab = value;
                TabChangeEvent?.Invoke();
            }
        }
        var config = FuncConfigConfig.Get("PhantasmPavilion");
        var jsonData = JsonMapper.ToObject(config.Numerical1);
        List<string> keyList = jsonData.Keys.ToList();
        for (int i = 0; i < keyList.Count; i++)
        private int m_selectItemId;
        public int selectItemId
        {
            int key = int.Parse(keyList[i]);
            int value = int.Parse(jsonData[keyList[i]].ToString());
            defaultIDDict[PhantasmPavilionTab.Avatar][key] = value;
        }
        jsonData = JsonMapper.ToObject(config.Numerical2);
        keyList = jsonData.Keys.ToList();
        for (int i = 0; i < keyList.Count; i++)
        {
            int key = int.Parse(keyList[i]);
            int value = int.Parse(jsonData[keyList[i]].ToString());
            defaultIDDict[PhantasmPavilionTab.AvatarFrame][key] = value;
        }
        //defaultIDDict[PhantasmPavilionTab.ChatExpression][0] = int.Parse(config.Numerical3);
        defaultIDDict[PhantasmPavilionTab.ChatBubble][0] = int.Parse(config.Numerical3);
    }
    private void InitTabRedPoint()
    {
        var values = Enum.GetValues(typeof(PhantasmPavilionTab));
        for (int i = 0; i < values.Length; i++)
        {
            PhantasmPavilionTab tab = (PhantasmPavilionTab)values.GetValue(i);
            int id = MainRedDot.PhantasmPavilionRepoint * 10 + (int)tab + 1;
            tabRedPointDict[tab] = new Redpoint(MainRedDot.PhantasmPavilionRepoint, id);
        }
    }
    private void InitItemRedPoint(PhantasmPavilionTab tab, List<string> keys)
    {
        if (!infoDict.ContainsKey(tab))
            itemRedPointDict[tab] = new Dictionary<int, Redpoint>();
        List<int> idList = StringListToIntList(keys);
        for (int i = 0; i < idList.Count; i++)
        {
            int id = idList[i];
            int baseValue = MainRedDot.PhantasmPavilionRepoint * 10 + (int)tab + 1;
            itemRedPointDict[tab][id] = new Redpoint(baseValue, baseValue * 1000 + id);
        }
    }
    public void UpdateRedPoint()
    {
        var values = Enum.GetValues(typeof(PhantasmPavilionTab));
        for (int i = 0; i < values.Length; i++)
        {
            PhantasmPavilionTab key = (PhantasmPavilionTab)values.GetValue(i);
            tabRedPointDict[key].state = RedPointState.None;
            var keyList = itemRedPointDict[key].Keys.ToList();
            for (int j = 0; j < keyList.Count; j++)
            get { return m_selectItemId; }
            set
            {
                int id = keyList[j];
                itemRedPointDict[key][id].state = RedPointState.None;
                //可激活
                if (GetUnLockState(key, id) == 1)
                {
                    itemRedPointDict[key][id].state = RedPointState.Simple;
                m_selectItemId = value;
                ItemIdChangeEvent?.Invoke();
            }
        }
                    if (selectTab != key)
                    {
                        tabRedPointDict[key].state = RedPointState.Simple;
                    }
        //当前选中的表情包组
        private int m_SelectEmojiPackID;
        public int selectEmojiPackID
        {
            get { return m_SelectEmojiPackID; }
            set
            {
                m_SelectEmojiPackID = value;
                EmojiPackIDChangeEvent?.Invoke();
            }
        }
        private Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler> handlers = new Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler>();
        public Dictionary<PhantasmPavilionTab, Dictionary<int, PhantasmPavilionInfo>> infoDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, PhantasmPavilionInfo>>();
        public Dictionary<PhantasmPavilionTab, Dictionary<int, int>> defaultIDDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, int>>();
        public Dictionary<PhantasmPavilionTab, int> nowIDDict = new Dictionary<PhantasmPavilionTab, int>();
        // 幻境阁入口红点 459
        Redpoint mainRedPoint = new Redpoint(10101, MainRedDot.PhantasmPavilionRepoint);
        //标签页红点 4591 - 4594
        public Dictionary<PhantasmPavilionTab, Redpoint> tabRedPointDict = new Dictionary<PhantasmPavilionTab, Redpoint>();
        public Dictionary<PhantasmPavilionTab, Dictionary<int, Redpoint>> itemRedPointDict = new Dictionary<PhantasmPavilionTab, Dictionary<int, Redpoint>>();
        public event Action TabChangeEvent;         //切换标签页
        public event Action ItemIdChangeEvent;      //切换选中项
        public event Action EmojiPackIDChangeEvent;      //切换选中项
        public event Action UpdateFaceInfoEvent;
        public event Action UpdateFacePicInfoEvent;
        public event Action UpdateEmojiPackInfoEvent;
        public event Action UpdateChatBubbleBoxInfoEvent;
        public Action<string> SendChatAction;
        PackModel packModel { get { return ModelCenter.Instance.GetModel<PackModel>(); } }
        public override void Init()
        {
            PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent;
            packModel.refreshItemCountEvent += OnRefreshItemCountEvent;
            InitHandler();
            InitTable();
            InitRedPoint();
        }
        public override void UnInit()
        {
            PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent;
            packModel.refreshItemCountEvent -= OnRefreshItemCountEvent;
        }
        private void OnRefreshItemCountEvent(PackType type, int arg2, int arg3)
        {
            UpdateRedPoint();
        }
        public void OnPlayerLoginOk()
        {
            selectTab = PhantasmPavilionTab.Avatar;
            var list = ShowItemList(selectTab, out int fristIndex);
            if (!list.IsNullOrEmpty())
                selectItemId = fristIndex;
            nowIDDict[PhantasmPavilionTab.Avatar] = PlayerDatas.Instance.baseData.face;
            nowIDDict[PhantasmPavilionTab.AvatarFrame] = PlayerDatas.Instance.baseData.facePic;
            nowIDDict[PhantasmPavilionTab.ChatBubble] = (int)PlayerDatas.Instance.baseData.bubbleId;
        }
        private void OnPlayerDataRefreshEvent(PlayerDataType type)
        {
            if (type == PlayerDataType.Face)
            {
                nowIDDict[PhantasmPavilionTab.Avatar] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.Face);
            }
            else if (type == PlayerDataType.HairColor)
            {
                nowIDDict[PhantasmPavilionTab.AvatarFrame] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.HairColor);
            }
            else if (type == PlayerDataType.ExAttr10)
            {
                nowIDDict[PhantasmPavilionTab.ChatBubble] = (int)PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.ExAttr10);
            }
        }
        private void InitHandler()
        {
            handlers = new Dictionary<PhantasmPavilionTab, IPhantasmPavilionTabHandler>();
            handlers[PhantasmPavilionTab.Avatar] = new PhantasmPavilionAvatarHandler();
            handlers[PhantasmPavilionTab.AvatarFrame] = new PhantasmPavilionAvatarFrameHandler();
            handlers[PhantasmPavilionTab.ChatExpression] = new PhantasmPavilionChatExpressionHandler();
            handlers[PhantasmPavilionTab.ChatBubble] = new PhantasmPavilionChatBubbleHandler();
        }
        private void InitTable()
        {
            InitDefault();
        }
        private void InitRedPoint()
        {
            InitTabRedPoint();
            InitItemRedPoint(PhantasmPavilionTab.Avatar, PlayerFaceConfig.GetKeys());
            InitItemRedPoint(PhantasmPavilionTab.AvatarFrame, PlayerFacePicConfig.GetKeys());
            InitItemRedPoint(PhantasmPavilionTab.ChatExpression, EmojiPackConfig.GetKeys());
            InitItemRedPoint(PhantasmPavilionTab.ChatBubble, ChatBubbleBoxConfig.GetKeys());
        }
        private void InitDefault()
        {
            var tabValues = Enum.GetValues(typeof(PhantasmPavilionTab));
            for (int i = 0; i < tabValues.Length; i++)
            {
                PhantasmPavilionTab tab = (PhantasmPavilionTab)tabValues.GetValue(i);
                if (!defaultIDDict.ContainsKey(tab))
                {
                    defaultIDDict[tab] = new Dictionary<int, int>();
                }
                //可升星
            }
                if (IsUpStar(key, id))
            var config = FuncConfigConfig.Get("PhantasmPavilion");
            var jsonData = JsonMapper.ToObject(config.Numerical1);
            List<string> keyList = jsonData.Keys.ToList();
            for (int i = 0; i < keyList.Count; i++)
            {
                int key = int.Parse(keyList[i]);
                int value = int.Parse(jsonData[keyList[i]].ToString());
                defaultIDDict[PhantasmPavilionTab.Avatar][key] = value;
            }
            jsonData = JsonMapper.ToObject(config.Numerical2);
            keyList = jsonData.Keys.ToList();
            for (int i = 0; i < keyList.Count; i++)
            {
                int key = int.Parse(keyList[i]);
                int value = int.Parse(jsonData[keyList[i]].ToString());
                defaultIDDict[PhantasmPavilionTab.AvatarFrame][key] = value;
            }
            //defaultIDDict[PhantasmPavilionTab.ChatExpression][0] = int.Parse(config.Numerical3);
            defaultIDDict[PhantasmPavilionTab.ChatBubble][0] = int.Parse(config.Numerical3);
        }
        private void InitTabRedPoint()
        {
            var values = Enum.GetValues(typeof(PhantasmPavilionTab));
            for (int i = 0; i < values.Length; i++)
            {
                PhantasmPavilionTab tab = (PhantasmPavilionTab)values.GetValue(i);
                int id = MainRedDot.PhantasmPavilionRepoint * 10 + (int)tab + 1;
                tabRedPointDict[tab] = new Redpoint(MainRedDot.PhantasmPavilionRepoint, id);
            }
        }
        private void InitItemRedPoint(PhantasmPavilionTab tab, List<string> keys)
        {
            if (!infoDict.ContainsKey(tab))
                itemRedPointDict[tab] = new Dictionary<int, Redpoint>();
            List<int> idList = StringListToIntList(keys);
            for (int i = 0; i < idList.Count; i++)
            {
                int id = idList[i];
                int baseValue = MainRedDot.PhantasmPavilionRepoint * 10 + (int)tab + 1;
                itemRedPointDict[tab][id] = new Redpoint(baseValue, baseValue * 1000 + id);
            }
        }
        public void UpdateRedPoint()
        {
            var values = Enum.GetValues(typeof(PhantasmPavilionTab));
            for (int i = 0; i < values.Length; i++)
            {
                PhantasmPavilionTab key = (PhantasmPavilionTab)values.GetValue(i);
                tabRedPointDict[key].state = RedPointState.None;
                var keyList = itemRedPointDict[key].Keys.ToList();
                for (int j = 0; j < keyList.Count; j++)
                {
                    itemRedPointDict[key][id].state = RedPointState.Simple;
                    if (selectTab != key)
                    int id = keyList[j];
                    itemRedPointDict[key][id].state = RedPointState.None;
                    //可激活
                    if (GetUnLockState(key, id) == 1)
                    {
                        tabRedPointDict[key].state = RedPointState.Simple;
                        itemRedPointDict[key][id].state = RedPointState.Simple;
                        if (selectTab != key)
                        {
                            tabRedPointDict[key].state = RedPointState.Simple;
                        }
                    }
                    //可升星
                    if (IsUpStar(key, id))
                    {
                        itemRedPointDict[key][id].state = RedPointState.Simple;
                        if (selectTab != key)
                        {
                            tabRedPointDict[key].state = RedPointState.Simple;
                        }
                    }
                }
            }
        }
    }
    public void SetStarColor(int nowStar, List<ImageEx> starShowList)
    {
        for (int i = 0; i < starShowList.Count; i++)
        public void SetStarColor(int nowStar, List<ImageEx> starShowList)
        {
            // 根据星级设置不同颜色的星星
            if (nowStar <= 10)
            for (int i = 0; i < starShowList.Count; i++)
            {
                starShowList[i].SetSprite("TreasureStar1"); // 黄色星星
            }
            else if (nowStar <= 20)
            {
                int blueStars = nowStar - 10;
                if (i < blueStars)
                {
                    starShowList[i].SetSprite("TreasureStar2"); // 蓝色星星
                }
                else
                // 根据星级设置不同颜色的星星
                if (nowStar <= 10)
                {
                    starShowList[i].SetSprite("TreasureStar1"); // 黄色星星
                }
            }
            else
            {
                int purpleStars = nowStar - 20;
                if (i < purpleStars)
                else if (nowStar <= 20)
                {
                    starShowList[i].SetSprite("TreasureStar3"); // 紫色星星
                    int blueStars = nowStar - 10;
                    if (i < blueStars)
                    {
                        starShowList[i].SetSprite("TreasureStar2"); // 蓝色星星
                    }
                    else
                    {
                        starShowList[i].SetSprite("TreasureStar1"); // 黄色星星
                    }
                }
                else
                {
                    starShowList[i].SetSprite("TreasureStar2"); // 蓝色星星
                    int purpleStars = nowStar - 20;
                    if (i < purpleStars)
                    {
                        starShowList[i].SetSprite("TreasureStar3"); // 紫色星星
                    }
                    else
                    {
                        starShowList[i].SetSprite("TreasureStar2"); // 蓝色星星
                    }
                }
            }
        }
    }
    //获取不同职业对应的默认值
    public bool TryGetDefaultID(PhantasmPavilionTab key, int job, out int defaultID)
    {
        defaultID = 0;
        if (defaultIDDict == null || !defaultIDDict.TryGetValue(key, out var dict) || dict == null)
            return false;
        // 尝试获取 job 对应的值,如果没有则获取 key 为 0 的值
        return dict.TryGetValue(job, out defaultID) || dict.TryGetValue(0, out defaultID);
    }
    public bool TryGetNowShowID(PhantasmPavilionTab key, out int result)
    {
        result = 0;
        int job = PlayerDatas.Instance.baseData.Job;
        // 如果 nowIDDict 为空或没有当前 ID,直接尝试获取默认 ID
        if (nowIDDict == null || !TryGetDefaultID(key, job, out int defaultID))
            return false;
        // 获取当前 ID,如果存在则赋值给 result
        if (nowIDDict.TryGetValue(key, out int nowID) && IsUnlock(key, nowID))
        //获取不同职业对应的默认值
        public bool TryGetDefaultID(PhantasmPavilionTab key, int job, out int defaultID)
        {
            result = nowID;
        }
        else
        {
            result = defaultID;
            defaultID = 0;
            if (defaultIDDict == null || !defaultIDDict.TryGetValue(key, out var dict) || dict == null)
                return false;
            // 尝试获取 job 对应的值,如果没有则获取 key 为 0 的值
            return dict.TryGetValue(job, out defaultID) || dict.TryGetValue(0, out defaultID);
        }
        return true;
    }
    public bool TryGetInfo(PhantasmPavilionTab tab, int id, out PhantasmPavilionInfo info)
    {
        info = new PhantasmPavilionInfo();
        if (!Has(tab, id))
            return false;
        if (infoDict == null || !infoDict.TryGetValue(tab, out var tempInfoDict))
            return false;
        if (tempInfoDict == null || !tempInfoDict.TryGetValue(id, out info))
            return false;
        return true;
    }
    public List<int> StringListToIntList(List<string> stringList)
    {
        List<int> resultList = new List<int>();
        for (int i = 0; i < stringList.Count; i++)
        public bool TryGetNowShowID(PhantasmPavilionTab key, out int result)
        {
            string str = stringList[i];
            resultList.Add(int.Parse(str));
        }
        return resultList;
    }
            result = 0;
            int job = PlayerDatas.Instance.baseData.Job;
            // 如果 nowIDDict 为空或没有当前 ID,直接尝试获取默认 ID
            if (nowIDDict == null || !TryGetDefaultID(key, job, out int defaultID))
                return false;
    public List<int> ShowItemList(PhantasmPavilionTab tab, out int fristIndex)
    {
        fristIndex = 0;
        if (!handlers.TryGetValue(tab, out var handler))
            return new List<int>();
        var resList = handler.GetTableKeys();
        resList.Sort((int a, int b) => Cmp(a, b, tab));
        fristIndex = resList.First();
        return resList;
    }
    public int Cmp(int a, int b, PhantasmPavilionTab tab)
    {
        // 获取 a 和 b 的解锁状态
        int stateA = GetUnLockState(tab, a);
        int stateB = GetUnLockState(tab, b);
        // 将状态重新定义为优先级排序数值:可激活 > 已激活 > 未激活最后
        int priorityA = stateA == 1 ? 0 : (stateA == 2 ? 1 : 2);
        int priorityB = stateB == 1 ? 0 : (stateB == 2 ? 1 : 2);
        if (priorityA != priorityB)
        {
            return priorityA.CompareTo(priorityB);
        }
        // 如果激活状态相同,比较是否为限时:限时 (true) > 永久 (false)
        bool isLimitA = IsLimitTime(tab, a);
        bool isLimitB = IsLimitTime(tab, b);
        if (isLimitA != isLimitB)
        {
            return isLimitB.CompareTo(isLimitA);
        }
        // 限时状态相同,比较 SortNum
        int sortNumA = GetSortNum(tab, a);
        int sortNumB = GetSortNum(tab, b);
        if (sortNumA != sortNumB)
        {
            if (tab == PhantasmPavilionTab.Avatar)
            // 获取当前 ID,如果存在则赋值给 result
            if (nowIDDict.TryGetValue(key, out int nowID) && IsUnlock(key, nowID))
            {
                return sortNumB.CompareTo(sortNumA);
                result = nowID;
            }
            else
            {
                return sortNumA.CompareTo(sortNumB);
                result = defaultID;
            }
            return true;
        }
        return a.CompareTo(b);
    }
    ////获得当前状态 0 - 未激活 1 - 可激活 2 - 已激活
    public int GetUnLockState(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return 0;
        //没激活
        if (!IsUnlock(tab, id))
        public bool TryGetInfo(PhantasmPavilionTab tab, int id, out PhantasmPavilionInfo info)
        {
            //没有填激活物品
            if (!TryGetUnLockNeedItem(tab, id, out int itemId, out int count))
                return 0;
            //激活物品数量不足
            int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
            if (hasCnt < count)
                return 0;
            return 1;
            info = new PhantasmPavilionInfo();
            if (!Has(tab, id))
                return false;
            if (infoDict == null || !infoDict.TryGetValue(tab, out var tempInfoDict))
                return false;
            if (tempInfoDict == null || !tempInfoDict.TryGetValue(id, out info))
                return false;
            return true;
        }
        return 2;
    }
    //获得属性展示样式类型  0 加号 1 箭头 false不展示
    public bool TryGetAttrShowType(PhantasmPavilionTab tab, int faceId, out int type)
    {
        type = 0;
        int unLockState = GetUnLockState(tab, faceId);// 0 - 未激活 1 - 可激活 2 - 已激活
        bool isNoMaxStar = TryGetUpStar(tab, faceId, out int nowUpStar);
        bool isHaveUnLockAttr = TryGetUnLockAttr(tab, selectItemId, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
        bool isHaveAddStarAttr = TryGetMaxStarLV(tab, faceId, out int starCount);
        if (!isHaveUnLockAttr)
            return false;
        if (unLockState == 2)
        public List<int> StringListToIntList(List<string> stringList)
        {
            if (!isHaveAddStarAttr)
            List<int> resultList = new List<int>();
            for (int i = 0; i < stringList.Count; i++)
            {
                string str = stringList[i];
                resultList.Add(int.Parse(str));
            }
            return resultList;
        }
        public List<int> ShowItemList(PhantasmPavilionTab tab, out int fristIndex)
        {
            fristIndex = 0;
            if (!handlers.TryGetValue(tab, out var handler))
                return new List<int>();
            var resList = handler.GetTableKeys();
            resList.Sort((int a, int b) => Cmp(a, b, tab));
            fristIndex = resList.First();
            return resList;
        }
        public int Cmp(int a, int b, PhantasmPavilionTab tab)
        {
            // 获取 a 和 b 的解锁状态
            int stateA = GetUnLockState(tab, a);
            int stateB = GetUnLockState(tab, b);
            // 将状态重新定义为优先级排序数值:可激活 > 已激活 > 未激活最后
            int priorityA = stateA == 1 ? 0 : (stateA == 2 ? 1 : 2);
            int priorityB = stateB == 1 ? 0 : (stateB == 2 ? 1 : 2);
            if (priorityA != priorityB)
            {
                return priorityA.CompareTo(priorityB);
            }
            // 如果激活状态相同,比较是否为限时:限时 (true) > 永久 (false)
            bool isLimitA = IsLimitTime(tab, a);
            bool isLimitB = IsLimitTime(tab, b);
            if (isLimitA != isLimitB)
            {
                return isLimitB.CompareTo(isLimitA);
            }
            // 限时状态相同,比较 SortNum
            int sortNumA = GetSortNum(tab, a);
            int sortNumB = GetSortNum(tab, b);
            if (sortNumA != sortNumB)
            {
                if (tab == PhantasmPavilionTab.Avatar)
                {
                    return sortNumB.CompareTo(sortNumA);
                }
                else
                {
                    return sortNumA.CompareTo(sortNumB);
                }
            }
            return a.CompareTo(b);
        }
        ////获得当前状态 0 - 未激活 1 - 可激活 2 - 已激活
        public int GetUnLockState(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return 0;
            //没激活
            if (!IsUnlock(tab, id))
            {
                //没有填激活物品
                if (!TryGetUnLockNeedItem(tab, id, out int itemId, out int count))
                    return 0;
                //激活物品数量不足
                int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
                if (hasCnt < count)
                    return 0;
                return 1;
            }
            return 2;
        }
        //获得属性展示样式类型  0 加号 1 箭头 false不展示
        public bool TryGetAttrShowType(PhantasmPavilionTab tab, int faceId, out int type)
        {
            type = 0;
            int unLockState = GetUnLockState(tab, faceId);// 0 - 未激活 1 - 可激活 2 - 已激活
            bool isNoMaxStar = TryGetUpStar(tab, faceId, out int nowUpStar);
            bool isHaveUnLockAttr = TryGetUnLockAttr(tab, selectItemId, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
            bool isHaveAddStarAttr = TryGetMaxStarLV(tab, faceId, out int starCount);
            if (!isHaveUnLockAttr)
                return false;
            if (unLockState == 2)
            {
                if (!isHaveAddStarAttr)
                {
                    type = 0;
                }
                else
                {
                    type = isNoMaxStar ? 1 : 0;
                }
            }
            else
            {
                type = 0;
            }
            else
            {
                type = isNoMaxStar ? 1 : 0;
            }
            return true;
        }
        else
        //获取激活后下一星级和当前星级的对比数据 0星是刚激活的状态
        public bool TryGetAttrProp(PhantasmPavilionTab tab, int id, int faceStar, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList)
        {
            type = 0;
        }
        return true;
    }
            attrTypeList = new List<int>();
            oldAttrValueList = new List<int>();
            newAttrValueList = new List<int>();
            if (!Has(tab, id))
                return false;
            bool isHaveUnLockAttr = TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
            bool isHaveAddStarAttr = TryGetMaxStarLV(tab, id, out int maxStarLV);
            if (!isHaveUnLockAttr || faceStar > maxStarLV)
                return false;
    //获取激活后下一星级和当前星级的对比数据 0星是刚激活的状态
    public bool TryGetAttrProp(PhantasmPavilionTab tab, int id, int faceStar, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList)
    {
        attrTypeList = new List<int>();
        oldAttrValueList = new List<int>();
        newAttrValueList = new List<int>();
        if (!Has(tab, id))
            return false;
        bool isHaveUnLockAttr = TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
        bool isHaveAddStarAttr = TryGetMaxStarLV(tab, id, out int maxStarLV);
        if (!isHaveUnLockAttr || faceStar > maxStarLV)
            return false;
            int nextStar = faceStar + 1;
            bool isHaveNowStarAttr = TryGetAddStarAttr(tab, id, faceStar, out int[] nowAddStarAttrTypeArr, out int[] nowAddStarAttrValueArr);
            bool isHaveNextStarAttr = TryGetAddStarAttr(tab, id, nextStar, out int[] nextAddStarAttrTypeArr, out int[] nextAddStarAttrValueArr);
            Dictionary<int, int> oldDict = new Dictionary<int, int>();
            Dictionary<int, int> newDict = new Dictionary<int, int>();
        int nextStar = faceStar + 1;
        bool isHaveNowStarAttr = TryGetAddStarAttr(tab, id, faceStar, out int[] nowAddStarAttrTypeArr, out int[] nowAddStarAttrValueArr);
        bool isHaveNextStarAttr = TryGetAddStarAttr(tab, id, nextStar, out int[] nextAddStarAttrTypeArr, out int[] nextAddStarAttrValueArr);
        Dictionary<int, int> oldDict = new Dictionary<int, int>();
        Dictionary<int, int> newDict = new Dictionary<int, int>();
        if (!isHaveAddStarAttr)
        {
            attrTypeList = lightAttrTypeArr.ToList();
            newAttrValueList = lightAttrValueArr.ToList();
            for (int i = 0; i < attrTypeList.Count; i++)
            if (!isHaveAddStarAttr)
            {
                oldAttrValueList.Add(0);
            }
        }
        else
        {
            for (int i = 0; i < lightAttrTypeArr.Length; i++)
            {
                int attrType = lightAttrTypeArr[i];
                oldDict[attrType] = lightAttrValueArr[i];
                newDict[attrType] = lightAttrValueArr[i];
            }
            if (faceStar == 0)
            {
                if (!isHaveNextStarAttr)
                    return false;
                attrTypeList = nextAddStarAttrTypeArr.ToList();
                for (int i = 0; i < nextAddStarAttrTypeArr.Length; i++)
                {
                    int attrType = nextAddStarAttrTypeArr[i];
                    int nextAttrValue = nextAddStarAttrValueArr[i];
                    if (!oldDict.ContainsKey(attrType))
                    {
                        oldDict[attrType] = 0;
                    }
                    if (!newDict.ContainsKey(attrType))
                    {
                        newDict[attrType] = nextAttrValue;
                    }
                    else
                    {
                        newDict[attrType] += nextAttrValue;
                    }
                }
                attrTypeList = lightAttrTypeArr.ToList();
                newAttrValueList = lightAttrValueArr.ToList();
                for (int i = 0; i < attrTypeList.Count; i++)
                {
                    int attrType = attrTypeList[i];
                    oldAttrValueList.Add(oldDict[attrType]);
                    newAttrValueList.Add(newDict[attrType]);
                }
            }
            else if (nextStar > maxStarLV)
            {
                attrTypeList = nowAddStarAttrTypeArr.ToList();
                for (int i = 0; i < nowAddStarAttrTypeArr.Length; i++)
                {
                    int attrType = nowAddStarAttrTypeArr[i];
                    int nextAttrValue = nowAddStarAttrValueArr[i];
                    if (!oldDict.ContainsKey(attrType))
                    {
                        oldDict[attrType] = nextAttrValue;
                    }
                    else
                    {
                        oldDict[attrType] += nextAttrValue;
                    }
                    newDict[attrType] = 0;
                }
                for (int i = 0; i < attrTypeList.Count; i++)
                {
                    int attrType = attrTypeList[i];
                    newAttrValueList.Add(oldDict[attrType]);
                    oldAttrValueList.Add(0);
                }
            }
            else
            {
                attrTypeList = nextAddStarAttrTypeArr.ToList();
                for (int i = 0; i < nextAddStarAttrTypeArr.Length; i++)
                for (int i = 0; i < lightAttrTypeArr.Length; i++)
                {
                    int attrType = nextAddStarAttrTypeArr[i];
                    int attrValue = nextAddStarAttrValueArr[i];
                    int attrType = lightAttrTypeArr[i];
                    oldDict[attrType] = lightAttrValueArr[i];
                    newDict[attrType] = lightAttrValueArr[i];
                }
                    if (!oldDict.ContainsKey(attrType))
                if (faceStar == 0)
                {
                    if (!isHaveNextStarAttr)
                        return false;
                    attrTypeList = nextAddStarAttrTypeArr.ToList();
                    for (int i = 0; i < nextAddStarAttrTypeArr.Length; i++)
                    {
                        oldDict[attrType] = 0;
                        int attrType = nextAddStarAttrTypeArr[i];
                        int nextAttrValue = nextAddStarAttrValueArr[i];
                        if (!oldDict.ContainsKey(attrType))
                        {
                            oldDict[attrType] = 0;
                        }
                        if (!newDict.ContainsKey(attrType))
                        {
                            newDict[attrType] = nextAttrValue;
                        }
                        else
                        {
                            newDict[attrType] += nextAttrValue;
                        }
                    }
                    if (!newDict.ContainsKey(attrType))
                    for (int i = 0; i < attrTypeList.Count; i++)
                    {
                        int attrType = attrTypeList[i];
                        oldAttrValueList.Add(oldDict[attrType]);
                        newAttrValueList.Add(newDict[attrType]);
                    }
                }
                else if (nextStar > maxStarLV)
                {
                    attrTypeList = nowAddStarAttrTypeArr.ToList();
                    for (int i = 0; i < nowAddStarAttrTypeArr.Length; i++)
                    {
                        int attrType = nowAddStarAttrTypeArr[i];
                        int nextAttrValue = nowAddStarAttrValueArr[i];
                        if (!oldDict.ContainsKey(attrType))
                        {
                            oldDict[attrType] = nextAttrValue;
                        }
                        else
                        {
                            oldDict[attrType] += nextAttrValue;
                        }
                        newDict[attrType] = 0;
                    }
                    newDict[attrType] += attrValue;
                }
                for (int i = 0; i < nowAddStarAttrTypeArr.Length; i++)
                {
                    int attrType = nowAddStarAttrTypeArr[i];
                    int attrValue = nowAddStarAttrValueArr[i];
                    oldDict[attrType] += attrValue;
                }
                for (int i = 0; i < attrTypeList.Count; i++)
                {
                    int attrType = attrTypeList[i];
                    oldAttrValueList.Add(oldDict[attrType]);
                    newAttrValueList.Add(newDict[attrType]);
                }
            }
        }
        if (attrTypeList == null || oldAttrValueList == null || newAttrValueList == null)
            return false;
        if (attrTypeList.Count != oldAttrValueList.Count || oldAttrValueList.Count != newAttrValueList.Count)
            return false;
        return true;
    }
    #region 表情包接入相关
    public List<int> GetUnlockIDList()
    {
        List<int> allList = StringListToIntList(EmojiPackConfig.GetKeys());
        List<int> result = new List<int>();
        for (int i = 0; i < allList.Count; i++)
        {
            int id = allList[i];
            if (IsUnlock(PhantasmPavilionTab.ChatExpression, id))
            {
                result.Add(id);
            }
        }
        return result;
    }
    public List<string> GetEmojiList(int id)
    {
        var info = FaceConfig.GetEmojiPackList();
        if (info == null || !info.TryGetValue(id, out var list) || list == null)
            return new List<string>();
        return list;
    }
    public int GetShowEmojiInfo(float itemWidth, int id, out int rowCount, out int emojiCount, out int space)
    {
        emojiCount = 0;
        rowCount = 0;
        space = 0; // 默认值
        int minSpace = 5; // 最小间隔
        int maxSpace = 50; // 最大间隔
        int width = Mathf.CeilToInt(itemWidth);
        GetEmojiShowSize(id, out int emojiWidth, out int emojiHeight);
        List<string> emojiList = GetEmojiList(id);
        if (emojiList == null || emojiList.Count == 0 || emojiWidth == 0)
            return 0;
        int listCount = emojiList.Count;
        emojiCount = (int)MathF.Min(MaxEmojiCount, MathF.Min((float)width / emojiWidth, listCount));
        if (emojiCount > 1)
        {
            int availableWidthForSpaces = width - (emojiCount * emojiWidth);
            space = availableWidthForSpaces / (emojiCount - 1);
            space = Math.Clamp(space, minSpace, maxSpace);
        }
        else
        {
            space = 0; // 没有空间可分配间隔或者间隔之间只有一个表情
        }
        rowCount = Mathf.CeilToInt((float)listCount / emojiCount);
        return 0;
    }
    // 获得表情包中表情最大的尺寸
    public void GetEmojiShowSize(int id, out int width, out int height)
    {
        width = 0;
        height = 0;
        List<string> emojiList = GetEmojiList(id);
        if (emojiList.IsNullOrEmpty())
            return;
        for (int i = 0; i < emojiList.Count; i++)
        {
            string imgSrc = emojiList[i];
            if (UIFrameMgr.Inst.ContainsDynamicImage(imgSrc))
            {
                List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(imgSrc);
                if (!spriteList.IsNullOrEmpty())
                {
                    for (int j = 0; j < spriteList.Count; j++)
                    for (int i = 0; i < attrTypeList.Count; i++)
                    {
                        UpdateMaxSize(spriteList[j], ref width, ref height);
                        int attrType = attrTypeList[i];
                        newAttrValueList.Add(oldDict[attrType]);
                        oldAttrValueList.Add(0);
                    }
                }
                else
                {
                    attrTypeList = nextAddStarAttrTypeArr.ToList();
                    for (int i = 0; i < nextAddStarAttrTypeArr.Length; i++)
                    {
                        int attrType = nextAddStarAttrTypeArr[i];
                        int attrValue = nextAddStarAttrValueArr[i];
                        if (!oldDict.ContainsKey(attrType))
                        {
                            oldDict[attrType] = 0;
                        }
                        if (!newDict.ContainsKey(attrType))
                        {
                            newDict[attrType] = 0;
                        }
                        newDict[attrType] += attrValue;
                    }
                    for (int i = 0; i < nowAddStarAttrTypeArr.Length; i++)
                    {
                        int attrType = nowAddStarAttrTypeArr[i];
                        int attrValue = nowAddStarAttrValueArr[i];
                        oldDict[attrType] += attrValue;
                    }
                    for (int i = 0; i < attrTypeList.Count; i++)
                    {
                        int attrType = attrTypeList[i];
                        oldAttrValueList.Add(oldDict[attrType]);
                        newAttrValueList.Add(newDict[attrType]);
                    }
                }
            }
            else if (IconConfig.Has(imgSrc))
            {
                UnityEngine.Sprite sprite = UILoader.LoadSprite(imgSrc);
                UpdateMaxSize(sprite, ref width, ref height);
            }
            if (attrTypeList == null || oldAttrValueList == null || newAttrValueList == null)
                return false;
            if (attrTypeList.Count != oldAttrValueList.Count || oldAttrValueList.Count != newAttrValueList.Count)
                return false;
            return true;
        }
    }
    // 更新最大尺寸的方法
    private void UpdateMaxSize(UnityEngine.Sprite sprite, ref int width, ref int height)
    {
        float nowWidth = sprite.rect.width;
        float nowHeight = sprite.rect.height;
        if (width < nowWidth)
            width = Mathf.CeilToInt(nowWidth);
        if (height < nowHeight)
            height = Mathf.CeilToInt(nowHeight);
    }
        #region 表情包接入相关
    #endregion
    //获得自己的聊天气泡ID
    public int GetNowChatBubbleID()
    {
        PhantasmPavilionTab key = PhantasmPavilionTab.ChatBubble;
        int job = 0;
        // 尝试获取当前 ID
        if (nowIDDict.TryGetValue(key, out int nowID) && ChatBubbleBoxConfig.Has(nowID) && IsUnlock(key, nowID))
            return nowID;
        // 如果当前 ID 不存在或未解锁,尝试获取默认 ID
        return TryGetDefaultID(key, job, out int defaultID) ? defaultID : -1;
    }
    //获得其他玩家的聊天气泡ID
    public int GetNowOtherChatBubbleID(int nowID)
    {
        PhantasmPavilionTab key = PhantasmPavilionTab.AvatarFrame;
        // 尝试获取当前 ID
        if (ChatBubbleBoxConfig.Has(nowID))
            return nowID;
        // 如果当前 ID 不存在或未解锁,尝试获取默认 ID
        return TryGetDefaultID(key, 0, out int defaultID) ? defaultID : -1;
    }
    public bool IsUnlock(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return false;
        int unlockDefault = GetUnlockDefault(tab, id);
        //配默认激活的 不做其他判定直接激活
        if (unlockDefault == 1)
            return true;
        // 封包中没有
        if (!TryGetInfo(tab, id, out var info))
            return false;
        // 状态是未激活
        if (!info.State)
            return false;
        // 时效不为永久 且时效用完
        if (info.EndTime > 0 && info.EndTime < TimeUtility.AllSeconds)
            return false;
        return true;
    }
    //是否有时效 true 有时间限制 false 永久(无时间限制)
    public bool IsLimitTime(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return false;
        int unlockDefault = GetUnlockDefault(tab, id);
        int expireMinutes = GetExpireMinutes(tab, id);
        //没找到
        if (unlockDefault == -1 || expireMinutes == -1)
            return false;
        //默认激活的都是永久的,没有时效限制
        if (unlockDefault == 1)
            return false;
        //时效分钟配0的都是永久的,没有时效限制
        if (expireMinutes <= 0)
            return false;
        return true;
    }
    //可升星?
    public bool IsUpStar(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return false;
        //未激活的不可升星
        if (!IsUnlock(tab, id))
            return false;
        //没有有下一星可以升级
        if (!TryGetUpStar(tab, id, out int nowUpStar))
            return false;
        //表格没有填写升星物品
        if (!TryGetStarUpNeedItem(tab, id, nowUpStar, out int itemId, out int count))
            return false;
        //限时的不能升星
        if (IsLimitTime(tab, id))
            return false;
        //激活物品数量不足
        int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
        if (hasCnt < count)
            return false;
        return true;
    }
    public void ShowImage(PhantasmPavilionTab tab, int id, ImageEx imgTitle)
    {
        if (!Has(tab, id))
            return;
        string image = GetImage(tab, id);
        UIFrame frame = imgTitle.GetComponent<UIFrame>();
        if (UIFrameMgr.Inst.ContainsDynamicImage(image))
        public List<int> GetUnlockIDList()
        {
            if (frame == null)
                frame = imgTitle.gameObject.AddComponent<UIFrame>();
            List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(image);
            if (!spriteList.IsNullOrEmpty())
            List<int> allList = StringListToIntList(EmojiPackConfig.GetKeys());
            List<int> result = new List<int>();
            for (int i = 0; i < allList.Count; i++)
            {
                imgTitle.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
                int id = allList[i];
                if (IsUnlock(PhantasmPavilionTab.ChatExpression, id))
                {
                    result.Add(id);
                }
            }
            return result;
        }
        public List<string> GetEmojiList(int id)
        {
            var info = FaceConfig.GetEmojiPackList();
            if (info == null || !info.TryGetValue(id, out var list) || list == null)
                return new List<string>();
            return list;
        }
        public int GetShowEmojiInfo(float itemWidth, int id, out int rowCount, out int emojiCount, out int space)
        {
            emojiCount = 0;
            rowCount = 0;
            space = 0; // 默认值
            int minSpace = 5; // 最小间隔
            int maxSpace = 50; // 最大间隔
            int width = Mathf.CeilToInt(itemWidth);
            GetEmojiShowSize(id, out int emojiWidth, out int emojiHeight);
            List<string> emojiList = GetEmojiList(id);
            if (emojiList == null || emojiList.Count == 0 || emojiWidth == 0)
                return 0;
            int listCount = emojiList.Count;
            emojiCount = (int)MathF.Min(MaxEmojiCount, MathF.Min((float)width / emojiWidth, listCount));
            if (emojiCount > 1)
            {
                int availableWidthForSpaces = width - (emojiCount * emojiWidth);
                space = availableWidthForSpaces / (emojiCount - 1);
                space = Math.Clamp(space, minSpace, maxSpace);
            }
            else
            {
                space = 0; // 没有空间可分配间隔或者间隔之间只有一个表情
            }
            imgTitle.raycastTarget = false;
            frame.ResetFrame(image);
            frame.enabled = true;
            rowCount = Mathf.CeilToInt((float)listCount / emojiCount);
            return 0;
        }
        else
        // 获得表情包中表情最大的尺寸
        public void GetEmojiShowSize(int id, out int width, out int height)
        {
            if (frame != null)
                frame.enabled = false;
            imgTitle.SetSprite(image);
            imgTitle.SetNativeSize();
            width = 0;
            height = 0;
            List<string> emojiList = GetEmojiList(id);
            if (emojiList.IsNullOrEmpty())
                return;
            for (int i = 0; i < emojiList.Count; i++)
            {
                string imgSrc = emojiList[i];
                if (UIFrameMgr.Inst.ContainsDynamicImage(imgSrc))
                {
                    List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(imgSrc);
                    if (!spriteList.IsNullOrEmpty())
                    {
                        for (int j = 0; j < spriteList.Count; j++)
                        {
                            UpdateMaxSize(spriteList[j], ref width, ref height);
                        }
                    }
                }
                else if (IconConfig.Has(imgSrc))
                {
                    UnityEngine.Sprite sprite = UILoader.LoadSprite(imgSrc);
                    UpdateMaxSize(sprite, ref width, ref height);
                }
            }
        }
    }
    public bool TryGetUpStar(PhantasmPavilionTab tab, int id, out int nowUpStar)
    {
        nowUpStar = 0;
        if (!Has(tab, id))
            return false;
        if (!TryGetMaxStarLV(tab, id, out int maxStarCount))
            return false;
        if (!TryGetInfo(tab, id, out var info))
            return false;
        nowUpStar = info.Star + 1;
        if (nowUpStar > maxStarCount)
            return false;
        return true;
    }
    #region handler相关
    public bool Has(PhantasmPavilionTab tab, int id)
    {
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.Has(id);
    }
    public int GetSortNum(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return 0;
        if (!handlers.TryGetValue(tab, out var handler))
            return 0;
        return handler.GetSortNum(id);
    }
    public string GetName(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return string.Empty;
        if (!handlers.TryGetValue(tab, out var handler))
            return string.Empty;
        return handler.GetName(id);
    }
    public string GetImage(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return string.Empty;
        if (!handlers.TryGetValue(tab, out var handler))
            return string.Empty;
        return handler.GetImage(id);
    }
    public int GetUnlockDefault(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return 0;
        if (!handlers.TryGetValue(tab, out var handler))
            return 0;
        return handler.GetUnlockDefault(id);
    }
    public int GetExpireMinutes(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return 0;
        if (!handlers.TryGetValue(tab, out var handler))
            return 0;
        return handler.GetExpireMinutes(id);
    }
    public bool IsUsing(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return false;
        if (!TryGetNowShowID(tab, out int result))
            return false;
        return result == id;
    }
    public bool TryGetUnLockAttr(PhantasmPavilionTab tab, int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
    {
        lightAttrTypeArr = null;
        lightAttrValueArr = null;
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetUnLockAttr(id, out lightAttrTypeArr, out lightAttrValueArr);
    }
    public bool TryGetUnLockNeedItem(PhantasmPavilionTab tab, int id, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetUnLockNeedItem(id, out itemId, out count);
    }
    public bool TryGetStarUpNeedItem(PhantasmPavilionTab tab, int id, int faceStar, out int itemId, out int count)
    {
        itemId = 0;
        count = 0;
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetStarUpNeedItem(id, faceStar, out itemId, out count);
    }
    public bool TryGetEffectID(PhantasmPavilionTab tab, int id, out int effectID)
    {
        effectID = 0;
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetEffectID(id, out effectID);
    }
    public bool TryGetMaxStarLV(PhantasmPavilionTab tab, int id, out int maxStarLV)
    {
        maxStarLV = 0;
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetMaxStarLV(id, out maxStarLV);
    }
    public bool TryGetAddStarAttr(PhantasmPavilionTab tab, int id, int faceStar, out int[] nowAddStarAttrTypeArr, out int[] nowAddStarAttrValueArr)
    {
        nowAddStarAttrTypeArr = new int[1];
        nowAddStarAttrValueArr = new int[1];
        if (!Has(tab, id))
            return false;
        if (!handlers.TryGetValue(tab, out var handler))
            return false;
        return handler.TryGetAddStarAttr(id, faceStar, out nowAddStarAttrTypeArr, out nowAddStarAttrValueArr);
    }
    public void SendStarUPPack(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return;
        if (!handlers.TryGetValue(tab, out var handler))
            return;
        handler.SendStarUPPack(id);
    }
    public void SendUsePack(PhantasmPavilionTab tab, int id)
    {
        if (!Has(tab, id))
            return;
        if (!handlers.TryGetValue(tab, out var handler))
            return;
        handler.SendUsePack(id);
    }
    #endregion
    #region 发封包
    public void SendCA323UnLockPack(int itemIndex, int count)
    {
        var pack = new CA323_tagCMUseItems();
        pack.ItemIndex = (byte)itemIndex;
        pack.UseCnt = (ushort)count;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public void SendCB226FaceChange(int faceId)
    {
        var pack = new CB226_tagCMFaceChange();
        pack.FaceID = (uint)faceId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public void SendCB227FaceStarUP(int faceId)
    {
        var pack = new CB227_tagCMFaceStarUP();
        pack.FaceID = (uint)faceId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public void SendCB228FacePicChange(int facePicId)
    {
        var pack = new CB228_tagCMFacePicChange();
        pack.FacePicID = (uint)facePicId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public void SendCB229FacePicStarUP(int facePicId)
    {
        var pack = new CB229_tagCMFacePicStarUP();
        pack.FacePicID = (uint)facePicId;
        GameNetSystem.Instance.SendInfo(pack);
    }
    public void SendCA230SetChatBubbleBox(int id)
    {
        CA230_tagCMSetChatBubbleBox pak = new CA230_tagCMSetChatBubbleBox();
        pak.BubbleBoxType = (byte)id;
        GameNetSystem.Instance.SendInfo(pak);
    }
    public void SendCA236ChatBubbleBoxStarUP(int id)
    {
        var pack = new CA236_tagCMChatBubbleBoxStarUP();
        pack.BoxID = (byte)id;
        GameNetSystem.Instance.SendInfo(pack);
    }
    #endregion
    #region 收封包
    public void UpdateFaceInfo(HB117_tagMCFaceInfo vNetData)
    {
        if (!infoDict.ContainsKey(PhantasmPavilionTab.Avatar))
            infoDict[PhantasmPavilionTab.Avatar] = new Dictionary<int, PhantasmPavilionInfo>();
        for (int i = 0; i < vNetData.FaceList.Length; i++)
        // 更新最大尺寸的方法
        private void UpdateMaxSize(UnityEngine.Sprite sprite, ref int width, ref int height)
        {
            HB117_tagMCFaceInfo.tagMCFace tagMCFaces = vNetData.FaceList[i];
            if (!infoDict[PhantasmPavilionTab.Avatar].ContainsKey((int)tagMCFaces.FaceID))
                infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID] = new PhantasmPavilionInfo();
            infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].ID = (int)tagMCFaces.FaceID;
            infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].State = tagMCFaces.State == 1;
            infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].EndTime = tagMCFaces.EndTime;
            infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].Star = tagMCFaces.Star;
            float nowWidth = sprite.rect.width;
            float nowHeight = sprite.rect.height;
            if (width < nowWidth)
                width = Mathf.CeilToInt(nowWidth);
            if (height < nowHeight)
                height = Mathf.CeilToInt(nowHeight);
        }
        UpdateRedPoint();
        UpdateFaceInfoEvent?.Invoke();
    }
    public void UpdateFacePicInfo(HB118_tagMCFacePicInfo vNetData)
    {
        if (!infoDict.ContainsKey(PhantasmPavilionTab.AvatarFrame))
            infoDict[PhantasmPavilionTab.AvatarFrame] = new Dictionary<int, PhantasmPavilionInfo>();
        #endregion
        for (int i = 0; i < vNetData.FacePicList.Length; i++)
        //获得自己的聊天气泡ID
        public int GetNowChatBubbleID()
        {
            HB118_tagMCFacePicInfo.tagMCFacePic tagMCFacePics = vNetData.FacePicList[i];
            if (!infoDict[PhantasmPavilionTab.AvatarFrame].ContainsKey((int)tagMCFacePics.FacePicID))
                infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID] = new PhantasmPavilionInfo();
            infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].ID = (int)tagMCFacePics.FacePicID;
            infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].State = tagMCFacePics.State == 1;
            infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].EndTime = tagMCFacePics.EndTime;
            infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].Star = tagMCFacePics.Star;
            PhantasmPavilionTab key = PhantasmPavilionTab.ChatBubble;
            int job = 0;
            // 尝试获取当前 ID
            if (nowIDDict.TryGetValue(key, out int nowID) && ChatBubbleBoxConfig.Has(nowID) && IsUnlock(key, nowID))
                return nowID;
            // 如果当前 ID 不存在或未解锁,尝试获取默认 ID
            return TryGetDefaultID(key, job, out int defaultID) ? defaultID : -1;
        }
        UpdateRedPoint();
        UpdateFacePicInfoEvent?.Invoke();
    }
    public void UpdateEmojiPackInfo(HA721_tagMCEmojiPackInfo vNetData)
    {
        if (!infoDict.ContainsKey(PhantasmPavilionTab.ChatExpression))
            infoDict[PhantasmPavilionTab.ChatExpression] = new Dictionary<int, PhantasmPavilionInfo>();
        for (int i = 0; i < vNetData.EmojiPackList.Length; i++)
        //获得其他玩家的聊天气泡ID
        public int GetNowOtherChatBubbleID(int nowID)
        {
            HA721_tagMCEmojiPackInfo.tagMCEmojiPack emojiPack = vNetData.EmojiPackList[i];
            if (!infoDict[PhantasmPavilionTab.ChatExpression].ContainsKey((int)emojiPack.PackID))
                infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID] = new PhantasmPavilionInfo();
            infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].ID = (int)emojiPack.PackID;
            infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].State = emojiPack.State == 1;
            infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].EndTime = emojiPack.EndTime;
            PhantasmPavilionTab key = PhantasmPavilionTab.AvatarFrame;
            // 尝试获取当前 ID
            if (ChatBubbleBoxConfig.Has(nowID))
                return nowID;
            // 如果当前 ID 不存在或未解锁,尝试获取默认 ID
            return TryGetDefaultID(key, 0, out int defaultID) ? defaultID : -1;
        }
        UpdateRedPoint();
        UpdateEmojiPackInfoEvent?.Invoke();
    }
    public void UpdateChatBubbleBoxInfo(HA717_tagMCChatBubbleBoxState vNetData)
    {
        if (!infoDict.ContainsKey(PhantasmPavilionTab.ChatBubble))
            infoDict[PhantasmPavilionTab.ChatBubble] = new Dictionary<int, PhantasmPavilionInfo>();
        for (int i = 0; i < vNetData.BoxList.Length; i++)
        public bool IsUnlock(PhantasmPavilionTab tab, int id)
        {
            HA717_tagMCChatBubbleBoxState.tagMCChatBubbleBox chatBubbleBox = vNetData.BoxList[i];
            if (!infoDict[PhantasmPavilionTab.ChatBubble].ContainsKey((int)chatBubbleBox.BoxID))
                infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID] = new PhantasmPavilionInfo();
            infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].ID = (int)chatBubbleBox.BoxID;
            infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].State = chatBubbleBox.State == 1;
            infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].EndTime = chatBubbleBox.EndTime;
            infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].Star = chatBubbleBox.Star;
            if (!Has(tab, id))
                return false;
            int unlockDefault = GetUnlockDefault(tab, id);
            //配默认激活的 不做其他判定直接激活
            if (unlockDefault == 1)
                return true;
            // 封包中没有
            if (!TryGetInfo(tab, id, out var info))
                return false;
            // 状态是未激活
            if (!info.State)
                return false;
            // 时效不为永久 且时效用完
            if (info.EndTime > 0 && info.EndTime < TimeUtility.AllSeconds)
                return false;
            return true;
        }
        UpdateRedPoint();
        UpdateChatBubbleBoxInfoEvent?.Invoke();
        //是否有时效 true 有时间限制 false 永久(无时间限制)
        public bool IsLimitTime(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return false;
            int unlockDefault = GetUnlockDefault(tab, id);
            int expireMinutes = GetExpireMinutes(tab, id);
            //没找到
            if (unlockDefault == -1 || expireMinutes == -1)
                return false;
            //默认激活的都是永久的,没有时效限制
            if (unlockDefault == 1)
                return false;
            //时效分钟配0的都是永久的,没有时效限制
            if (expireMinutes <= 0)
                return false;
            return true;
        }
        //可升星?
        public bool IsUpStar(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return false;
            //未激活的不可升星
            if (!IsUnlock(tab, id))
                return false;
            //没有有下一星可以升级
            if (!TryGetUpStar(tab, id, out int nowUpStar))
                return false;
            //表格没有填写升星物品
            if (!TryGetStarUpNeedItem(tab, id, nowUpStar, out int itemId, out int count))
                return false;
            //限时的不能升星
            if (IsLimitTime(tab, id))
                return false;
            //激活物品数量不足
            int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
            if (hasCnt < count)
                return false;
            return true;
        }
        public void ShowImage(PhantasmPavilionTab tab, int id, ImageEx imgTitle)
        {
            if (!Has(tab, id))
                return;
            string image = GetImage(tab, id);
            UIFrame frame = imgTitle.GetComponent<UIFrame>();
            if (UIFrameMgr.Inst.ContainsDynamicImage(image))
            {
                if (frame == null)
                    frame = imgTitle.gameObject.AddComponent<UIFrame>();
                List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(image);
                if (!spriteList.IsNullOrEmpty())
                {
                    imgTitle.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
                }
                imgTitle.raycastTarget = false;
                frame.ResetFrame(image);
                frame.enabled = true;
            }
            else
            {
                if (frame != null)
                    frame.enabled = false;
                imgTitle.SetSprite(image);
                imgTitle.SetNativeSize();
            }
        }
        public bool TryGetUpStar(PhantasmPavilionTab tab, int id, out int nowUpStar)
        {
            nowUpStar = 0;
            if (!Has(tab, id))
                return false;
            if (!TryGetMaxStarLV(tab, id, out int maxStarCount))
                return false;
            if (!TryGetInfo(tab, id, out var info))
                return false;
            nowUpStar = info.Star + 1;
            if (nowUpStar > maxStarCount)
                return false;
            return true;
        }
        #region handler相关
        public bool Has(PhantasmPavilionTab tab, int id)
        {
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.Has(id);
        }
        public int GetSortNum(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return 0;
            if (!handlers.TryGetValue(tab, out var handler))
                return 0;
            return handler.GetSortNum(id);
        }
        public string GetName(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return string.Empty;
            if (!handlers.TryGetValue(tab, out var handler))
                return string.Empty;
            return handler.GetName(id);
        }
        public string GetImage(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return string.Empty;
            if (!handlers.TryGetValue(tab, out var handler))
                return string.Empty;
            return handler.GetImage(id);
        }
        public int GetUnlockDefault(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return 0;
            if (!handlers.TryGetValue(tab, out var handler))
                return 0;
            return handler.GetUnlockDefault(id);
        }
        public int GetExpireMinutes(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return 0;
            if (!handlers.TryGetValue(tab, out var handler))
                return 0;
            return handler.GetExpireMinutes(id);
        }
        public bool IsUsing(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return false;
            if (!TryGetNowShowID(tab, out int result))
                return false;
            return result == id;
        }
        public bool TryGetUnLockAttr(PhantasmPavilionTab tab, int id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr)
        {
            lightAttrTypeArr = null;
            lightAttrValueArr = null;
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetUnLockAttr(id, out lightAttrTypeArr, out lightAttrValueArr);
        }
        public bool TryGetUnLockNeedItem(PhantasmPavilionTab tab, int id, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetUnLockNeedItem(id, out itemId, out count);
        }
        public bool TryGetStarUpNeedItem(PhantasmPavilionTab tab, int id, int faceStar, out int itemId, out int count)
        {
            itemId = 0;
            count = 0;
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetStarUpNeedItem(id, faceStar, out itemId, out count);
        }
        public bool TryGetEffectID(PhantasmPavilionTab tab, int id, out int effectID)
        {
            effectID = 0;
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetEffectID(id, out effectID);
        }
        public bool TryGetMaxStarLV(PhantasmPavilionTab tab, int id, out int maxStarLV)
        {
            maxStarLV = 0;
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetMaxStarLV(id, out maxStarLV);
        }
        public bool TryGetAddStarAttr(PhantasmPavilionTab tab, int id, int faceStar, out int[] nowAddStarAttrTypeArr, out int[] nowAddStarAttrValueArr)
        {
            nowAddStarAttrTypeArr = new int[1];
            nowAddStarAttrValueArr = new int[1];
            if (!Has(tab, id))
                return false;
            if (!handlers.TryGetValue(tab, out var handler))
                return false;
            return handler.TryGetAddStarAttr(id, faceStar, out nowAddStarAttrTypeArr, out nowAddStarAttrValueArr);
        }
        public void SendStarUPPack(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return;
            if (!handlers.TryGetValue(tab, out var handler))
                return;
            handler.SendStarUPPack(id);
        }
        public void SendUsePack(PhantasmPavilionTab tab, int id)
        {
            if (!Has(tab, id))
                return;
            if (!handlers.TryGetValue(tab, out var handler))
                return;
            handler.SendUsePack(id);
        }
        #endregion
        #region 发封包
        public void SendCA323UnLockPack(int itemIndex, int count)
        {
            var pack = new CA323_tagCMUseItems();
            pack.ItemIndex = (byte)itemIndex;
            pack.UseCnt = (ushort)count;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public void SendCB226FaceChange(int faceId)
        {
            var pack = new CB226_tagCMFaceChange();
            pack.FaceID = (uint)faceId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public void SendCB227FaceStarUP(int faceId)
        {
            var pack = new CB227_tagCMFaceStarUP();
            pack.FaceID = (uint)faceId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public void SendCB228FacePicChange(int facePicId)
        {
            var pack = new CB228_tagCMFacePicChange();
            pack.FacePicID = (uint)facePicId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public void SendCB229FacePicStarUP(int facePicId)
        {
            var pack = new CB229_tagCMFacePicStarUP();
            pack.FacePicID = (uint)facePicId;
            GameNetSystem.Instance.SendInfo(pack);
        }
        public void SendCA230SetChatBubbleBox(int id)
        {
            CA230_tagCMSetChatBubbleBox pak = new CA230_tagCMSetChatBubbleBox();
            pak.BubbleBoxType = (byte)id;
            GameNetSystem.Instance.SendInfo(pak);
        }
        public void SendCA236ChatBubbleBoxStarUP(int id)
        {
            var pack = new CA236_tagCMChatBubbleBoxStarUP();
            pack.BoxID = (byte)id;
            GameNetSystem.Instance.SendInfo(pack);
        }
        #endregion
        #region 收封包
        public void UpdateFaceInfo(HB117_tagMCFaceInfo vNetData)
        {
            if (!infoDict.ContainsKey(PhantasmPavilionTab.Avatar))
                infoDict[PhantasmPavilionTab.Avatar] = new Dictionary<int, PhantasmPavilionInfo>();
            for (int i = 0; i < vNetData.FaceList.Length; i++)
            {
                HB117_tagMCFaceInfo.tagMCFace tagMCFaces = vNetData.FaceList[i];
                if (!infoDict[PhantasmPavilionTab.Avatar].ContainsKey((int)tagMCFaces.FaceID))
                    infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID] = new PhantasmPavilionInfo();
                infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].ID = (int)tagMCFaces.FaceID;
                infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].State = tagMCFaces.State == 1;
                infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].EndTime = tagMCFaces.EndTime;
                infoDict[PhantasmPavilionTab.Avatar][(int)tagMCFaces.FaceID].Star = tagMCFaces.Star;
            }
            UpdateRedPoint();
            UpdateFaceInfoEvent?.Invoke();
        }
        public void UpdateFacePicInfo(HB118_tagMCFacePicInfo vNetData)
        {
            if (!infoDict.ContainsKey(PhantasmPavilionTab.AvatarFrame))
                infoDict[PhantasmPavilionTab.AvatarFrame] = new Dictionary<int, PhantasmPavilionInfo>();
            for (int i = 0; i < vNetData.FacePicList.Length; i++)
            {
                HB118_tagMCFacePicInfo.tagMCFacePic tagMCFacePics = vNetData.FacePicList[i];
                if (!infoDict[PhantasmPavilionTab.AvatarFrame].ContainsKey((int)tagMCFacePics.FacePicID))
                    infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID] = new PhantasmPavilionInfo();
                infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].ID = (int)tagMCFacePics.FacePicID;
                infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].State = tagMCFacePics.State == 1;
                infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].EndTime = tagMCFacePics.EndTime;
                infoDict[PhantasmPavilionTab.AvatarFrame][(int)tagMCFacePics.FacePicID].Star = tagMCFacePics.Star;
            }
            UpdateRedPoint();
            UpdateFacePicInfoEvent?.Invoke();
        }
        public void UpdateEmojiPackInfo(HA721_tagMCEmojiPackInfo vNetData)
        {
            if (!infoDict.ContainsKey(PhantasmPavilionTab.ChatExpression))
                infoDict[PhantasmPavilionTab.ChatExpression] = new Dictionary<int, PhantasmPavilionInfo>();
            for (int i = 0; i < vNetData.EmojiPackList.Length; i++)
            {
                HA721_tagMCEmojiPackInfo.tagMCEmojiPack emojiPack = vNetData.EmojiPackList[i];
                if (!infoDict[PhantasmPavilionTab.ChatExpression].ContainsKey((int)emojiPack.PackID))
                    infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID] = new PhantasmPavilionInfo();
                infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].ID = (int)emojiPack.PackID;
                infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].State = emojiPack.State == 1;
                infoDict[PhantasmPavilionTab.ChatExpression][(int)emojiPack.PackID].EndTime = emojiPack.EndTime;
            }
            UpdateRedPoint();
            UpdateEmojiPackInfoEvent?.Invoke();
        }
        public void UpdateChatBubbleBoxInfo(HA717_tagMCChatBubbleBoxState vNetData)
        {
            if (!infoDict.ContainsKey(PhantasmPavilionTab.ChatBubble))
                infoDict[PhantasmPavilionTab.ChatBubble] = new Dictionary<int, PhantasmPavilionInfo>();
            for (int i = 0; i < vNetData.BoxList.Length; i++)
            {
                HA717_tagMCChatBubbleBoxState.tagMCChatBubbleBox chatBubbleBox = vNetData.BoxList[i];
                if (!infoDict[PhantasmPavilionTab.ChatBubble].ContainsKey((int)chatBubbleBox.BoxID))
                    infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID] = new PhantasmPavilionInfo();
                infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].ID = (int)chatBubbleBox.BoxID;
                infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].State = chatBubbleBox.State == 1;
                infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].EndTime = chatBubbleBox.EndTime;
                infoDict[PhantasmPavilionTab.ChatBubble][(int)chatBubbleBox.BoxID].Star = chatBubbleBox.Star;
            }
            UpdateRedPoint();
            UpdateChatBubbleBoxInfoEvent?.Invoke();
        }
        #endregion
    }
    #endregion
}
public class PhantasmPavilionInfo
{
    public int ID;                  //ID
    public bool State;              //是否已激活
    public uint EndTime;            //到期时间戳,0为永久
    public int Star;               //星级
    public class PhantasmPavilionInfo
    {
        public int ID;                  //ID
        public bool State;              //是否已激活
        public uint EndTime;            //到期时间戳,0为永久
        public int Star;               //星级
    }
}
System/PhantasmPavilion/PhantasmPavilionTabCell.cs
@@ -1,32 +1,34 @@
using System;
using UnityEngine;
using vnxbqy.UI;
public class PhantasmPavilionTabCell : CellView
{
    [SerializeField] ButtonEx btnTab;
    [SerializeField] TextEx txtTab;
    [SerializeField] ImageEx imgChoose;
    [SerializeField] RedpointBehaviour redpointBehaviour;
    int index;
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    public void Display(int index)
    {
        this.index = index;
        redpointBehaviour.redpointId = (MainRedDot.PhantasmPavilionRepoint * 10 + index + 1);
        txtTab.text = Language.Get(StringUtility.Contact("PhantasmPavilionTab", index));
        imgChoose.SetActive(index == (int)model.selectTab);
        btnTab.SetListener(OnTabClick);
    }
    private void OnTabClick()
    {
        if (!Enum.IsDefined(typeof(PhantasmPavilionTab), index))
            return;
        PhantasmPavilionTab tab = (PhantasmPavilionTab)index;
        if (tab == model.selectTab)
            return;
        model.selectTab = tab;
    }
namespace vnxbqy.UI
{
    public class PhantasmPavilionTabCell : CellView
    {
        [SerializeField] ButtonEx btnTab;
        [SerializeField] TextEx txtTab;
        [SerializeField] ImageEx imgChoose;
        [SerializeField] RedpointBehaviour redpointBehaviour;
        int index;
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        public void Display(int index)
        {
            this.index = index;
            redpointBehaviour.redpointId = (MainRedDot.PhantasmPavilionRepoint * 10 + index + 1);
            txtTab.text = Language.Get(StringUtility.Contact("PhantasmPavilionTab", index));
            imgChoose.SetActive(index == (int)model.selectTab);
            btnTab.SetListener(OnTabClick);
        }
        private void OnTabClick()
        {
            if (!Enum.IsDefined(typeof(PhantasmPavilionTab), index))
                return;
            PhantasmPavilionTab tab = (PhantasmPavilionTab)index;
            if (tab == model.selectTab)
                return;
            model.selectTab = tab;
        }
    }
}
System/PhantasmPavilion/PhantasmPavilionWin.cs
@@ -2,371 +2,373 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using vnxbqy.UI;
public class PhantasmPavilionWin : Window
namespace vnxbqy.UI
{
    [SerializeField] ScrollerController sclTab;
    [SerializeField] ScrollerController sclItem;
    [SerializeField] ScrollerController sclAttr;
    [SerializeField] ItemCell unlockItemCell;
    [SerializeField] ItemCell starUpItemCell;
    [SerializeField] AvatarCell avatarCell;
    [SerializeField] ImageEx imgFace;
    [SerializeField] UIEffect uiEffect;
    [SerializeField] TextEx txtTime;
    [SerializeField] ButtonEx btnUnLock;
    [SerializeField] ButtonEx btnAddStar;
    [SerializeField] ButtonEx btnUse;
    [SerializeField] Button btnClose;
    [SerializeField] GameObject StarGroup;
    [SerializeField] List<ImageEx> starList = new List<ImageEx>();  //星星显示隐藏 starList和starShowList数量一致
    [SerializeField] List<ImageEx> starShowList = new List<ImageEx>();  //星星是亮是暗
    PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
    PackModel packModel { get { return ModelCenter.Instance.GetModel<PackModel>(); } }
    protected override void AddListeners()
    public class PhantasmPavilionWin : Window
    {
        btnUnLock.SetListener(OnClickUnLock);
        btnAddStar.SetListener(OnClickAddStar);
        btnUse.SetListener(OnClickUse);
        btnClose.SetListener(CloseClick);
    }
        [SerializeField] ScrollerController sclTab;
        [SerializeField] ScrollerController sclItem;
        [SerializeField] ScrollerController sclAttr;
        [SerializeField] ItemCell unlockItemCell;
        [SerializeField] ItemCell starUpItemCell;
        [SerializeField] AvatarCell avatarCell;
        [SerializeField] ImageEx imgFace;
        [SerializeField] UIEffect uiEffect;
        [SerializeField] TextEx txtTime;
        [SerializeField] ButtonEx btnUnLock;
        [SerializeField] ButtonEx btnAddStar;
        [SerializeField] ButtonEx btnUse;
        [SerializeField] Button btnClose;
    protected override void BindController()
    {
    }
        [SerializeField] GameObject StarGroup;
        [SerializeField] List<ImageEx> starList = new List<ImageEx>();  //星星显示隐藏 starList和starShowList数量一致
        [SerializeField] List<ImageEx> starShowList = new List<ImageEx>();  //星星是亮是暗
        PhantasmPavilionModel model { get { return ModelCenter.Instance.GetModel<PhantasmPavilionModel>(); } }
        PackModel packModel { get { return ModelCenter.Instance.GetModel<PackModel>(); } }
    protected override void OnPreOpen()
    {
        sclTab.OnRefreshCell += OnRefreshTabCell;
        sclItem.OnRefreshCell += OnRefreshItemCell;
        sclAttr.OnRefreshCell += OnRefreshAttrCell;
        model.TabChangeEvent += OnTabChangeEvent;
        model.ItemIdChangeEvent += OnItemIdChangeEvent;
        model.UpdateFaceInfoEvent += UpdateFaceInfoEvent;
        model.UpdateFacePicInfoEvent += OnUpdateFacePicInfoEvent;
        model.UpdateEmojiPackInfoEvent += OnUpdateEmojiPackInfoEvent;
        model.UpdateChatBubbleBoxInfoEvent += OnUpdateUpdateChatBubbleBoxInfoEvent;
        packModel.refreshItemCountEvent += OnRefreshItemCountEvent;
        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent;
        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
    }
    protected override void OnPreClose()
    {
        sclTab.OnRefreshCell -= OnRefreshTabCell;
        sclItem.OnRefreshCell -= OnRefreshItemCell;
        sclAttr.OnRefreshCell -= OnRefreshAttrCell;
        model.TabChangeEvent -= OnTabChangeEvent;
        model.ItemIdChangeEvent -= OnItemIdChangeEvent;
        model.UpdateFaceInfoEvent -= UpdateFaceInfoEvent;
        model.UpdateFacePicInfoEvent -= OnUpdateFacePicInfoEvent;
        model.UpdateEmojiPackInfoEvent -= OnUpdateEmojiPackInfoEvent;
        model.UpdateChatBubbleBoxInfoEvent -= OnUpdateUpdateChatBubbleBoxInfoEvent;
        packModel.refreshItemCountEvent -= OnRefreshItemCountEvent;
        PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent;
        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
    }
    protected override void OnAfterOpen()
    {
        CreateTabScroller();
        CreateItemScroller();
        CreateAttrScroller();
        Display();
    }
    protected override void OnAfterClose()
    {
    }
    private void OnTabChangeEvent()
    {
        sclTab.m_Scorller.RefreshActiveCellViews();
        var list = model.ShowItemList(model.selectTab, out int fristIndex);
        if (!list.IsNullOrEmpty())
        protected override void AddListeners()
        {
            model.selectItemId = fristIndex;
            CreateItemScroller();
            btnUnLock.SetListener(OnClickUnLock);
            btnAddStar.SetListener(OnClickAddStar);
            btnUse.SetListener(OnClickUse);
            btnClose.SetListener(CloseClick);
        }
    }
    private void OnItemIdChangeEvent()
    {
        sclItem.m_Scorller.RefreshActiveCellViews();
        CreateAttrScroller();
        Display();
        model.UpdateRedPoint();
    }
        protected override void BindController()
        {
        }
    private void UpdateFaceInfoEvent()
    {
        RefreshAll();
    }
        protected override void OnPreOpen()
        {
            sclTab.OnRefreshCell += OnRefreshTabCell;
            sclItem.OnRefreshCell += OnRefreshItemCell;
            sclAttr.OnRefreshCell += OnRefreshAttrCell;
            model.TabChangeEvent += OnTabChangeEvent;
            model.ItemIdChangeEvent += OnItemIdChangeEvent;
            model.UpdateFaceInfoEvent += UpdateFaceInfoEvent;
            model.UpdateFacePicInfoEvent += OnUpdateFacePicInfoEvent;
            model.UpdateEmojiPackInfoEvent += OnUpdateEmojiPackInfoEvent;
            model.UpdateChatBubbleBoxInfoEvent += OnUpdateUpdateChatBubbleBoxInfoEvent;
            packModel.refreshItemCountEvent += OnRefreshItemCountEvent;
            PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent;
            GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
        }
    private void OnUpdateFacePicInfoEvent()
    {
        RefreshAll();
    }
        protected override void OnPreClose()
        {
            sclTab.OnRefreshCell -= OnRefreshTabCell;
            sclItem.OnRefreshCell -= OnRefreshItemCell;
            sclAttr.OnRefreshCell -= OnRefreshAttrCell;
            model.TabChangeEvent -= OnTabChangeEvent;
            model.ItemIdChangeEvent -= OnItemIdChangeEvent;
            model.UpdateFaceInfoEvent -= UpdateFaceInfoEvent;
            model.UpdateFacePicInfoEvent -= OnUpdateFacePicInfoEvent;
            model.UpdateEmojiPackInfoEvent -= OnUpdateEmojiPackInfoEvent;
            model.UpdateChatBubbleBoxInfoEvent -= OnUpdateUpdateChatBubbleBoxInfoEvent;
            packModel.refreshItemCountEvent -= OnRefreshItemCountEvent;
            PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent;
            GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
        }
    private void OnUpdateEmojiPackInfoEvent()
    {
        RefreshAll();
    }
        protected override void OnAfterOpen()
        {
            CreateTabScroller();
            CreateItemScroller();
            CreateAttrScroller();
            Display();
        }
    private void OnUpdateUpdateChatBubbleBoxInfoEvent()
    {
        RefreshAll();
    }
        protected override void OnAfterClose()
        {
        }
    private void OnRefreshItemCountEvent(PackType type, int arg2, int arg3)
    {
        RefreshAll();
    }
        private void OnTabChangeEvent()
        {
            sclTab.m_Scorller.RefreshActiveCellViews();
            var list = model.ShowItemList(model.selectTab, out int fristIndex);
            if (!list.IsNullOrEmpty())
            {
                model.selectItemId = fristIndex;
                CreateItemScroller();
            }
        }
    private void OnPlayerDataRefreshEvent(PlayerDataType type)
    {
        if (type == PlayerDataType.Face || type == PlayerDataType.HairColor || type == PlayerDataType.ExAttr10)
        private void OnItemIdChangeEvent()
        {
            sclItem.m_Scorller.RefreshActiveCellViews();
            CreateAttrScroller();
            Display();
            model.UpdateRedPoint();
        }
        private void UpdateFaceInfoEvent()
        {
            RefreshAll();
        }
    }
    private void OnSecondEvent()
    {
        RefreshAll();
    }
    private void RefreshAll()
    {
        sclTab.m_Scorller.RefreshActiveCellViews();
        sclItem.m_Scorller.RefreshActiveCellViews();
        CreateAttrScroller();
        Display();
        model.UpdateRedPoint();
    }
    private void OnRefreshTabCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as PhantasmPavilionTabCell;
        _cell.Display(_cell.index);
    }
    private void OnRefreshItemCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as PhantasmPavilionItemCell;
        _cell.Display(_cell.index);
    }
    private void OnRefreshAttrCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as PhantasmPavilionAttrCell;
        _cell.Display(_cell.index);
    }
    private void CreateTabScroller()
    {
        sclTab.Refresh();
        int enumCount = Enum.GetValues(typeof(PhantasmPavilionTab)).Length;
        for (int i = 0; i < enumCount; i++)
        private void OnUpdateFacePicInfoEvent()
        {
            sclTab.AddCell(ScrollerDataType.Header, i);
            RefreshAll();
        }
        sclTab.Restart();
    }
    private void CreateItemScroller()
    {
        sclItem.Refresh();
        List<int> showItemList = model.ShowItemList(model.selectTab, out int fristIndex);
        if (!showItemList.IsNullOrEmpty())
        private void OnUpdateEmojiPackInfoEvent()
        {
            int rowCount = (int)Math.Ceiling((double)showItemList.Count / model.MaxItemRowCount);
            for (int i = 0; i < rowCount; i++)
            RefreshAll();
        }
        private void OnUpdateUpdateChatBubbleBoxInfoEvent()
        {
            RefreshAll();
        }
        private void OnRefreshItemCountEvent(PackType type, int arg2, int arg3)
        {
            RefreshAll();
        }
        private void OnPlayerDataRefreshEvent(PlayerDataType type)
        {
            if (type == PlayerDataType.Face || type == PlayerDataType.HairColor || type == PlayerDataType.ExAttr10)
            {
                sclItem.AddCell(ScrollerDataType.Header, i);
                RefreshAll();
            }
        }
        sclItem.Restart();
    }
    private void CreateAttrScroller()
    {
        int id = model.selectItemId;
        PhantasmPavilionTab tab = model.selectTab;
        int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
        bool isHaveUnLockAttr = model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
        sclAttr.Refresh();
        if (isHaveUnLockAttr)
        private void OnSecondEvent()
        {
            if (unLockState == 2)
            RefreshAll();
        }
        private void RefreshAll()
        {
            sclTab.m_Scorller.RefreshActiveCellViews();
            sclItem.m_Scorller.RefreshActiveCellViews();
            CreateAttrScroller();
            Display();
            model.UpdateRedPoint();
        }
        private void OnRefreshTabCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as PhantasmPavilionTabCell;
            _cell.Display(_cell.index);
        }
        private void OnRefreshItemCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as PhantasmPavilionItemCell;
            _cell.Display(_cell.index);
        }
        private void OnRefreshAttrCell(ScrollerDataType type, CellView cell)
        {
            var _cell = cell as PhantasmPavilionAttrCell;
            _cell.Display(_cell.index);
        }
        private void CreateTabScroller()
        {
            sclTab.Refresh();
            int enumCount = Enum.GetValues(typeof(PhantasmPavilionTab)).Length;
            for (int i = 0; i < enumCount; i++)
            {
                if (!model.TryGetInfo(tab, id, out var info))
                    return;
                bool isHaveAttrProp = model.TryGetAttrProp(tab, id, info.Star, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList);
                if (isHaveAttrProp)
                sclTab.AddCell(ScrollerDataType.Header, i);
            }
            sclTab.Restart();
        }
        private void CreateItemScroller()
        {
            sclItem.Refresh();
            List<int> showItemList = model.ShowItemList(model.selectTab, out int fristIndex);
            if (!showItemList.IsNullOrEmpty())
            {
                int rowCount = (int)Math.Ceiling((double)showItemList.Count / model.MaxItemRowCount);
                for (int i = 0; i < rowCount; i++)
                {
                    for (int i = 0; i < attrTypeList.Count; i++)
                    sclItem.AddCell(ScrollerDataType.Header, i);
                }
            }
            sclItem.Restart();
        }
        private void CreateAttrScroller()
        {
            int id = model.selectItemId;
            PhantasmPavilionTab tab = model.selectTab;
            int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
            bool isHaveUnLockAttr = model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
            sclAttr.Refresh();
            if (isHaveUnLockAttr)
            {
                if (unLockState == 2)
                {
                    if (!model.TryGetInfo(tab, id, out var info))
                        return;
                    bool isHaveAttrProp = model.TryGetAttrProp(tab, id, info.Star, out List<int> attrTypeList, out List<int> oldAttrValueList, out List<int> newAttrValueList);
                    if (isHaveAttrProp)
                    {
                        for (int i = 0; i < attrTypeList.Count; i++)
                        {
                            sclAttr.AddCell(ScrollerDataType.Header, i);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < lightAttrTypeArr.Length; i++)
                    {
                        sclAttr.AddCell(ScrollerDataType.Header, i);
                    }
                }
            }
            else
            sclAttr.Restart();
        }
        private void Display()
        {
            int id = model.selectItemId;
            PhantasmPavilionTab tab = model.selectTab;
            int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
            bool isLimitTime = model.IsLimitTime(tab, id);
            bool isUsing = model.IsUsing(tab, id);
            bool isNoMaxStar = model.TryGetUpStar(tab, id, out int nowUpStar);
            bool isInfo = model.TryGetInfo(tab, id, out var info);
            bool isUnLockAttr = model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
            bool isUnlockDefault = model.GetUnlockDefault(tab, id) == 1;
            bool isMaxStarLV = model.TryGetMaxStarLV(tab, id, out int maxStar);
            bool isUnLockNeedItem = model.TryGetUnLockNeedItem(tab, id, out int itemId, out int count);
            bool isStarUpNeedItem = model.TryGetStarUpNeedItem(tab, id, nowUpStar, out int itemId1, out int count1);
            sclAttr.SetActive(isUnLockAttr);
            unlockItemCell.SetActive(isUnLockNeedItem && unLockState != 2);
            starUpItemCell.SetActive(isStarUpNeedItem && unLockState == 2 && !isLimitTime && isNoMaxStar);
            btnUnLock.SetActive(isUnLockNeedItem && unLockState != 2);
            btnAddStar.SetActive(isStarUpNeedItem && unLockState == 2 && !isLimitTime && isNoMaxStar);
            btnUse.SetActive(!isUsing && unLockState == 2 && model.selectTab != PhantasmPavilionTab.ChatExpression);
            txtTime.SetActive(isInfo && unLockState == 2 || isUnlockDefault);
            StarGroup.SetActive(isInfo && isMaxStarLV && unLockState == 2);
            imgFace.SetActive(model.selectTab == PhantasmPavilionTab.ChatBubble || model.selectTab == PhantasmPavilionTab.ChatExpression);
            model.ShowImage(tab, id, imgFace);
            avatarCell.SetActive(model.selectTab == PhantasmPavilionTab.Avatar || model.selectTab == PhantasmPavilionTab.AvatarFrame);
            if (model.selectTab == PhantasmPavilionTab.Avatar)
            {
                for (int i = 0; i < lightAttrTypeArr.Length; i++)
                int avatarId = model.selectItemId;
                int avatarEffect = AvatarHelper.GetAvatarFrameEffectID(avatarId);
                int avatarFrameId = AvatarHelper.GetMyAvatarFrameID();
                int avatarFrameEffect = AvatarHelper.GetAvatarFrameEffectID(avatarFrameId);
                avatarCell.InitUI(new AvatarModel(avatarId, avatarFrameId, avatarEffect, avatarFrameEffect));
            }
            else if (model.selectTab == PhantasmPavilionTab.AvatarFrame)
            {
                int avatarId = AvatarHelper.GetMyAvatarID();
                int avatarEffect = AvatarHelper.GetAvatarFrameEffectID(avatarId);
                int avatarFrameId = model.selectItemId;
                int avatarFrameEffect = AvatarHelper.GetAvatarFrameEffectID(avatarFrameId);
                avatarCell.InitUI(new AvatarModel(avatarId, avatarFrameId, avatarEffect, avatarFrameEffect));
            }
            uiEffect.Stop();
            if (model.TryGetEffectID(tab, id, out int effectID))
            {
                uiEffect.effect = effectID;
                uiEffect.Play();
            }
            int subTime = 0;
            if (info != null)
            {
                subTime = (int)(info.EndTime - TimeUtility.AllSeconds);
            }
            txtTime.text = Language.Get("FairyEmblem03", !isLimitTime ? Language.Get("PhantasmPavilion03") : TimeUtility.SecondsToDHMSCHS(subTime));
            int star = 0;
            if (info != null)
                star = info.Star;
            for (int i = 0; i < starList.Count; i++)
            {
                starList[i].SetActive(i < maxStar && i < starList.Count);
                starShowList[i].SetActive(i < star && i < starList.Count);
            }
            model.SetStarColor(star, starShowList);
            if (isUnLockNeedItem)
            {
                int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
                var hasCntColor = UIHelper.AppendColor(hasCnt >= count ? TextColType.DarkGreen : TextColType.Red, hasCnt.ToString());
                unlockItemCell.Init(new ItemCellModel(itemId, false, (ulong)count));
                starUpItemCell.countText.SetActive(true);
                unlockItemCell.countText.text = StringUtility.Contact(hasCntColor, "/", count);
                unlockItemCell.button.SetListener(() =>
                {
                    sclAttr.AddCell(ScrollerDataType.Header, i);
                }
                    ItemTipUtility.Show(itemId);
                });
            }
            if (isStarUpNeedItem)
            {
                int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId1);
                var hasCntColor = UIHelper.AppendColor(hasCnt >= count1 ? TextColType.DarkGreen : TextColType.Red, hasCnt.ToString());
                starUpItemCell.Init(new ItemCellModel(itemId1, false, (ulong)count1));
                starUpItemCell.countText.SetActive(true);
                starUpItemCell.countText.text = StringUtility.Contact(hasCntColor, "/", count1);
                starUpItemCell.button.SetListener(() =>
                {
                    ItemTipUtility.Show(itemId1);
                });
            }
        }
        sclAttr.Restart();
    }
    private void Display()
    {
        int id = model.selectItemId;
        PhantasmPavilionTab tab = model.selectTab;
        int unLockState = model.GetUnLockState(tab, id);// 0 - 未激活 1 - 可激活 2 - 已激活
        bool isLimitTime = model.IsLimitTime(tab, id);
        bool isUsing = model.IsUsing(tab, id);
        bool isNoMaxStar = model.TryGetUpStar(tab, id, out int nowUpStar);
        bool isInfo = model.TryGetInfo(tab, id, out var info);
        bool isUnLockAttr = model.TryGetUnLockAttr(tab, id, out int[] lightAttrTypeArr, out int[] lightAttrValueArr);
        bool isUnlockDefault = model.GetUnlockDefault(tab, id) == 1;
        bool isMaxStarLV = model.TryGetMaxStarLV(tab, id, out int maxStar);
        bool isUnLockNeedItem = model.TryGetUnLockNeedItem(tab, id, out int itemId, out int count);
        bool isStarUpNeedItem = model.TryGetStarUpNeedItem(tab, id, nowUpStar, out int itemId1, out int count1);
        sclAttr.SetActive(isUnLockAttr);
        unlockItemCell.SetActive(isUnLockNeedItem && unLockState != 2);
        starUpItemCell.SetActive(isStarUpNeedItem && unLockState == 2 && !isLimitTime && isNoMaxStar);
        btnUnLock.SetActive(isUnLockNeedItem && unLockState != 2);
        btnAddStar.SetActive(isStarUpNeedItem && unLockState == 2 && !isLimitTime && isNoMaxStar);
        btnUse.SetActive(!isUsing && unLockState == 2 && model.selectTab != PhantasmPavilionTab.ChatExpression);
        txtTime.SetActive(isInfo && unLockState == 2 || isUnlockDefault);
        StarGroup.SetActive(isInfo && isMaxStarLV && unLockState == 2);
        imgFace.SetActive(model.selectTab == PhantasmPavilionTab.ChatBubble || model.selectTab == PhantasmPavilionTab.ChatExpression);
        model.ShowImage(tab, id, imgFace);
        avatarCell.SetActive(model.selectTab == PhantasmPavilionTab.Avatar || model.selectTab == PhantasmPavilionTab.AvatarFrame);
        if (model.selectTab == PhantasmPavilionTab.Avatar)
        private void OnClickUnLock()
        {
            int avatarId = model.selectItemId;
            int avatarEffect = AvatarHelper.GetAvatarFrameEffectID(avatarId);
            int avatarFrameId = AvatarHelper.GetMyAvatarFrameID();
            int avatarFrameEffect = AvatarHelper.GetAvatarFrameEffectID(avatarFrameId);
            avatarCell.InitUI(new AvatarModel(avatarId, avatarFrameId, avatarEffect, avatarFrameEffect));
        }
        else if (model.selectTab == PhantasmPavilionTab.AvatarFrame)
        {
            int avatarId = AvatarHelper.GetMyAvatarID();
            int avatarEffect = AvatarHelper.GetAvatarFrameEffectID(avatarId);
            int avatarFrameId = model.selectItemId;
            int avatarFrameEffect = AvatarHelper.GetAvatarFrameEffectID(avatarFrameId);
            avatarCell.InitUI(new AvatarModel(avatarId, avatarFrameId, avatarEffect, avatarFrameEffect));
        }
        uiEffect.Stop();
        if (model.TryGetEffectID(tab, id, out int effectID))
        {
            uiEffect.effect = effectID;
            uiEffect.Play();
        }
        int subTime = 0;
        if (info != null)
        {
            subTime = (int)(info.EndTime - TimeUtility.AllSeconds);
        }
        txtTime.text = Language.Get("FairyEmblem03", !isLimitTime ? Language.Get("PhantasmPavilion03") : TimeUtility.SecondsToDHMSCHS(subTime));
        int star = 0;
        if (info != null)
            star = info.Star;
        for (int i = 0; i < starList.Count; i++)
        {
            starList[i].SetActive(i < maxStar && i < starList.Count);
            starShowList[i].SetActive(i < star && i < starList.Count);
        }
        model.SetStarColor(star, starShowList);
        if (isUnLockNeedItem)
        {
            int state = model.GetUnLockState(model.selectTab, model.selectItemId);
            if (state == 2)
                return;
            if (!model.TryGetUnLockNeedItem(model.selectTab, model.selectItemId, out int itemId, out int count))
                return;
            int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
            var hasCntColor = UIHelper.AppendColor(hasCnt >= count ? TextColType.DarkGreen : TextColType.Red, hasCnt.ToString());
            unlockItemCell.Init(new ItemCellModel(itemId, false, (ulong)count));
            starUpItemCell.countText.SetActive(true);
            unlockItemCell.countText.text = StringUtility.Contact(hasCntColor, "/", count);
            unlockItemCell.button.SetListener(() =>
            if (hasCnt < count)
            {
                ItemTipUtility.Show(itemId);
            });
                SysNotifyMgr.Instance.ShowTip("RealmLevelUpError_3");
                return;
            }
            string guid = packModel.GetItemGUIDByID(itemId);
            if (guid == null)
                return;
            var itemModel = packModel.GetItemByGuid(guid);
            if (itemModel == null)
                return;
            model.SendCA323UnLockPack(itemModel.gridIndex, count);
        }
        if (isStarUpNeedItem)
        private void OnClickUse()
        {
            int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId1);
            var hasCntColor = UIHelper.AppendColor(hasCnt >= count1 ? TextColType.DarkGreen : TextColType.Red, hasCnt.ToString());
            starUpItemCell.Init(new ItemCellModel(itemId1, false, (ulong)count1));
            starUpItemCell.countText.SetActive(true);
            starUpItemCell.countText.text = StringUtility.Contact(hasCntColor, "/", count1);
            starUpItemCell.button.SetListener(() =>
            model.SendUsePack(model.selectTab, model.selectItemId);
        }
        private void OnClickAddStar()
        {
            if (!model.TryGetUpStar(model.selectTab, model.selectItemId, out int nowUpStar))
                return;
            int state = model.GetUnLockState(model.selectTab, model.selectItemId);
            if (state == 0 || state == 1)
                return;
            if (!model.TryGetStarUpNeedItem(model.selectTab, model.selectItemId, nowUpStar, out int itemId, out int count))
                return;
            int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
            if (hasCnt < count)
            {
                ItemTipUtility.Show(itemId1);
            });
                SysNotifyMgr.Instance.ShowTip("RealmLevelUpError_3");
                return;
            }
            model.SendStarUPPack(model.selectTab, model.selectItemId);
        }
    }
    private void OnClickUnLock()
    {
        int state = model.GetUnLockState(model.selectTab, model.selectItemId);
        if (state == 2)
            return;
        if (!model.TryGetUnLockNeedItem(model.selectTab, model.selectItemId, out int itemId, out int count))
            return;
        int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
        if (hasCnt < count)
        {
            SysNotifyMgr.Instance.ShowTip("RealmLevelUpError_3");
            return;
        }
        string guid = packModel.GetItemGUIDByID(itemId);
        if (guid == null)
            return;
        var itemModel = packModel.GetItemByGuid(guid);
        if (itemModel == null)
            return;
        model.SendCA323UnLockPack(itemModel.gridIndex, count);
    }
    private void OnClickUse()
    {
        model.SendUsePack(model.selectTab, model.selectItemId);
    }
    private void OnClickAddStar()
    {
        if (!model.TryGetUpStar(model.selectTab, model.selectItemId, out int nowUpStar))
            return;
        int state = model.GetUnLockState(model.selectTab, model.selectItemId);
        if (state == 0 || state == 1)
            return;
        if (!model.TryGetStarUpNeedItem(model.selectTab, model.selectItemId, nowUpStar, out int itemId, out int count))
            return;
        int hasCnt = packModel.GetItemCountByID(PackType.Item, itemId);
        if (hasCnt < count)
        {
            SysNotifyMgr.Instance.ShowTip("RealmLevelUpError_3");
            return;
        }
        model.SendStarUPPack(model.selectTab, model.selectItemId);
    }
}